- Vấn đề.
- Giới thiệu về NoSql.
- Giới thiệu về MongoDB.
- Cài đặt trong Window.
- Cài đặt trong Linux.
Triết lý thiết kế của MongoDB là tập trung vào việc kết hợp các tính năng quan trọng của cơ sở dữ liệu quan hệ với những đổi mới của công nghệ NoSQL.
[Ảnh]
Cơ sở dữ liệu quan hệ được sử dụng trong các ứng dụng trong nhiều năm nay, với những tính năng quan trọng - nền móng cho việc phát triển thế hệ cơ sở dữ liệu mới:
- Expressive query language & secondary Indexes.
- Strong consistency.
- Enterprise Management and Integrations.
Tuy nhiên, các ứng dụng hiện đại đặt ra yêu cầu mới mà cơ sở dữ liệu quan hệ không giải quyết được, chính điều này đã thúc đẩy sự phát triển của NoSQL:
- Flexible Data Model.
- Scalability and Performance.
- Always-On Global Deployments.
Để cung cấp được những tính năng trên, NoSQL đã buộc phải hy sinh những tính năng, ưu điểm của cơ sở dữ liệu quan hệ. Với một cách tiếp cận hoàn toàn khác, MongoDB là hệ cơ sở dữ liệu duy nhất khai thác được những đổi mới của NoSQL trong khi duy trì những ưu điểm cơ sở dữ liệu quan hệ.
-
Thiết kế Schema của bạn theo yêu cầu của người dùng.
-
Tổ hợp các đối tượng vào trong một Document nếu bạn sẽ sử dụng các đối tượng đó cùng nhau. Nếu không, bạn nên phân biệt chúng (nhưng đảm bảo là không cần thiết sử dụng các Join).
-
Sao dữ liệu (nhưng có giới hạn) bởi vì không gian trên đĩa không là gì khi so sánh với thời gian tính toán.
-
Thực hiện Join trong khi ghi, đừng thực hiện trong khi đọc.
-
Tối ưu hóa Schema của bạn với các trường hợp thường xuyên sử dụng.
-
Thực hiện Aggregation phức tạp trong Schema đó.
Khi thiết kế 1 MongoDB Schema, điều đầu tiên ta cần quan tâm là định lượng các mối quan hệ. Trong MongoDB, tùy vào thuộc tính của mối quan hệ "One to N" mà ta có phân ra làm 3 loại khác nhau : "One to few", "One to many", "One to squillions( rất nhiều )" . Với từng loại ta có cách thiết kế schema khác nhau.
- One to few.
Một ví dụ của "One to few" là việc bạn mô tả địa chỉ của một người. Trong trường hợp này chúng ta hoàn toàn có thể sử dụng việc nhúng dữ liệu. Ở đây ta sẽ để các địa chỉ dưới dạng array nằm trong đối tượng Person.
> db.person.findOne()
{
name: 'Kate Monster',
ssn: '123-456-7890',
addresses : [
{ street: '123 Sesame St', city: 'Anytown', cc: 'USA' },
{ street: '123 Avenue Q', city: 'New York', cc: 'USA' }
]
}
Ưu điểm của việc nhúng dữ liệu là ta chỉ cần 1 câu lệnh query để có thể lấy đầy đủ thông tin chi tiết bên trong tuy nhiên dữ liệu lại sẽ phụ thuộc vào Person nên chúng ta không thể xử lý nó như 1 thực thể độc lập Address được.
Ví dụ: Nếu ta cần model một hệ thống quản lý tác vụ. Mỗi người nhận một số lượng tác vụ nhất định. Với cách làm trên khi gặp vấn đề truy vấn như : "Hãy cho tối biết số các tác vụ cần hoàn thành vào ngày mai ?". Giải pháp được đưa ra sẽ là vào từng người trong hệ thống , kiểm tra từng tác vụ của họ xem có cái nào cần hoàn thành vào ngày mai không , gom hết lại trả về ... Tuy nhiên như vậy, truy vấn sẽ trở nên phức tạp hơn. Khi đó, chúng ta có thể sử dụng "One to many".
- One to many.
Ví dụ : Ta có 1 sản phẩm như Smartphone chẳng hạn. Nó bao gồm rất nhiều các linh kiện bên trong và các link kiên này có thể thay thế được. Số linh kiên ở đây bị giới hạn cỡ vài trăm. Giải pháp cho vấn đề này là đặt một mảng các ObjectID của từng link kiện trong dữ liệu của sản phẩm. (Trong ví dụ này sẽ sử dụng các ObjectID 2-byte vì nó dễ đọc , trong ứng dụng thật bạn hoàn toàn có thể sử dụng ObjectID 12-byte)
Với mỗi link kiện đều có một bản dữ liệu riêng :
> db.parts.findOne()
{
_id : ObjectID('AAAA'),
partno : '123-aff-456',
name : '#4 grommet',
qty: 94,
cost: 0.94,
price: 3.99
}
Với mỗi sản phẩm sẽ có một mảng các ObjectID để tham chiếu đến các linh kiện tạo nên sản phẩm:
> db.products.findOne()
{
name : 'left-handed smoke shifter',
manufacturer : 'Acme Corp',
catalog_number: 1234,
parts : [ // array of references to Part documents
ObjectID('AAAA'),
ObjectID('F17C'),
ObjectID('D2AA'),
// etc
]
Để có thể truy vấn dữ liệu từng linh kiện trong một sản phẩm xác định ta có thể sử dụng cú pháp sau:
// lấy thông tin sản phẩm qua catalog_number
> product = db.products.findOne({catalog_number: 1234});
// Lấy toàn bộ linh kiện trong sản phẩm
> product_parts = db.parts.find({_id: { $in : product.parts } } ).toArray() ;
Để tối ưu việc truy vấn, bạn cần đặt index cho "products.catalog_number".Ở trong hệ thống đã có sắn index cho "parts._id", nên không cần phải tối ưu nữa.
Với loại thứ 2 này, ta có 2 đối tượng riêng rẽ dễ dàng truy vấn tuy nhiên điều này làm cho việc bạn lấy dữ liệu của linh kiện trong một sản phẩm chậm hơn một chút. Tất nhiên chẳng bao giờ có giải pháp nào hoàn hảo cả. Thêm vào đó, hoàn thành có thể thấy các sản phẩm thì có nhiều linh kiện giống nhau. Từ đó mối quan hệ "one to Many " thành "N to N " rồi.
- One to Squillions.
Một ví dụ của "One of squillions" là hệ thống logging sự kiện thu thập những thông điệp log từ các máy khác nhau. Bất kỳ máy chủ nào cũng có thể sinh ra các thông điệp vượt quá kích thước tối đa của document16MB, ngay cả khi bạn chỉ lưu trữ mảng các ObjectID. Đây là một trường hợp sử dụng kinh điển của "parent-referencing": chúng ta có các document ở máy chủ, và sau đó chỉ lưu trữ mảng các ObjectID của máy chủ đó trong document cho từng thông điệp.
> db.hosts.findOne()
{
_id : ObjectID('AAAB'),
name : 'goofy.example.com',
ipaddr : '127.66.66.66'
}
> db.logmsg.findOne()
{
time : ISODate("2014-03-28T09:42:41.382Z"),
message : 'cpu is on fire!',
host: ObjectID('AAAB') // Reference to the Host document
}
Muốn lấy toàn bộ thông điệp từ máy chủ:
> host = db.hosts.findOne({ipaddr : '127.66.66.66'}); // assumes unique index
> last_5k_msg = db.logmsg.find({host: host._id}).sort({time : -1}).limit(5000).toArray()
- Tổng kết.
Ngay cả ở mức cơ bản, có nhiều điều phải để ý khi thiết kế lược đồ MongoDB. Chúng ta cần chú ý đến 2 yếu tố:
- Có phải các thực thể phía "N" trong mối quan hệ "One to N" cần đứng một mình? ("Will the entities on the “N” side of the One-to-N ever need to stand alone?")
- Loại của mối quan hệ: One to few, One to many hay One to squillions?
Dựa trên các yếu tố này, chúng ta sẽ chọn ra 1 trong 3 loại quan hệ ở trên:
- Nhúng phía N nếu loại là One to few và không có nhu cầu để truy cập vào các đối tượng nhúng từ bên ngoài bối cảnh của đối tượng parent.
- Sử dụng mảng tham chiếu đến các đối tượng N-side nếu loại là One to many.
- Sử dụng một tham chiếu đến 1-side trong các đối tượng N-side nếu loại là One to squillions.
- Internet of Thing.
Hiện nay, IoT đang nổi lên như một xu hướng phát triển mới của Công nghệ thông tin. Nhắc đến IoT là nhắc đến các sensor. Lượng dữ liệu được sinh ra bởi sensor là rất lớn, và chúng ta cần lưu trữ, xử lý những dữ liệu này để đạt được mục đích của mình. Việc này có thể sử dụng Cơ sở dữ liệu quan hệ để xử lý.
Tuy nhiên, Cơ sở dữ liệu quan hệ(RDBMS) đã bộc lộ nhiều hạn chế. Số lượng các loại sensor rất lớn, và có xu hướng tăng lên, thay đổi theo từng ngày nên việc lưu trữ thêm vào RDBMS là rất khó khăn. Ngoài ra, không dễ gì mở rộng RDBMS, đồng thời dữ liệu sensor phải được phân tích xử lý theo thời gian thực. Những điều này RDBMS không thể giải quyết được, tuy nhiên MongoDB thì hoàn toàn có thể.
Do MongoDB cho phép lưu trữ và xử lý nhiều kiểu cấu trúc dữ liệu: sự kiện, dãy thời gian, text... Cấu trúc model mềm dẻo, cho phép thay đổi dễ dàng. Thêm nữa, MongoDB cung cấp cơ chế cho phép scale dễ dàng.
- Di động.
- Phân tích thời gian thực - Real-time Analytics.
- Cá nhân hóa.
- Catalogs.
- Quản lý nội dung.
- MongoDB as a Database for Scalable (Web) Applications.
MongoDB là lựa hàng hàng đầu khi lưu trữ dữ liệu cho ứng dụng web, nhờ những đặc điểm sau:
- Khả năng mở rộng: Yêu cầu gửi đến ứng dụng web cùng với khối lượng dữ liệu là rất lớn và tăng đều đặn.
- Tính khả dụng: Có khả năng thiết lập node ở chế độ chờ (stand-by) để hệ thống luôn hoạt động, ngay cả khi có server xảy ra hỏng hóc.
- Tính nhất quán cuối cùng(Eventual Consistency): Khi có một hoạt động write xảy ra, không yêu cầu các reading client phải lấy về dữ liệu được cập nhật, thêm vào ngay lập tức. Sử dụng MongoDB, có thể sẽ mất một khoảng thời gian ngắn( thường > 1s) trước khi dữ liệu được hoàn toàn cập nhật.
- Tính nhất quản được đặt lên trên tính khả dụng: Trong một số trường hợp, không thể đồng thời đảm bảo tính khả dụng và tính nhất quản, vì vậy MongoDB sẽ đặt tính nhất quán lên trước tính khả dụng.
- MongoDB as an Object Store for Scalable Web Applications.
MongoDB lưu trữ dữ liệu theo dạng JSON-document và nhóm lại thành các collections. Bình thường mọi ứng dụng đều phải lưu trữ file nhị phân như video, ảnh,... Sau đó, sử dụng MongoDB để lưu trữ chúng vào documents. Tuy nhiên, document chỉ có thể nhỏ hơn 16MB.
Để có thể lưu trữ file lớn hơn, MongoDB cung cấp hệ thống con GridFS. GridFS chia file lớn thành các chunk, vừa với document. Khi đọc file từ GridFS, file được gộp lại các chunk lấy từ documents.
Nhờ tính năng này, MongoDB có thể được sử dụng như Object Store cho ứng dụng Web, lưu trữ ảnh, video, văn bản...
- MongoDB as a Store for Log Events (Operational Intelligence).
Khi chạy các phần mềm, chúng thường được cấu hình để sinh ra những thông điệp log. Ví dụ web server sẽ sinh ra thông điệp log cho từng HTTP request mà nó xử lý. Thông điệp này có thể chứa vài thông tin như thời gian nhận request, URL, trình duyệt web...
Các thông điệp log truyền thống thường được lưu trữ trong file trong cùng một machine mà hệ thống đang thực thi. Điều này khiến cho việc phân tích dữ liệu trở nên khó khăn, đặc biệt khi hệ thống được triển khai phân tán. Quay lại với ví dụ về web server, hãy tưởng tượng chúng ta có một cụm web server, mỗi web server lại sinh ra thông điệp log. Để phân tích dữ liệu, đầu tiên chúng ta phải đi thu thập dữ liệu log ở từng server trong cụm.
Thay vì ghi log vào các file khác nhau, nên sử dụng cơ sở dữ liệu như MongoDB để lưu trữ chúng. Khả năng mở rộng theo chiều ngang cho phép xử lý việc các thông điệp tăng lên nhanh chóng. Trên thực tế, MongoDB chỉ cung cấp eventual consistency vì trường hợp này không yêu cầu strong consistency.
Để cho phép một lượng lớn thông điệp log đến cùng lúc, có thể cấu hình MongoDB bỏ qua tính bền vững của dữ liệu. Điều đó không có nghĩa, dữ liệu không được lưu trữ lại, mà chỉ có nghĩa là khi có một client thêm vào 1 bản ghi, MongoDB sẽ không gửi xác nhận lại cho client rằng việc thêm vào đã thành công.
Tính năng tập hợp, nhóm lại của MongoDB sẽ rất có ích trong việc phân tích thông điệp log. Ví dụ, gom nhóm log đến trong một khoảng thời gian cố định, sắp xếp, sau đó xử lý, phân tích hoặc biểu đồ hóa.
- https://www.mongodb.com/mongodb-architecture
- http://www.ibm.com/developerworks/data/library/techarticle/dm-1306mongodb/
- http://www.slideshare.net/mongodb/an-enterprise-architects-view-of-mongodb-40882393
- http://blog.mongodb.org/post/87200945828/6-rules-of-thumb-for-mongodb-schema-design-part-1
- https://www.mongodb.com/presentations/schema-design-basics-1
- https://docs.mongodb.org/ecosystem/use-cases/
- http://www.slideshare.net/mongodb/common-use-cases-hannes
- https://tinhte.vn/threads/mongodb-nosql-la-gi.2243949/
- http://kipalog.com/posts/Gioi-thieu-MongoDB
- http://bsonspec.org/
- http://kipalog.com/posts/6-Quy-tac-thiet-ke-schema-MongoDB--phan-1
- http://techmaster.vn/posts/33431/co-so-du-lieu-mongodb
- http://vietjack.com/mongodb/mongodb_advantages.jsp
- http://highscalability.com/blog/2014/3/5/10-things-you-should-know-about-running-mongodb-at-scale.html
- http://www.slideshare.net/mongodb/mongodb-days-silicon-valley-jumpstart-the-right-and-wrong-use-cases-for-mongodb
- https://viblo.asia/duongichi/posts/57rVRqDQv4bP
- http://specify.io/systems/mongodb/features-and-usecases
- https://www.pythian.com/blog/when-is-mongodb-the-right-choice-for-your-business-we-explore-detailed-use-cases-2/
Features: (Ai tìm hiểu cái này ?)