Báo cáo xêmina các vấN ĐỀ hiệN ĐẠi về CÔng nghệ phần mềM



tải về 115.74 Kb.
Chuyển đổi dữ liệu02.01.2018
Kích115.74 Kb.


TRƯỜNG ĐH CÔNG NGHỆ - ĐH QUỐC GIA HÀ NỘI

KHOA CÔNG NGHỆ THÔNG TIN

-----    -----



BÁO CÁO

XÊMINA CÁC VẤN ĐỀ HIỆN ĐẠI VỀ CÔNG NGHỆ PHẦN MỀM

Đề tài

MONGODB

Nhóm học viên: Trần Quang Hào

Phạm Hồng Trang

Lê Vĩnh Yên
Giảng viên: TS.Võ Đình Hiếu

HÀ NỘI - 2012




MỤC LỤC


MỤC LỤC 3

I.ĐẶT VẤN ĐỀ 4

5

II. GIỚI THIỆU VỀ NOSQL 5



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

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

3.1.1 Nhúng hay Tham chiếu 7

3.1.2 Lựa chọn chỉ mục 8

3.2 Chỉ mục 8

3.2.1 Các khái niệm cơ bản 8

3.2.2 Chỉ mục hỗn hợp các khóa 8

3.2.3 Chỉ mục thưa thớt 9

3.2.4 Chỉ mục duy nhất 9

3.2.5 Xóa chỉ mục 9

3.2.6 ReIndex 9

3.3 Sao chép 10

3.4 Truy vấn 12

IV. ỨNG DỤNG 13

V. KẾT LUẬN VÀ KIẾN NGHỊ 13

VI. TÀI LIỆU THAM KHẢO 14

VII. PHỤ LỤC 15




  1. ĐẶT VẤN ĐỀ


Với sự phát triển không ngừng của ngành công nghệ thông tin. Khối dữ liệu cần xử lý trong các ứng dụng là rất lớn. Đặc biệt là sự bùng nổ công nghệ Web 2.0, nơi các mạng dịch vụ dữ liệu cộng đồng cho phép người dùng tự do tạo nội dung trên web, dẫn đến dữ liệu tăng lên rất nhanh, vượt qua giới hạn xử lý của các Hệ quản trị cơ sở dữ liệu quan hệ truyền thống. Để đáp ứng được nhu cầu phát triển của xã hội, đòi hỏi một cơ sở dữ liệu (CSDL) có thể lưu trữ, xử lý được một lượng dữ liệu lớn một cách nhanh chóng và hiệu quả. NoSQL đã ra đời, thay thế hệ quản trị CSDL quan hệ, giải quyết bài toán trên.

Tác giả viết tài liệu này với mục đích giúp người đọc bước đầu tiếp cận, có cái nhìn khái quát về các CSDL hiện đại NoSQL, hiểu chi tiết hơn về hệ cơ sở dữ liệu cơ bản của NoSQL là MongoDB và đồng thời giúp người đọc có thể thực hiện một ứng dụng cơ bản trên hệ cơ sở dữ liệu MongoDB.


  1. GIỚI THIỆU VỀ NOSQL


Với hầu hết các thời kỳ web, Hệ quản trị cơ sở dữ liệu quan hệ dựa trên SQL đã thống trị hầu hết các hệ Quản trị Cơ sở dữ liệu. Tuy nhiên, thời gian gần đây, một cách tiếp cận mới đã bắt đầu biết đến là NoSQL, tạo ra sự thay thế cho các hệ quản trị cơ sở dữ liệu quan hệ truyền thống.

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 - Không chỉ SQL. NoSQL ám chỉ đến những cơ sở dữ liệu không dùng mô hình dữ liệu quan hệ để quản lý dữ liệu trong lĩnh vực phần mềm

Thuật ngữ NoSQL được giới thiệu lần đầu vào năm 1998 sử dụng làm tên gọi chung cho các cơ sở dữ liệu quan hệ nguồn mở nhỏ nhưng không sử dụng SQL cho truy vấn.

Vào năm 2009, Eric Evans, nhân viên của Rackspace giới thiệu lại thuật ngữ NoSQL khi Johan Oskarsson của Last.fm muốn tổ chức một hội thảo về cơ sở dữ liệu nguồn mở phân tán. Thuật ngữ NoSQL đánh dấu bước phát triển của thế hệ CSDL mới: một thế hệ CSDL không ràng buộc, phân tán, nguồn mở, khả năng mở rộng theo chiều ngang, có thể lưu trữ, xử lý từ một lượng rất nhỏ cho tới hàng petabytes dữ liệu trong hệ thống có độ chịu tải, chịu lỗi cao với những đòi hỏi về tài nguyên phần cứng thấp.

Một số đặc điểm nhận dạng cho thế 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,...

Sau đây là danh sách các CSDL NoSQL:

1. Wide Column Store / Column Families: Hadoop/HBase  –  Apache,  BigTable  –  Google,  Cassandra  - Facebook/Apache, Hypertable - Zvents Inc/Baidu, Cloudera, SciDB, Mnesia, Tablets,…

2. Key-Value Store/Tuple store

a. Key/value cache in RAM: memcached, Citrusleaf database, Velocity, Redis, Tuple space,...

b. Key/value save on disk: Memcachedb, Berkeley DB, Tokyo Cabinet, Redis,...

c. Eventually Consistent Key Value Store: Amazon Dynamo, Voldemort, Dynomite, KAI, Cassandra, Hibari, Project Voldemort,…

d. Ordered key-value store: NMDB, Memcachedb, Berkeley DB,...

e. Distributed systems: Apache River, MEMBASE, Azure Table Storage, Amazon Dynamo,...

3. Document Store: Apache Jackrabbit, CouchDB, IBM Lotus Notes Storage Format (NSF),  MongoDB,  Terrastore,  ThruDB, OrientDB, RavenDB,...

4. Graph Database: Neo4J, Sones, AllegroGraph, Core Data, DEX, FlockDB, InfoGrid, OpenLink Virtuoso,...

Tuy cùng mang những đặc điểm chung của NoSQL nhưng mỗi CSDL NoSQL cũng có những đặc điểm riêng, và vì thế thường được dùng cho những dự án khác nhau. Ví dụ:

MongoDB và Redis là những lựa chọn tốt cho việc lưu trữ các dữ liệu thống kê ít được đọc mà lại được viết thường xuyên.

Hadoop, một CSDL dạng tự do, phân tán làm tốt công việc lưu trữ các dữ liệu lớn như các con số thống kê thời tiết hoặc công việc phân tích nghiệp vụ.

Memcachedb, một CSDL nhất thời chóng tàn, tuyệt vời trong lưu trữ các phiên làm việc web, các khóa, và các con số thống kê ngắn hạn.

Cassandra và Riak (các lưu trữ dư thừa, tự động tạo bó cluster) làm tốt trong các môi trường với các ứng dụng có tính sẵn sàng cao, khi thời gian sống tối đa là sống còn.

Để tìm hiểu sâu hơn về các CSDL hiện đại NoSQL, chúng ta đi nghiên cứu chi tiết CSDL đặc trưng là MongoDB.

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


Trong những gương mặt góp phần làm suy tàn đế chế SQL thì MongoDB nổi lên là một CSDL đáng tin cậy và dễ dùng nhất. 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.

Trước khi đi vào tìm hiểu kỹ hơn về MongoDB, chúng ta làm quen với một số 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.

Văn bản

Văn bản là một khái niệm quan trọng trong MongoDB. Văn bản bao gồm tập hợp các khóa với các giá trị tương ứng.

Ví dụ: {"greeting" : "Hello, world!"}

Văn bản trên gồm một khóa là “greeting”, với giá trị là “Hello, world!”. Các văn bản có thể chứa nhiều cặp khóa/giá trị.

Ví dụ: {"greeting" : "Hello, world!", "foo" : 3}

Một số lưu ý:



  • Các cặp khóa/ giá trị trong văn bản được sắp xếp. Văn bản trên sẽ khác với văn bản sau

{"foo" : 3, "greeting" : "Hello, world!"}

  • Khóa trong văn bản là một chuỗi

  • MongoDB phân biệt chữ hoa chữ thường

  • Văn bản trong MongoDB không được chứa những khóa giống nhau. Ví dụ văn bản sau là không hợp lệ

{"greeting" : "Hello, world!", "greeting" : "Hello, MongoDB!"}

Bộ sưu tập

Bộ sưu tập là một nhóm các văn bản. Nếu văn bản tương đương với dòng trong CSDL quan hệ thì bộ sưu tập tương đương với bảng.

Bộ sưu tập là một Schema-Free, nghĩa là các văn bản có hình dạng khác nhau có thể cùng được lưu trữ trong 1 bộ sưu tập.

Ví dụ các văn bản sau có thể cùng được lưu trong một bộ sưu tập:

{"greeting" : "Hello, world!"}

{"foo" : 5}

Bộ sưu tập được xác định bởi tên của nó là một chuỗi UTF-8

Các đặc trưng của MongoDB:



  • Lưu trữ hướng văn bản: Văn bản theo phong cách JSON với những lược đồ động đơn giản

  • Hỗ trợ chỉ mục đầy đủ: chỉ mục trên bất kỳ các thuộc tính

  • Tính sao lặp và tính sẵn sàng cao: mở rộng

  • Auto-sharding: mở rộng theo chiều ngang mà không ảnh hưởng đến chức năng

  • Truy vấn: đa dạng, truy vấn dựa trên văn bản

  • Cập nhật nhanh:

  • Map/Reduce

  • GridFS: lưu trữ file với bất kỳ kích cỡ nào mà không làm phức tạp ngăn xếp

  • Hỗ trợ thương mại: hỗ trợ doanh nghiệp, đào tào, tư vấn

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


Với MongoDB, chúng ta ít phải “chuẩn hóa” hơn so với khi làm việc với lược đồ quan hệ vì trong MongoDB không có khái niệm liên kết (join). Nói chung, với mỗi đối tượng (object) mức cao nhất, ta 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 đó.

Hình 2.1 minh họa có 2 bộ sưu tập: students và courses. Các văn bản student được nhúng văn bản address và văn bản score. Trong đó, văn bản Score được tham chiếu đến Courses.

Hình 2.1. Minh họa bộ sưu tập

So sánh với lược đồ quan hệ: ta cần lưu Score vào bảng riêng và dùng khóa ngoài liên kết với Student.

3.1.1 Nhúng hay Tham chiếu


Một câu hỏi quan trọng trong thiết kế lược đồ Mongo là: “Đối tượng này có cần một bộ sưu tập của riêng nó không hay nên nhúng vào trong các đối tượng trong các bộ sưu tập khác?” Trong cơ sở dữ liệu quan hệ, mỗi tiểu mục có thể trở thành một bảng riêng biệt. Trong Mongo, nó không được khuyến cáo, việc nhúng các đối tượng hiệu quả hơn nhiều. Chúng ta cũng có thể đặt ra câu hỏi “Tại sao tôi không muốn nhúng đối tượng này?”

Tại sao tham chiếu lại chậm. Ta xem ví dụ sau. Chúng ta có một đối tượng Student và cần thực hiện:

print( students.address.city );

Phép toán này sẽ luôn được thực hiện nhanh nếu Address là một đối tượng nhúng, và được lưu ở RAM nếu Student được lưu ở RAM.

Tuy nhiên, với truy vấn:

print( students.scores[0].for_course.name );

Nếu đó là lần đầu truy cập đến khóa này thì trình tiện ích phải thực hiện truy vấn:

students.scores[0].for_course = db.courses.findOne({_id:_course_id_to_find_});



Các luật cơ bản

  • Các đối tượng “lớp thứ nhất” là các đối tượng ở mức cao nhất, có bộ sưu tập của riêng mình.

  • Các đối tượng miêu tả chi tiết các mục thường được nhúng

  • Các đối tượng mà theo mô hình đối tượng có chứa quan hệ nói chung nên được nhúng

  • Quan hệ nhiều – nhiều thường được tham chiếu.

  • Các bộ sưu tập chỉ với một vài đối tượng có thể tồn tại một cách an toàn giống như bộ sưu tập riêng lẻ, được lưu trữ nhanh chóng trong bộ nhớ máy chủ ứng dụng.

  • Các đối tượng nhúng khó khăn để tham chiếu hơn là các đối tượng mức cao.

  • Sẽ khó khăn hơn để có một cái nhìn mức hệ thống đối với các đối tượng nhúng. Ví dụ: Sẽ dễ thực hiện truy vấn tìm 100 sinh viên có điểm cao nhất hơn nếu Score không bị nhúng.

  • Nếu dữ liệu được nhúng lớn, có thể đạt đến giới hạn kích thước của một đối tượng.

  • Nếu hiệu suất là quan trọng, hãy nhúng.








Một số ví dụ




















    • C










  • Nghe

Đọc ngữ âm

- Customer/Order/ Order Line-Item: Customers, Orders nên có một bộ sưu tập riêng. Line-Items nên là một mảng các mục cần mua và được nhúng trong đối tượng Order



  • Hệ thống Blog: Posts cần có bộ sưu tập riêng. Post Author có thể có bộ sưu tập riêng hoặc nếu đơn giản chỉ là địa chỉ mail của tác giả thì cho thành một trường trong Posts. Comments được nhúng trong Posts

3.1.2 Lựa chọn chỉ mục


Một khía cạnh thứ hai khi thiết kế lược đồ là việc lựa chọn chỉ mục. Việc đánh chỉ mục làm cho việc thực hiện truy vấn nhanh hơn. Một truy vấn bình thường cần vài phút, có thể được thực hiện ngay lập tức với việc sử dụng chỉ mục.

Trong MongoDB:



  • Trường _id được đánh chỉ mục tự động

  • Những trường mà theo đó các khóa được tìm kiếm nên được đánh chỉ mục

  • Những trường sắp xếp nói chung nên được đánh chỉ mục

Lưu ý rằng việc thêm vào chỉ mục chỉ làm chậm quá trình ghi vào bộ sưu tập mà không làm chậm quá trình đọc. Vì vậy, sử dụng nhiều chỉ mục với những bộ sưu tập mà tỉ lệ read:write cao. Với những bộ sưu tập mà ghi nhiều hơn đọc, sử dụng chỉ mục là rất tốn kém.

3.2 Chỉ mục


Chỉ mục làm tăng hiệu suất truy vấn lên rất nhiều. Điều quan trọng là nghĩ xem xét tất cả các loại truy vấn 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.

3.2.1 Các khái niệm cơ bản


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. Cấu trúc dữ liệu này được sử dụng trong tối ưu truy vấn Mongo để sắp xếp nhanh các văn bản trong một bộ sưu tập.

Chúng ta có thể khởi tạo chỉ mục bằng cách gọi 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ỉ mục. 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 bộ sưu tập đượ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 thậm chí 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.2.2 Chỉ mục hỗn hợp các khóa


Ngoài chỉ mục khóa đơn, MongoDB còn hỗ trợ đánh chỉ mục hỗn hợp nhiều khóa. Giống như đánh chỉ mục cơ bản, chúng ta sử dụng hàm ensureIndex() để khởi tạo chỉ mục.

db.things.ensureIndex({j:1, name:-1});

Khi khởi tạo một chỉ mục, số đi cùng với khóa là hướng của chỉ mục, 1: tăng dần, -1: giảm dần. Hướng không ảnh hưởng đến việc truy cập ngẫu nhiên nhưng quan trọng nếu bạn đang làm các truy vấn sắp xếp hoặc phân loại trên chỉ mục hỗn hợp.

Nếu chúng ta có một chỉ mục hỗn hợp trên nhiều trường, chúng ta có thể sử dụng nó để truy vấn trên các tập hợp con đầu của các trường đó. Ví dụ ta có chỉ mục trên (a, b, c), ta có thể sử dụng nó để truy vấn trên (a), (a, b), (a, b, c).


3.2.3 Chỉ mục thưa thớt


Chỉ mục thưa thớt là chỉ mục mà chỉ bao gồm các văn bản có trường được đánh chỉ mục. Bất kỳ văn bản nào bị thiếu trường đánh chỉ mục thưa thớt đều không được lưu vào trong chỉ mục. Các chỉ mục là thưa thớt vì bị thiếu những văn bản không có giá trị của trường được đánh chỉ mục.

Chỉ mục thưa thớt, theo định nghĩa, là không đầy đủ và hoạt động khác với chỉ mục đầy đủ. Khi sử dụng chỉ mục thưa thớt để sắp xếp, một vài văn bản trong bộ sưu tập sẽ không được trả về. Đó là do chỉ những văn bản được đánh chỉ mục mới được trả về.

db.people.ensureIndex({title : 1}, {sparse : true})

db.people.save({name:"Jim"})

db.people.save({name:"Sarah", title:"Princess"})

db.people.find({title:{$ne:null}}).sort({title:1})

// returns only Sarah

3.2.4 Chỉ mục duy nhất


MongoDB hỗ trợ đánh chỉ mục duy nhất, đảm bảo rằng không có văn bảo nào được chèn mà giá trị của khóa được đánh chỉ mục lại trùng với văn bản đã tồn tại. Để tạo ra một chỉ mục đảm bảo ràng không có 2 văn bản có cùng giá trị cho 2 trường firstname và lastname ta làm như sau:

db.things.ensureIndex({firstname: 1, lastname: 1}, {unique: true});



Khóa bị thiếu

Khi một văn bản được lưu vào bộ sưu tập với việc đánh chỉ mục duy nhất, bất kỳ khóa được đánh chỉ mục nào bị thiếu sẽ được chèn vào với giá trị null. Vì vậy, không được phép chèn nhiều văn bản bị thiếu cùng một khóa được đánh chỉ mục

db.things.ensureIndex({firstname: 1}, {unique: true});

db.things.save({lastname: "Smith"});


// Next operation will fail because of the unique index on firstname.

db.things.save({lastname: "Jones"});


Giá trị lặp lại
Chỉ mục duy nhất không cho phép một khóa có giá trị nhân bản. Nếu bạn muốn đánh chỉ mục bằng mọi giá, hãy giữ văn bản đầu tiên trong CSDL và xóa tất cả các văn bản có giá trị bị nhân bản, thêm tùy chọn dropDups

db.things.ensureIndex({firstname : 1}, {unique : true, dropDups : true})

3.2.5 Xóa chỉ mục


Xóa tất cả các chỉ mục trên bộ sưu tập:

db.collection.dropIndexes();

Xóa chỉ mục đơn:

db.collection.dropIndex({x: 1, y: -1})

Chạy trực tiếp như một lệnh mà không cần hỗ trợ:

// note: command was "deleteIndexes", not "dropIndexes", before MongoDB v1.3.2

// remove index with key pattern {y:1} from collection foo

db.runCommand({dropIndexes:'foo', index : {y:1}})

// remove all indexes:

db.runCommand({dropIndexes:'foo', index : '*'})


3.2.6 ReIndex


Lệnh reIndex sẽ xây dựng lại tất cả các chỉ mục cho bộ sưu tập.

db.myCollection.reIndex ()

/ / giống như:

db.runCommand ({reIndex: 'myCollection'})

Thông thường, điều này là không cần thiết. Chúng ta có thể làm điều này nếu kích thước bộ sưu tập đã thay đổi đáng kể hoặc không gian đĩa được sử dụng bởi các chỉ mục có vẻ lớn bất thường.

reIndex sẽ bị chậm với các bộ sưu tập lớn.

Các lệnh sửa CSDL tái tạo lại tất cả các chỉ mục trong CSDL.

Lưu ý


  • Chỉ mục trong MongoDB phân biệt chữ hoa chữ thường

  • Chỉ số thông tin được lưu giữ trong bộ sưu tập system.indexes, chạy db.system.indexes.find () để xem ví dụ.

Hiệu suất chỉ mục

Việc đánh chỉ mục thực hiện rất nhanh. Cập nhật được thực hiện nhanh hơn vì MongoDB có thể tìm thấy các văn bản cần cập nhật rất nhanh chóng. Tuy nhiên, với việc sử dụng chỉ mục, khi ghi dữ liệu vào bộ sưu tập, các khóa sau đó phải được thêm vào trường chỉ mục. Như vậy, chỉ mục chỉ tốt cho bộ sưu tập có số lượng đọc nhiều hơn rất nhiều số lượng ghi. Đối với các bộ sưu tập chú trọng ghi, việc sử dụng chỉ mục, trong một số trường hợp, có thể phản tác dụng. Hầu hết các bộ sưu tập đều chú trọng đọc, vì vậy mà chỉ mục là tốt trong hầu hết các tình huống.



Sử dụng Sort() mà không cần chỉ mục

Chúng ta có thể sử dụng sort() để trả về dữ liệu được sắp thứ tự mà không cần phải dùng chỉ mục nếu dữ liệu cần trả về là nhỏ (< 4 MB). Đối với những trường hợp này tốt nhất là sử dụng hàm limit() và sort() cùng nhau.


3.3 Sao chép


Có lẽ công việc quan trọng nhất của bất kỳ quản trị viên MongoDB là đảm bảo sao cho sao chép được thiết lập và hoạt động đúng. Sao chép có thể được sử dụng hoàn toàn để dự phòng và toàn vẹn dữ liệu hoặc có thể được sử dụng cho mục đích cao hơn như mở rộng đọc, sao lưu nóng,…

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.

Master-Slave Replication

Sao chép Master-slave là mô hình sao chép phổ biến nhất được hỗ trợ bởi MongoDB. Mô hình này rất linh hoạt và có thể được sử dụng để sao lưu, dự phòng, mở rộng đọc, …

Hình 2.2 minh họa mô hình Master – Slave bao gồm 2 nút, một nút làm Master, nút còn lại làm Slave

Hình 2.2. Mô hình Master – Slave hai nút

Hình 2.3 minh họa mô hình Master – Slave bao gồm 4 nút, một nút làm Master, 3 nút còn lại làm Slave

Hình 2.3. Mô hình Master – Slave bốn nút

Để thiết lập cần khởi động nút master và một hoặc nhiều nút slave, các nút này đều biết địa chỉ của nút master. Để khởi động master, chạy mongod --master. Để khởi động slave, chạy mongod --slave --source master_address, trong đó master_address là địa chỉ của nút master vừa được khởi động

Replica Sets

Replica Sets là một cụm master-slave tự động chịu lỗi. Replica Sets không có một master cố định: một master được bầu chọn và có thể thay đổi đến nút khác nếu master bị sập [1].

Hình 2.4 mô phỏng mô hình Replica Sets gồm 2 nút.

Hình 2.4. Mô hình Replica Sets hai nút

Khi server chính chết, server cấp 2 chở thành server chính (hình 2.5).

Hình 2.5. Replica Sets – Bầu chọn master mới

Nếu server chính ban đầu hoạt động trở lại, nó trở thành server cấp 2 (hình 2.6).

Hình 2.6. Server chính trở thành server cấp 2


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 (ad hoc). Hệ thống hỗ trợ truy vấn động không yêu cầu bất cứ chỉ mục nào để tìm dữ liệu. Người dùng có thể tìm dữ liệu với việc sử dụng bất kỳ tiêu chuẩn nào. Với CSDL quan hệ, truy vấn động là chuẩn hóa.

Đố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ụ, giả sử chúng ta muốn sử dụng trình MongoDB để 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({})

Trong trường hợp này, lựa chọn (điều kiện) của chúng ta là trống, nó phù hợp với mọi văn bản trong bộ sưu tập. Chúng ta xem thêm một số ví dụ:

db.users.find({'last_name': 'Smith'})

Ở đây, lựa chọn của chúng ta là tất cả các văn bản mà thuộc tính last_name là Smith.



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

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

Ngoài các biểu thức truy vấn, truy vấn MongoDB còn có thể thêm vào các tham số. Ví dụ, chúng ta muốn các số CMT của tất cả người có họ là Smith, ta có thực hiện truy vấn:

// 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});


// lấy tất cả các trường ngoại trừ trường thumbnail đối với tất cả các văn bản.

db.users.find({}, {thumbnail:0});

Chú ý rằng, trường _id luôn luôn được trả về ngay cả khi không yêu cầu

Sắp xếp

Truy vấn MongoDB có thể trả về kết quả được sắp xếp. Để trả về tất cả các văn bản mà trường last_name được sắp xếp theo thứ tự tăng dần, ta viết truy vấn sau:

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

Bỏ qua và giới hạn

MongoDB luôn luôn hỗ trợ bỏ qua và giới hạn để phân trang một cách dễ dàng. Ví dụ ta muốn bỏ qua 20 họ đầu tiên và giới hạn kết quả đến 10, ta viết truy vấn sau:

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

db.users.find({}, {}, 10, 20); // giống như lệnh trên nhưng không rõ ràng.



slaveOk

Khi thực hiện truy vấn ở một hoặc nhiều bản sao, trình tiện ích gửi yêu cầu đến master, để thực hiện truy vấn đối với slave, truy vấn có thể chạy với tùy chọn slaveOk.

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

db.users.find(...)



Con trỏ

Các truy vấn CSDL được thực hiện với phương thức find(), với kỹ thuật này 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ề. Chúng ta có thể xem ví dụ sau:

> var cur = db.example.find();

> cur.forEach( function(x) { print(tojson(x))});

{"n" : 1 , "_id" : "497ce96f395f2f052a494fd4"}

{"n" : 2 , "_id" : "497ce971395f2f052a494fd5"}

{"n" : 3 , "_id" : "497ce973395f2f052a494fd6"}

>

Như vậy, MongoDB là một CSDL hướng văn bản, lưu trữ dữ liệu dưới cặp khóa/giá trị. Các đối tượng trong MongoDB thường được nhúng trong các đối tượng mức cao hơn để tăng tốc độ xử lý truy vấn. Để tăng tốc độ truy vấn, người ta cũng thường đánh chỉ mục cho những bộ sưu tập có tỉ lệ đọc:ghi cao. MongoDB thực hiện truy vấn để lấy dữ liệu thông qua các biểu thức truy vấn cùng các tham số cần thiết. Với những dự án mà tỉ lệ lượng dữ liệu ghi vào CSDL lớn hơn lượng đọc thì lựa chọn MongoDB sẽ mang lại hiệu quả cao.



Để làm quen với truy vấn trong MongoDB, người đọc có thể tham khảo một số lệnh tương đương với truy vấn SQL chuẩn mà chúng tôi trình bày trong Phụ lục của báo cáo này.
  1. ỨNG DỤNG


Để mô phỏng ứng dụng các CSDL hiện đại, chúng tôi đi vào trình bày các bước để chạy một ứng dụng viết trên ngôn ngữ lập trình PHP. Chương trình demo xây dựng một ứng dụng web (blog) thực hiện các chức năng: add, edit va delete dữ liệu database. Sau đó sẽ theo dõi sự thay đổi dữ liệu trong database thông qua command line cua MongoDB. Trong chương trình ta liên kết với cơ sở dữ liệu MongoDB để đọc, ghi, xử lý dữ liệu. Chương trình chạy trên hệ điều hành Widows 32 bit.

Môi trường cài đặt demo


OS: Windows XP 32bit.
Server: Xampp, PHP 5.3
MongoDB: version v2.0.7
Framework:  Cakephp

Để chạy MongoDB ta thực hiện command


Patch_cai_dat_mongodb\bin\mongod.exe --dbpath="patch_data_mongodb"

Để chạy các command truy vấn MongoDB


Patch_cai_dat_mongodb\bin\mongo.exe
Áp dụng vào ứng dụng web blog ta kết nối với MongoDB như sau:
class DATABASE_CONFIG {
    public $default = array(
        'datasource' => 'Mongodb.MongodbSource',
        'host' => 'host_cai_dat_mongodb',
        'database' => 'database_name',
        'port' => 27017,
        'prefix' => '',
        'persistent' => 'true'
    );
}

Cần lưu ý rằng, để PHP có thể hiểu được các đối tượng của MongoDB, ta cần cài đặt trước MongoDB driver cho PHP.


  1. KẾT LUẬN VÀ KIẾN NGHỊ


Sự phát triển không ngừng của công nghệ thông tin, nhu cầu xã hội đòi hòi những hệ thống phần mềm có khả năng lưu trữ và có tốc độ xử lý cao với một lượng dữ liệu lớn. Một trong những công nghệ mới ra đời để giải quyết bài toán đó là NoSQL. Một hệ thống những CSDL với nhiều ưu điểm như mã nguồn mở, có khả năng lưu trữ và xử lý một lượng dữ liệu lớn. Mỗi CSDL trong NoSQL có những đặc điểm chung, đồng thời mang những đặc trưng riêng, mềm dẻo, phù hợp với những dự án khác nhau.

Trong tài liệu đã đề cập đến CSDL cơ bản của NoSQL là MongoDB là một CSDL hướng văn bản, lưu trữ dữ liệu dưới cặp khóa/giá trị. Để tăng tốc độ xử lý truy vấn, người ta thường sử dụng việc đánh chỉ mục và nhúng các đối tượng trong MongoDB. MongoDB tỏ ra đặc biệt hiệu quả với những dự án mà tỉ lệ lượng dữ liệu ghi vào CSDL lớn hơn lượng đọc.

Trong tài liệu cũng đã trình bầy các bước cơ bản để có thể chạy một ứng dụng MongoDB. MongoDB được dùng kết hợp với ngôn ngữ lập trình PHP tạo ra một ứng dụng chạy trên hệ điều hành Windows.

Với các kết quả đạt được, tài liệu đã đáp ứng được mục đích, yêu cầu đặt ra. Tuy nhiên, do hạn chế về thời gian nên mức độ chuyên sâu nghiên cứu của tài liệu chưa cao. Tài liệu đã đề cập đến một lĩnh vực rất mới mẻ và có tính ứng dụng cao. Hy vọng vấn đề này sẽ được đông đảo bạn đọc và những người nghiên cứu khoa học quan tâm, nghiên cứu sâu hơn, khai thác triệt để những ứng dụng to lớn của các hệ cơ sở dữ liệu hiện đại để tạo ra các phần mềm chất lượng cao, đáp ứng nhu cầu xã hội.




  1. TÀI LIỆU THAM KHẢO


  1. Kristina Chodorow - Michael Dirolf, MongoDB: The Definitive Guide, O’reilly, 2010.

  2. http://www.mongodb.org



  1. PHỤ LỤC



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


SQL Statement

Mongo Statement

CREATE TABLE USERS (a Number, b Number)

implicit; can also be done explicitly with

db.createCollection("mycoll")



ALTER TABLE users ADD ...

implicit

 

 

INSERT INTO USERS VALUES(3,5)

db.users.insert({a:3,b:5})

 

 

SELECT a,b FROM users

db.users.find({}, {a:1,b:1})

SELECT * FROM users

db.users.find()

SELECT * FROM users WHERE age=33

db.users.find({age:33})

SELECT a,b FROM users WHERE age=33

db.users.find({age:33}, {a:1,b:1})

SELECT * FROM users WHERE age=33 ORDER BY name

db.users.find({age:33}).sort({name:1})

SELECT * FROM users WHERE age>33

db.users.find({age:{$gt:33}})

SELECT * FROM users WHERE age!=33

db.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<=40

db.users.find({'age':{$gt:33,$lte:40}})

SELECT * FROM users ORDER BY name DESC

db.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 20

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

SELECT * FROM users WHERE a=1 or b=2

db.users.find( { $or : [ {a:1} , {b:2} ] } )

SELECT * FROM users LIMIT 1

db.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 users

db.users.distinct('last_name')

SELECT COUNT(*y)

FROM users



db.users.count()

SELECT COUNT(*y)

FROM users where AGE > 30



db.users.find({age: {'$gt': 30}}).count()

SELECT COUNT(AGE) from users

db.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=3

db.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'});





Поделитесь с Вашими друзьями:


Cơ sở dữ liệu được bảo vệ bởi bản quyền ©tieuluan.info 2019
được sử dụng cho việc quản lý

    Quê hương