Bài 10: Sơ lược về Mongo DB (No SQL)

co-so-du-lieu-mongodb

I.Giới thiệu sơ lược về MongoDB.

– MongoDB là một hệ quản trị Cơ Sở Dữ Liệu hướng tài liệu đa nền tảng (Crossplatform Document-Oriented ).
– MongoDB được xếp vào nhóm CSDL NoSQL.
– MongoDB không sử dụng cấu trúc cơ sở dữ liệu quan hệ dựa trên các bảng như truyền thống mà sử dụng một cấu trúc dạng tài liệu giống với JSON với mô hình động (Dynamic Schemas).
– MongoDB là 1 phần mềm miễn phí,mã nguồn mở.
– MongoDB là hệ thống CSDL NoSQL phổ biến nhất hiện nay.

II.Cách thức lưu trữ.

- Cấu trúc lưu trữ CSDL giống JSON. Cấu trúc đó trong MongoDB được gọi là BSON (Binary JSON).Điều này khiến việc xử lý một kiểu dữ liệu nào đó dễ dàng hơn và nhanh hơn.(Khi truy cập chỉ cần key của trường).So với kiểu dữ liệu dựa trên cấu trúc bảng như MySQL thì linh động hơn rất nhiều

1

– Các định nghĩa trong MySQL được ánh xạ sang MongoDB như bảng sau:

SQL Terms/Concepts MongoDB Terms/Concepts
database database
table collection
row document or BSON document
column field
index index
table joins embedded documents and linking
primary key (Khóa Chính) primary keytrong mongodb thì khóa chính được khởi tạo tự động là _id

– MongoDB lưu trữ dữ liệu theo các cặp khóa – giá trị (key-value) tương tự JSON. Mỗi khóa sẽ có duy nhất 1 giá trị tương ứng. Giá trị này có thể là các kiểu dữ liệu thong thường, hoặc 1 giá trị phức hợp có cấu trúc như 1 tài liệu(document) riêng biệt, hoặc 1 mảng các giá trị có cấu trúc tương tự nhau.
– Trong MongoDB, các cột(trường) là không cố định và không cần khai báo khi tạo bảng, mỗi khi một tài liệu được thêm vào, các trường dữ liệu của nó sẽ được quản lý bằng khóa. Vì vậy, không cần chỉnh sửa cấu trúc bảng thủ công như các hệ thống CSDL SQL mà nó sẽ tự động co dãn theo các khóa được truyền vào.
– Khóa (Primary Key) trong MongoDB được tự động đặt cho trường “_id”. Không giống với MySQL cần phải chỉ định khóa, hay khóa có thể đa trị.
– Tham chiếu và các quan hệ giữa các Collection. Có 2 cách để biểu thị quan hệ giữa
các dữ liệu: Tham chiếu và tài liệu nhúng (References and embedded documents)
+ Tham chiếu(reference) lưu trữ ,mối quan hệ giữa dữ liệu bằng các đường
dẫn (link) hay tham chiếu(reference). Đây là mô hình dữ liệu chuẩn hóa.
VD:

3_1

+ Tài liệu nhúng (embedded document): Tài liệu nhúng lưu trữ quan hệ bằng cách lưu trữ dữ liệu có liên quan trong 1 cấu trúc tài liệu. Như đã nói ở trên 1 giá trị được đánh dấu bằng 1 khóa có thể là 1 giá trị phức hợp.Nó sẽ được lưu trữ như 1 tài liệu thông thường, nhưng sẽ không có khóa, và tồn tại gắn liền với tài liệu cha (Mối quan hệ Composition). Đây là dạng phi chuẩn hóa. Cách sử dụng tham chiếu khá giống với khóa ngoài trong MySQL.Còn cách sử dụng tài liệu nhúng thì tương tự thêm các cột trong MySQL.

4_1

*Dạng tham chiếu thường được sử dụng khi mối quan hệ cần biểu thị là quan hệ nhiều-nhiều (many-to-many). Khi đó, dạng tài liệu nhúng tạo ra các tài liệu trùng lặp mà không tạo ra đủ chênh lệch về hiệu năng, và có thể làm cho hệ thống nặng hơn, tốn thêm không gian lưu trữ. Hoặc trong trường hợp mô hình kế thừa giữa các dữ liệu quá lớn, quá phức tạp. Còn dạng quan hệ sử dụng tài liệu nhúng được sử dụng khi quan hệ là một-một (one-to-one) hay một-nhiều(one-to-many). Trong trường hợp quan hệ là một nhiều,giá trị thường sẽ được lưu trữ dưới dạng một mảng.
– Đánh chỉ mục trong MongoDB (không đi sâu vì sẽ tốn thời gian): MongoDB cung cấp một vài cách đánh chỉ mục khác nhau. Ta có thể đánh chỉ mục ở bất cứ trường nào hay cho cả các tài liệu nhúng.
+Các loại chỉ mục:
1.Single Field Indexes.
2.Compound Indexes.
3.Multikey Indexes.
4.Geospatial Indexes and Queries
5.Text Indexes
6.Hash Index
III.Ưu nhược điểm của MongoDB.
- Ưu điểm:
+Cấu trúc linh động.Không cần lệnh thay đổi cấu trúc bảng.
+Nhẹ.
+Auto sharding (Chia nhỏ dữ liệu).
+Nhân bản (Replication) dễ dàng.
+Truy vấn dễ dàng.
- Nhược điểm :
+ Thiếu tin cậy,dễ gây mất mát dữ liệu khi có sự cố,sửa chữa tốn công sức và thường không đem lại hiểu quả.Vì vậy,cách duy nhất là cần có bản sao trên các trung tâm dữ liệu khác nhau.
+ Chỉ mục (indexing) tốn rất nhiều tài nguyên hệ thống (RAM).
*Các ưu điểm của MongoDB
– Mô hình dữ liệu linh hoạt: Mô hình dữ liệu tài liệu (document) của MongoDB khiến bạn có thể lưu trữ dữ liệu ở bất cứ cấu trúc nào và sửa đổi mô hình dữ liệu động (dynamically).
– Nhiều công cụ vận hành mạnh mẽ : MongoDB Management Service và Ops Manager cho phép bạn triển khai,giám sát, sao lưu và mở rộng MongoDB dễ dàng.
– Secondary Indexes : Truy suất dữ liệu nhanh,chính xác,bao gồm đầy đủ index trên bất cứ trường nào, như địa điểm , tìm kiếm văn bản (text search) và TTL index.
-Tính mở rộng cao : Mở rộng quy mô theo chiều dọc (scale up–vertical scaling) hoặc mở rộng theo chiều ngang (scale out-horizontal scaling) hay sharding. Cho phép dễ dàng tăng quy mô của máy chủ hay từ một máy đơn lẻ thành hàng nghìn nút (node). Triển khai trên mây (cloud) và giữa các trung tâm dữ liệu.
– Ngôn ngữ truy vấn dễ hiểu : Ngôn ngữ truy vấn của MongoDB cung cấp đa dạng các lệnh,kiểu dữ liệu và cập nhật tại chỗ ở mức trường. Driver cho bất cứ ngôn ngữ nào khiến nó trực quan để sử dụng.Hỗ trợ chính thức các ngôn ngữ: C, C++, C#, Java, Node.js, Perl, PHP, Python, Motor, Ruby, Scala; và được cộng đồng hỗ trợ Go và Erlang.
– Cộng đồng phát triển nhanh.
* Khi nào nên sử dụng MongoDB
MongoDB thật sự rất hot nhưng không phải lúc nào ta sử dụng nó cũng tốt, có những trường hợp không nên sử dụng và nên sử dụng
– MongoDB được sử dung khi:
+ Lượng dữ liệu lớn (large data set)
+ Chịu tải cao
– Nếu website có tính chất INSERT cao, bởi vì mặc định MongoDB có sẵn cơ chế ghi với tốc độ cao và an toàn.
– Website ở dạng thời gian thực nhiều, nghĩa là nhiều người thao tác với ứng dụng. Nếu trong quá trình load bị lỗi tại một điểm nào đó thì nó sẽ bỏ qua phần đó nên sẽ an toàn.
– Website có nhiều dữ liệu quá, giả sử web bạn có đến 10 triệu records thì đó là cơn ác mộng với MYSQL. Bởi vì MongoDB có khả năng tìm kiến thông tin liên quan cũng khá nhanh nên trường hợp này nên dùng nó.
– Máy chủ không có hệ quản trị CSDL, trường hợp này thường sẽ sử dụng SQL LIFE hoặc là MongoDB.
IV. Sharing
Sharding: là 1 phương pháp lưu dữ liệu trên nhiều máy chủ, MongoDB sử dụng sharding để lưu 1 lượng rất lớn dữ liệu và các phương pháp truy cập hiệu suất cao
Mục tiêu
Phân tán dữ liệu đến nhiều server (shards). Mỗi shard là 1cơ sở dữ liệu độc lập, tập trung, tất cả các shard tạo thành 1 cơ sở dữ liệu logic

5

Sharding giải quyết những vấn về trong mở rộng quy mô và hỗ trợ thông lượng
cao, dữ liệu lớn:
· Giảm số lượng các phép toán trên mỗi shard
· Giảm số lương dữ liệu lưu trữ trên mỗi server
Sharing trong MongoDB
MongoDB hỗ trợ sharding thông qua cấu hình của một cụm sharded.

6

Các cụm shard có các phần tử: shard, query routers và config server
· Shards: lưu dữ liệu, cung cấp dữ liệu luôn sẵn sang và nhất quán
· Query routers: bị che đi ở phía người dùng, tương tác trực tiếp với các shard.
Query router xử lý và gửi các yêu cầu đeén các shard và trả về dữ liệu cho người dùng
· Config server: lưu trữ siêu dữ liệu của các cluster. Dữ liệu này là ánh xạ dữ liệu của cụm thiết lập đến các shard, Query router sử dụng dữ liệu này để tìm đến hoạt động của từng shard cụ thể. Có chính xác 3 config server cho mỗi production sharded.
Data partitioning
Mongo phân tán dữ liệu, shard thành từng mức. Sharding phân tán dữ liệu của các tập bởi shard key.
Shard keys: để phân chia dữ liệu vào các shard, cần chọn 1 shard key. Shard key là chỉ số của trường hoặc chỉ số của mỗi cặp trường tồn tại trong mỗi document (tương ứng với các table trong mysql) trong tập dữ liệu. Mongo chia giá trị shard key và các chunks và phân tán các chunks đều nhau đến mỗi shard. Để làm được như vậy, MongoDB sử dụng range based partitioning hoặc hash based partitioning Range Based Sharding:với Range Based Sharding, Mongo chia dữ liệu thành các khoảng(range) xác định bởi biến shard key để cung cấp các range based partitioning. Giả sử bạn có shard key là 1 số, nếu bạn muốn hiện thực 1 dãy số từ âm vô cùng đến dương vô cùng, mà mỗi giá trị của shard key nằm trong đó.
Mongo phân chia đường đó thành các đường nhỏ hơn, các khoảng ko đè lên nhau gọi là các chunks. 1 chunk là 1 khoảng giá trị.

7

Hash based Sharding:các key sẽ được băm, và sử dụng các mã băm đó để tạo các
chunks

8

Tùy chỉnh phân phối dữ liệu với Tag Aware Sharding
MongoDB cho phép admin trực tiếp cân bằng sử dụng tag aware sharding Admin tạo ra các ánh xạ các thẻ(tag) với các khoảng shard key và ấn đinh các tags đó cho các shards. Sau đó, chuyển dời cân bằng các thẻ dữ liệu đến các shard thích hợp và đảm bảo rằng các cụm(cluster) luôn thực thi sự phân bố của các dữ liệu mà các thẻ mô tả.
Thẻ là cơ cấu chính để điều khiển hành vi cân bằng và phân tán của chunks trong cluster. Thông thường, server nhận biết thẻ để cải thiện vùng của dữ liệu cho sharded clusters – khoảng cách giữa các trung tâm dữ liệu
Duy trì cân bằng phân phối dữ liệu
Khi thêm dữ liệu mới hoặc server với có thể dẫn đến sự ko cần bằng dữ liệu giữa các cluster, như là 1 shard có thể chữa nhiều chunk, hoặc kích thước các chunk lớn hơn các shard khác

9

Mongo đảm bảo cân bằng cluster sẻ dụng 2 tiến trình chạy nền: splitting và balancer
Splitting
Splitting là 1 tiến trình chạy nền giữ các chunks khi trở nên quá lớn. Khi các chunk phát triển đến 1 cỡ nhất định, Mongo chia chunk thành 2 nửa. Mongo ko di chuyển dữ liệu hoặc làm ảnh hường đến các shard khác
Balancing
Balancer là 1 tiến trình nền quản lý sự di chuyển của các chunk. Balancer có thể di chuyển đến query router trong cluster. Khi phân tán của các tập shard trong custer là ko đều, tiến trình balancer di chuyển chunk từ shard có số lượng lớn chunk đến các shard nhỏ hơn cho đến khi tập cân bằng. Ví dụ, user có 100 chunk ở shard 1, 50 chunk ở shard 2, balancer sẽ di
chuyển các chunk để cân bằng.
Các shard manager di chuyển chunk như các hoạt động ngầm giữa shard chính và shard đích. Trong khi di chuyển, shard đích nhận toàn bộ các document ở chunk từ shard chính. Sau đó, shard đích lưu và chấp nhận toàn bộ thay đổi trong quá trình chuyển. Cuối cùng, đối với metadata, vị trí của chunk trên config server sẽ được cập nhật
Nếu có lỗi, cân bằng sẽ hủy bỏ quá trình chuyển chunk và ko thay đổi shard chính,
Mongo chỉ xóa dữ liệu chunk ở shard chính SAU KHI quá trình di chuyển chunk kết thúc
10

Thêm vào xóa shard từ cluster
Thêm 1 shard vào cluster tạo ra sự ko cân bằng vì shard mới ko có chunk. Khi đó Mongo bắt đầu di chuyển dữ liệu đến shard mới ngay lập tức, nó có thể mất thời gian trước khi các cluster cân bằng.
Khi xóa 1 shard, cân bằng di chuyển chunk từ shard đó đến các shard khác.
Sauk hi di chuyển, tất cả metadata được cập nhật, nên có thể xóa các shard
an toàn.

V. Ánh xạ từ MySQL sang Mongo DB

  1. Create and Alter
SQL Schema Statements MongoDB Schema Statements
CREATE TABLE users (id MEDIUMINT NOT NULL AUTO_INCREMENT,user_id Varchar(30), age Number, status char(1),PRIMARY KEY (id)) Tự động tạo tables khi dùng hàm inseart. ở đây _id primary key sẽ tự động khởi tạo nếu nó ko xác định giá trịdb.users.insert( {
user_id: “abc123″,
age: 55,
status: “A”
} )hoặc có thể dùng hàm createCollection
db.createCollection(“users”)
ALTER TABLE users
ADD join_date DATETIME
Collections không thay đổi cấu trúc document của nó. tức là không thay đổi được CollectionsTuy nhiên, tại Docuemnt, update() có thể thêm các document hiện có bằng cách dùng $set
db.users.update(
{ },
{ $set: { join_date: new Date() } },
{ multi: true }
)
ALTER TABLE users
DROP COLUMN join_date
Tương tự, update() có thể xóa giá trị = hàm $unset.
db.users.update(
{ },
{ $unset: { join_date: “” } },
{ multi: true }
)
CREATE INDEX idx_user_id_asc
ON users(user_id)
db.users.createIndex( { user_id: 1 } )
CREATE INDEX idx_user_id_asc_age_desc
ON users(user_id, age DESC)
db.users.createIndex( { user_id: 1, age: -1 } )
DROP TABLE users db.users.drop()
  1. Insert
SQL INSERT Statements MongoDB insert() Statements
INSERT INTO users(user_id, age, status)
VALUES (“bcd001″, 45, “A”)
db.users.insert(
{ user_id: “bcd001″, age: 45, status: “A” }
)
  1. Select
SQL SELECT Statements MongoDB find() Statements
SELECT *
FROM users
db.users.find()
SELECT id,
user_id,
status
FROM users
db.users.find(
{ },
{ user_id: 1, status: 1 }
)
SELECT user_id, status
FROM users
db.users.find(
{ },
{ user_id: 1, status: 1, _id: 0 }
)
SELECT *
FROM users
WHERE status = “A”
db.users.find(
{ status: “A” }
)
SELECT user_id, status
FROM users
WHERE status = “A”
db.users.find(
{ status: “A” },
{ user_id: 1, status: 1, _id: 0 }
)
SELECT *
FROM users
WHERE status != “A”
db.users.find(
{ status: { $ne: “A” } }
)
SELECT *
FROM users
WHERE status = “A”
AND age = 50
db.users.find(
{ status: “A”,
age: 50 }
)
SELECT *
FROM users
WHERE status = “A”
OR age = 50
db.users.find(
{ $or: [ { status: “A” } ,
{ age: 50 } ] }
)
SELECT *
FROM users
WHERE age > 25
db.users.find(
{ age: { $gt: 25 } }
)
SELECT *
FROM users
WHERE age < 25
db.users.find(
{ age: { $lt: 25 } }
)
SELECT *
FROM users
WHERE age > 25
AND age <= 50
db.users.find(
{ age: { $gt: 25, $lte: 50 } }
)
SELECT *
FROM users
WHERE user_id like “%bc%”
db.users.find( { user_id: /bc/ } )
SELECT *
FROM users
WHERE user_id like “bc%”
db.users.find( { user_id: /^bc/ } )
SELECT *
FROM users
WHERE status = “A”
ORDER BY user_id ASC
db.users.find( { status: “A” } ).sort( { user_id: 1 } )
SELECT *
FROM users
WHERE status = “A”
ORDER BY user_id DESC
db.users.find( { status: “A” } ).sort( { user_id: -1 } )
SELECT COUNT(*)
FROM users
db.users.count()or
db.users.find().count()
SELECT COUNT(user_id)
FROM users
db.users.count( { user_id: { $exists: true } } )or
db.users.find( { user_id: { $exists: true } } ).count()
SELECT COUNT(*)
FROM users
WHERE age > 30
db.users.count( { age: { $gt: 30 } } )or
db.users.find( { age: { $gt: 30 } } ).count()
SELECT DISTINCT(status)
FROM users
db.users.distinct( “status” )
SELECT *
FROM users
LIMIT 1
db.users.findOne()or
db.users.find().limit(1)
SELECT *
FROM users
LIMIT 5
SKIP 10
db.users.find().limit(5).skip(10)
EXPLAIN SELECT * FROM users
WHERE status = “A”
db.users.find( { status: “A” } ).explain()
  1. Update
SQL Update Statements MongoDB update() Statements
UPDATE users SET status = “C” WHERE age > 25 db.users.update(
{ age: { $gt: 25 } },
{ $set: { status: “C” } },
{ multi: true }
)
UPDATE users SET age = age + 3 WHERE status = “A” db.users.update(
{ status: “A” } ,
{ $inc: { age: 3 } },
{ multi: true }
)
  1. Delete
SQL Delete Statements MongoDB remove() Statements
DELETE FROM users WHERE status = “D” db.users.remove( { status: “D” } )
DELETE FROM users db.users.remove({})

VI. Lời kết

Bạn có thể download Mongo DB về cài đặt và trải nghiệm tại https://www.mongodb.org/downloads

Hướng dẫn cài đặt và tài liệu: http://docs.mongodb.org/manual/

You may also like...

4 Responses

  1. Loi says:

    Em đang tìm hiểu về mongodb và thấy nó rất hay nhưng em còn 1 vấn đề chưa giải quyết được đó là embedded hoặc linking trong mongodb.

    Ví dụ như em có 3 collection đó là:
    – companies
    – departments
    – staffs

    Ý tưởng của em là liệt kê các staff đang ở phòng ban (department) nào và ở công ty (company) nào
    Lúc đầu em định dùng embeded nhưng khi xem lại thì không ổn :)
    Còn linking kia thì em thấy rất khó hiểu. Mong admin và mọi người giúp đỡ để em thực hiện cái ý trên của em :)

    • long says:

      em nên kết hợp dùng cả cơ sở dữ liệu bình thường và mongo DB. Khi em lưu và collection staffs thì lưu luôn cả thông tin phòng ban và công ty vào

      • Loi says:

        Em chưa hiểu lắm về kết hợp dùng cả cơ sở dữ liệu bình thường và mongoDB. Anh có thể nói cụ thể hơn không ạ?

        • long says:

          em dùng song song 2 cơ sở dữ liệu cái nào cần lưu trữ dữ liệu với số lượng lớn thì lưu bằng mongoDB còn không thì lưu bằng mysql. Xử lý chi tiết trong code thì không nói rõ ràng được. Chỉ định hướng cho em được như thế thôi

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">