logo

Thông báo

Icon
Error

Chia sẻ
Tùy chọn
Xem
Xem bài viết cuối
Offline admin  
#1 Đã gửi : 16/03/2015 lúc 06:00:29(UTC)
admin

Danh hiệu: Administration

Chức danh:

Nhóm: Administrators
Gia nhập: 23-07-2013(UTC)
Bài viết: 6,115
Man
Viet Nam
Đến từ: Vietnam

Cảm ơn: 10 lần
Được cảm ơn: 2 lần trong 2 bài viết

RAVENDBNOSQL

I.    GIỚI THIỆU VỀ NOSQL

NoSQL còn có nghĩa là Non-Relational – không ràng buộc. Tuy nhiên, thuật ngữ đó ít phổ dụng hơn và ngày nay người ta thường dịch NoSQL thành Not Only SQL. NoSQL là một khái niệm chỉ về một lớp các hệ cơ sở dữ liệu không sử dụng mô hình quan hệ (RDBMS). RDBMS vốn tồn tại khá nhiều nhược điểm như có hiệu năng không tốt nếu kết nối dữ liệu nhiều bảng lại hay khi dữ liệu trong một bảng là rất lớn. NoSQL được phát triển trên Javascript Framework với kiểu dữ liệu là JSON và dạng dữ liệu theo kiểu key và value (1 đặc trưng về dữ liệu trong JSON). NoSQL ra đời như là 1 mảnh vá cho những khuyết điểm và thiếu xót cũng như hạn chế của mô hình dữ liệu quan hệ RDBMS về tốc độ, tính năng, khả năng mở rộng, memory cache,…

Đặc điểm của hệ CSDL mới này bao gồm: schema-free, hỗ trợ mở rộng dễ dàng, API đơn giản, nhất quán cuối (eventual consistency),  không giới hạn không gian dữ liệu,…

 

II.      HỆ CƠ SỞ DỮ LIỆU MONGODB

Trong bài viết này chúng ta sẽ tìm hiểu về MONGODB. Mongo viết bằng C++. Nó thích hợp cho các ứng dụng tầm trung trở lên. Nếu tỉ lệ lượng dữ liệu ghi vào CSDL của ứng dụng lớn hơn lượng đọc thì đây càng là lựa chọn hợp lý.

MongoDB là một CSDL có khả năng mở rộng, hiệu suất cao, mã nguồn mở và hướng văn bản.

Dưới đây là một vài khái niệm cơ bản của MongoDB:

-       Văn bản Document là đơn vị cơ bản của dữ liệu trong MongoDB, nó tương đương với một dòng trong CSDL quan hệ

-       Bộ sưu tập (Collection) có thể được coi như tương đương với một bảng.

-       MongoDB có thể lưu trữ nhiều CSDL độc lập, mỗi CSDL này có các bộ sưu tập và điều khoản riêng của mình

-       MongoDB đi kèm với một trình tiện ích JavaScript đơn giản nhưng mạnh mẽ, nó hữu ích trong quản trị và thao tác dữ liệu.

-       Mỗi văn bản có một khóa đặc biệt, đó là “_id”, nó là duy nhất trong bộ sưu tập của văn bản.

3.1 Thiết kế lược đồ

Trong MongoDB không có khái niệm liên kết (join). Với mỗi đối tượng object, sẽ có một bộ sưu tập collection dữ liệu.

Một bộ sưu tập không phải cho tất cả các lớp (class), thay vào đó, các đối tượng sẽ được nhúng vào đó.

 

3.2 Chỉ mục

Chỉ mục là một cấu trúc dữ liệu, thu thập thông tin về giá trị của các trường trong các văn bản của một bộ sưu tập. Chỉ mục làm tăng hiệu suất của query lên rất nhiều. Nhưng cần phải xem xét tất cả các loại query cần trong ứng dụng để xác định những chỉ mục liên quan. Khi đã xác định xong, việc tạo ra các chỉ mục trong MongoDB là khá dễ dàng. Cấu trúc dữ liệu này được sử dụng trong tối ưu query Mongo để sắp xếp nhanh các văn bản trong colllection.

Khởi tạo chỉ mục bằng hàm ensureIndex() và cung cấp một văn bản với một hoặc nhiều khóa để đánh chỉ muc. Ví dụ đánh chỉ mục cho trường name trong students

db.students.ensureIndex({name:1});

Hàm ensureIndex() chỉ khởi tạo chỉ mục nếu nó chưa tồn tại. Để kiểm tra việc tồn tại chỉ mục trên bộ sưu tập students, ta có thể chạy hàm db.students.getIndexes().

Khi một collection được đánh chỉ mục trên một khóa nào đó, truy cập ngẫu nhiên trên biểu thức truy vấn có chứa khóa đó sẽ được thực hiện rất nhanh. Nếu không được đánh chỉ mục, MongoDB phải soát tất cả các văn bản để kiểm tra giá trị của khóa đó trong truy vấn.

Chỉ mục mặc định

Một chỉ mục luôn luôn được tạo ra là _id. Chỉ mục này là đặc biệt và không thể bị xóa. Chỉ mục _id là duy nhất cho các khóa của nó.

Các khóa nhúng

Với MongoDB chúng ta có thể đánh chỉ mục trên các khóa bên trong văn bản nhúng. Ví dụ

db.students.ensureIndex({“address.city”: 1})

Văn bản như là khóa

Các trường được đánh chỉ mục có thể là bất kỳ loại nào, bao gồm cả văn bản.

Mảng

Khi giá trị của trường được đánh chỉ mục của văn bản là một mảng. MongoDB đánh chỉ mục mỗi phần tử của mảng đó.

 

3.3 Sao chép

MongoDB hỗ trợ sao chép dữ liệu không đồng bộ giữa các máy chủ. Tại một thời điểm, chỉ có 1 máy chủ hoạt động để ghi (primary hay master).

Có hai hình thức sao chép.

* Master-Slave Replication

* Replica Sets.

3.4 Truy vấn

Một trong những tính năng tốt nhất của MongoDB là hỗ trợ truy vấn đông.

Đối tượng biểu thức truy vấn

MongoDB hỗ trợ một số các đối tượng truy vấn để lấy dữ liệu. Ví dụ, để trả về mọi văn bản trong bộ sưu tập users. Truy vấn sẽ được viết như sau:

db.users.find({})

Chúng ta xem thêm một so ví dụ về các tùy chọn khi truy vấn..

Các tùy chọn truy vấn

Lựa chọn các trường

// lấy trường ssn của các văn bản có last_name == ‘Smith’:  db.users.find({last_name: ‘Smith’}, {‘ssn’: 1});

 Sắp xễp

db.users.find({}).sort({last_name: 1});

 Bỏ qua và giới hạn

db.users.find().skip(20).limit(10);

 slaveOk

db.getMongo().setSlaveOk(); // cho phép truy vân slave

 Con trỏ

Các query CSDL đưọc thực hiện bằng find(), lúc này có một con trỏ được trả về. Con trỏ sau đó được sử dụng lặp đi lặp lại để lấy tất cả các văn bản mà truy vấn trả về.

 

Một số lệnh truy vấn tương đương giữa SQL và MongoDB

 

SQL StatementMongo Statement
CREATE TABLE USERS (a Number, b Number)implicit; can also be done exiplicit withdb.createCollection(“mycoll”)
ALTER TABLE users ADD …implicit
  
INSERT INTO USERS VALUES(3,5)db.users.insert({a:3,b:5})
  
SELECT a,b FROM usersdb.users.find({}, {a:1,b:1})
SELECT * FROM usersdb.users.find()
SELECT * FROM users WHERE age=33db.users.find({age:33})
SELECT a,b FROM users WHERE age=33db.users.find({age:33}, {a:1,b:1})
SELECT * FROM users WHERE age=33 ORDER BY namedb.users.find({age:33}).sort({name:1})
SELECT * FROM users WHERE age>33db.users.find({age:{$gt:33}})
SELECT * FROM users WHERE age!=33db.users.find({age:{$ne:33}})
SELECT * FROM users WHERE name LIKE “%Joe%”db.users.find({name:/Joe/})
SELECT * FROM users WHERE name LIKE “Joe%”db.users.find({name:/^Joe/})
SELECT * FROM users WHERE age>33 AND age<=40db.users.find({‘age’:{$gt:33,$lte:40}})
SELECT * FROM users ORDER BY name DESCdb.users.find().sort({name:-1})
SELECT * FROM users WHERE a=1 and b=’q’db.users.find({a:1,b:’q’})
SELECT * FROM users LIMIT 10 SKIP 20db.users.find().limit(10).skip(20)
SELECT * FROM users WHERE a=1 or b=2db.users.find( { $or : [ {a:1} , {b:2} ] } )
SELECT * FROM users LIMIT 1db.users.findOne()
SELECT order_id FROM orders o, order_line_items li

WHERE li.order_id=o.order_id AND li.sku=12345

db.orders.find({“items.sku”:12345},{_id:1})
SELECT customer.name FROM customers,orders

WHERE orders.id = “q179″

AND orders.custid = customer.id

var o = db.orders.findOne({_id:”q179″});var name = db.customers.findOne({_id:o.custid})
  
SELECT DISTINCT last_name FROM usersdb.users.distinct(‘last_name’)
SELECT COUNT(*y)FROM usersdb.users.count()
SELECT COUNT(*y)FROM users where AGE > 30db.users.find({age: {‘$gt’: 30}}).count()
SELECT COUNT(AGE) from usersdb.users.find({age: {‘$exists’: true}}).count()
  
CREATE INDEX myindexname ON users(name)db.users.ensureIndex({name:1})
CREATE INDEX myindexname ON users(name,ts DESC)db.users.ensureIndex({name:1,ts:-1})
  
EXPLAIN SELECT * FROM users WHERE z=3db.users.find({z:3}).explain()
  
UPDATE users SET a=1 WHERE b=’q’db.users.update({b:’q’},{$set:{a:1}},false,true)
UPDATE users SET a=a+2 WHERE b=’q’db.users.update({b:’q’},{$inc:{a:2}},false,true)
  
DELETE FROM users WHERE z=”abc”db.users.remove({z:’abc’});

 

RavenDB cũng là open source được viết bằng C# nên thông qua nó ta có thể tìm hiểu được cơ chế của NoSql một cách thuận tiện hơn.

Chọn template là internet project.

- Add RavenDB (Embedded) reference bằng cách Tool > Extension and Update search online RavenDB.

2. Chỉnh sửa Model và Controller.

- Add project class library, chứa các class model, ở đây ta lấy ví dụ là database của một blog chứa nhiều comment.

- Trong project này, ta tạo thư mục  model và add 2 class Blog.cs và Comment.cs

image

RavenDB sẽ lưu trữ data thông qua DocumentStore object. Ta cần implement IDocumentStore interface. Mọi ‘connection’ đến DocumentStore được thông qua RavenDB DocumentSession. Để sử dụng tầng RavenDB access layer ta làm theo các bước sau:

- Tạo RavenController class được kế thừa từ MVC’s Controller class, class này được đặt trong thư mục Controller.

public class RavenController : Controller

{

public new IDocumentSession Session { get; set; }

protected IDocumentStore _documentStore;

public RavenController(IDocumentStore documentStore)

{

_documentStore = documentStore;

}

protected override void OnActionExecuting(ActionExecutingContext filterContext)

{

Session = _documentStore.OpenSession();

base.OnActionExecuting(filterContext);

}

protected override void OnActionExecuted(ActionExecutedContext filterContext)

{

using (Session)

{

if(Session!=null && filterContext.Exception == null)

{

Session.SaveChanges();

}

}

base.OnActionExecuted(filterContext);

}

}

- Chúng ta đã chuẩn bị xong base controller, giờ ta sẽ chuyển qua HomeContollerthay đổi để nó kế thừa từ RavenController thay cho controller default của MVC.

    public class HomeController : RavenController

{

public HomeController(IDocumentStore store)

: base(store)

{

}

- Chúng ta load một một row data của Blog từ RavenDB bằng cách như sau.

//

// GET: /Home/Details/5

public ViewResult Details(int id)

{

Blog blog = Session.Load<Blog>(id);

return View(blog);

}

- Danh sách các Blog được load như sau:

public ActionResult Index()

{

return View(Session.Query<Blog>().ToList());

}

 

- Update Blog và save vào RavenDB

//

// POST: /Home/Edit/5

[HttpPost]

public ActionResult Edit(Blog blog)

{

if (ModelState.IsValid)

{

Blog currentBlog = Session.Load<Blog>(blog.Id);

currentBlog.Title = blog.Title;

currentBlog.Content = blog.Content;

Session.Store(currentBlog);

return RedirectToAction(“Index”);

}

return View(blog);

}

 

RavenDB’s document session sẽ không updates ngay vào document. Khi chúng ta trực tiếp chỉnh sửa blog object thì sự thay đổi sẽ được lưu vào session store. Trong các bước tiếp theo chúng ta sẽ đề cập đến vấn đề này sau.

- Các action khác được định nghĩa các bạn có thể xem thêm trong source code để biết chi tiết thêm.

2. Implement cho View.

Phần tiếp theo ta implement view để hiển thị các chức năng danh sách blog, view detail block …

- Chúng ta sửa file Details.cshtml để hiển thị các comment của user.

</div>

<div class=”blog-item-footer”>

@Html.ActionLink(“Edit”, “Edit”, new { id = Model.Id }) |

@Html.ActionLink(“Back to List”, “Index”)

</div>

<div class=”blog-item-content”>

@Html.DisplayFor(model => model.Content)

</div>

<div>

@if (Model.Comments != null)

{

<div>

<h3>User Feedback</h3>

</div>

foreach (var item in Model.Comments)

{

<div style=”border: solid 1px #F0F0F0; margin: 2px”>

<div class=”comment-author”>

Comments by – @item.Author

</div>

<div class=”comment-message”>

@item.Message

</div>

</div>

}

}

</div>

<div id=”addComments” style=”display: inline;”>

<div>

@Html.Partial(“CreateComments”, new RaBlog.Domain.Model.Comment { BlogId = Model.Id })

</div>

</div>

 

- Bước kế tiếp ta add thêm 1 file Partial View đặt tên là CreateComments.cshtml.

@model RaBlog.Domain.Model.Comment

@using (Html.BeginForm())

{

@Html.ValidationSummary(true)

<fieldset>

<legend>Post Comment</legend>

@Html.HiddenFor(model => model.BlogId)

<div style=”height:35px;”>

<div class=”editor-label” style=”float:left; width:125px”>

@Html.LabelFor(model => model.Author)

</div>

<div class=”editor-field” style=”float:left;”>

@Html.EditorFor(model => model.Author)

@Html.ValidationMessageFor(model => model.Author)

</div>

</div>

<div style=”height:35px;”>

<div class=”editor-label” style=”float:left; width:125px”>

@Html.LabelFor(model => model.Email)

</div>

<div class=”editor-field” style=”float:left”>

@Html.EditorFor(model => model.Email)

@Html.ValidationMessageFor(model => model.Email)

</div>

</div>

<div style=”height:35px;”>

<div class=”editor-label” style=”float:left; width:125px”>

@Html.LabelFor(model => model.Message)

</div>

<div class=”editor-field” style=”float:left;”>

@Html.TextAreaFor(model => model.Message, new { rows = 5, cols = 100 })

@Html.ValidationMessageFor(model => model.Message)

</div>

</div>

<p>

<input type=”submit” name=”CreateComment” value=”Post Comment” />

</p>

</fieldset>

 

- Ở file Controller chúng ta cần handle action POST từ CreateComments view.

//

// POST: /Home/Details

[HttpPost]

public ActionResult Details(Comment comment)

{

Blog blog = Session.Load<Blog>(comment.BlogId);

if (blog.Comments == null)

{

blog.Comments = new List<Comment>();

}

blog.Comments.Add(comment);

Session.Store(blog);

return RedirectToAction(“Details”, comment.BlogId);

}

3. Control DocumentStore .

- Chúng ta cần cơ chế để khởi tạo, kết nối với DocumentStore  của RavenDB.

- Ta implement việc kết nối đến DocumentStore  thông qua method CreateControllerFactory trong class CompositionRoot

public class CompositionRoot

{

private readonly IControllerFactory controllerFactory;

public CompositionRoot()

{

this.controllerFactory = CompositionRoot.CreateControllerFactory();

}

public IControllerFactory ControllerFactory

{

get

{

return controllerFactory;

}

}

private static IControllerFactory CreateControllerFactory()

{

var cacheRepository = new EmbeddableDocumentStore();

cacheRepository.ConnectionStringName = “RavenDB”;

cacheRepository.Initialize();

var controllerFactory = new BlogControllerFactory(cacheRepository);

return controllerFactory;

}

}

- Như ở trên để khởi tạo instance của EmbeddableDocumentStore() chúng ta cần cung cấp ConnectionStringName – tên DB. connection string sẽ được định nghĩa trong web.config.

raven-db-embedded-connection-string

Sau các bước trên, giờ bạn chỉ còn 1 bước cuối là ấn F5 và chạy thử :D

link source code:

https://onedrive.live.com/redir?resid=AAAFFCDAE249948A!116&authkey=!AHPcc6UbwfZLEvQ&ithint=file%2czip

1. Các bước setup cơ bản ban đầu.

- Bắt đầu với việc tạo project Asp.net MVC

Ai đang xem chủ đề này?
OceanSpiders 2.0
Di chuyển  
Bạn không thể tạo chủ đề mới trong diễn đàn này.
Bạn không thể trả lời chủ đề trong diễn đàn này.
Bạn không thể xóa bài của bạn trong diễn đàn này.
Bạn không thể sửa bài của bạn trong diễn đàn này.
Bạn không thể tạo bình chọn trong diễn đàn này.
Bạn không thể bỏ phiếu bình chọn trong diễn đàn này.

| Cung cấp bởi YAF.NET 2.2.4.14 | YAF.NET © 2003-2020, Yet Another Forum.NET
Thời gian xử lý trang này hết 2.557 giây.