MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Các yếu tố hoạt động cần xem xét trong quá trình tạo mô hình dữ liệu MongoDB

Trong blog trước của tôi, Cách sử dụng Mô hình hóa dữ liệu MongoDB để cải thiện hoạt động thông lượng, chúng tôi đã thảo luận về 2 phương pháp tiếp cận mối quan hệ mô hình hóa dữ liệu chính đó là nhúng và tham chiếu. Khả năng mở rộng của MongoDB khá phụ thuộc vào kiến ​​trúc của nó và cụ thể là mô hình dữ liệu. Khi thiết kế một NoSQL DBM, điểm cần lưu ý chính là đảm bảo các tài liệu không có lược đồ bên cạnh một số lượng nhỏ các bộ sưu tập nhằm mục đích bảo trì dễ dàng. Tính toàn vẹn của dữ liệu tốt, áp dụng xác thực dữ liệu thông qua một số quy tắc xác định trước khi lưu trữ được khuyến khích. Kiến trúc và thiết kế cơ sở dữ liệu nên được chuẩn hóa và phân tách thành nhiều tập hợp nhỏ như một cách tránh lặp lại dữ liệu, cải thiện tính toàn vẹn của dữ liệu và giúp dễ dàng với các mẫu truy xuất. Với tính năng này, bạn có thể cải thiện tính nhất quán của dữ liệu, tính nguyên tử, độ bền và tính toàn vẹn của cơ sở dữ liệu của mình.

Mô hình hóa dữ liệu không phải là một công việc cần cân nhắc trước trong giai đoạn phát triển ứng dụng mà là một sự cân nhắc ban đầu vì nhiều khía cạnh ứng dụng thực sự được thực hiện trong giai đoạn mô hình hóa dữ liệu. Trong bài viết này, chúng ta sẽ thảo luận về những yếu tố nào cần được xem xét trong quá trình lập mô hình dữ liệu và xem chúng ảnh hưởng như thế nào đến hiệu suất của cơ sở dữ liệu nói chung.

Nhiều khi bạn sẽ cần triển khai một cụm cơ sở dữ liệu của mình như một cách để tăng tính khả dụng của dữ liệu. Với một mô hình dữ liệu được thiết kế tốt, bạn có thể phân phối các hoạt động đến một cụm phân đoạn hiệu quả hơn, do đó giảm các hoạt động thông lượng nhằm vào một phiên bản mongod duy nhất. Các yếu tố chính cần xem xét trong mô hình dữ liệu bao gồm:

  1. Khả năng mở rộng
  2. Tính nguyên tử
  3. Hiệu suất và Sử dụng dữ liệu
  4. Làm sắc nét
  5. Lập chỉ mục
  6. Tối ưu hóa dung lượng
  7. Cấu trúc tài liệu và tốc độ tăng trưởng
  8. Vòng đời dữ liệu

1. Khả năng mở rộng

Đây là sự gia tăng khối lượng công việc của một ứng dụng do lưu lượng truy cập tăng lên. Nhiều ứng dụng luôn kỳ vọng vào sự gia tăng số lượng người dùng của nó. Khi có quá nhiều người dùng được phục vụ bởi một phiên bản cơ sở dữ liệu duy nhất, hiệu suất không phải lúc nào cũng đáp ứng mong đợi. Với tư cách là người quản lý cơ sở dữ liệu, do đó bạn có nhiệm vụ thiết kế DBM này sao cho các tập hợp và thực thể dữ liệu được mô hình hóa dựa trên nhu cầu hiện tại và tương lai của ứng dụng. Cấu trúc cơ sở dữ liệu nói chung phải dễ nhìn để tăng cường quá trình sao chép và phân tách dễ dàng. Khi bạn có nhiều phân đoạn hơn, các hoạt động ghi được phân phối giữa các phân đoạn này để đối với bất kỳ bản cập nhật dữ liệu nào, nó được thực hiện trong phân đoạn chứa dữ liệu đó thay vì tìm kiếm trong một tập hợp dữ liệu lớn duy nhất để thực hiện cập nhật.

2. Tính nguyên tử

Điều này đề cập đến sự thành công hay thất bại của một hoạt động như một đơn vị duy nhất. Ví dụ, bạn có thể có một thao tác đọc liên quan đến một thao tác sắp xếp sau khi tìm nạp kết quả. Nếu thao tác sắp xếp không được xử lý đúng cách, do đó toàn bộ hoạt động sẽ không được chuyển sang giai đoạn tiếp theo.

Các giao dịch nguyên tử là một loạt các hoạt động không thể phân chia hoặc không thể rút gọn do đó xảy ra như một thực thể đơn lẻ hoặc không thành công như một hoạt động đơn lẻ. Các phiên bản MongoDB trước 4.0 hỗ trợ các hoạt động ghi dưới dạng các quy trình nguyên tử trên một cấp tài liệu duy nhất. Với phiên bản 4.0, giờ đây người ta có thể thực hiện các giao dịch đa tài liệu. Mô hình dữ liệu nâng cao hoạt động nguyên tử có xu hướng có hiệu suất lớn về độ trễ. Độ trễ chỉ đơn giản là khoảng thời gian mà một yêu cầu hoạt động được gửi đi và khi một phản hồi được trả lại từ cơ sở dữ liệu. Để bảo mật, có thể dễ dàng cập nhật dữ liệu được nhúng trong một tài liệu duy nhất thay vì một tài liệu được tham chiếu.

Ví dụ, hãy xem xét tập dữ liệu bên dưới

{
    childId : "535523",
    studentName : "James Karanja",
    parentPhone : 704251068,
    age : 12,
    settings : {
        location : "Embassy",
        address : "420 01",
        bus : "KAZ 450G",
        distance : "4"
      }
}

Nếu chúng tôi muốn cập nhật độ tuổi bằng cách tăng nó lên 1 và thay đổi vị trí thành London, chúng tôi có thể làm:

db.getCollection(‘students’).update({childId: 535523},{$set:{'settings.location':'London'}, $inc:{age:1}}).

Ví dụ:nếu hoạt động $ set không thành công, thì tự động hoạt động $ inc sẽ không được triển khai và nói chung toàn bộ hoạt động không thành công.

Mặt khác, hãy xem xét thành công dữ liệu được tham chiếu rằng có 2 bộ sưu tập, một bộ dành cho học sinh và bộ sưu tập còn lại dành cho cài đặt.

Bộ sưu tập sinh viên

{
    childId : "535523",
    studentName : "James Karanja",
    parentPhone : 704251068,
    age : 12
}

Bộ sưu tập cài đặt

{
  childId : "535523",  
  location : "Embassy",
  address : "420 01",
  bus : "KAZ 450G",
  distance : "4"
}

Trong trường hợp này, bạn có thể cập nhật các giá trị tuổi và vị trí bằng các thao tác ghi riêng biệt .i.e

db.getCollection(‘students’).update({childId: 535523},{$inc:{age:1}})
db.getCollection('settings’).update({childId: 535523 } , {$set: { 'settings.location':'London'}})

Nếu một trong các hoạt động không thành công, nó không nhất thiết ảnh hưởng đến hoạt động kia vì chúng được thực hiện như các thực thể khác nhau.

Giao dịch cho nhiều tài liệu

Với MongoDB phiên bản 4.0, giờ đây bạn có thể thực hiện nhiều giao dịch tài liệu cho các tập hợp bản sao. Điều này cải thiện hiệu suất vì các hoạt động được cấp cho một số bộ sưu tập, cơ sở dữ liệu và tài liệu để xử lý nhanh. Khi một giao dịch đã được cam kết, dữ liệu sẽ được lưu trong khi nếu có sự cố và một giao dịch không thành công, các thay đổi đã được thực hiện sẽ bị loại bỏ và giao dịch nói chung sẽ bị hủy bỏ. Sẽ không có bản cập nhật nào đối với bộ bản sao trong quá trình giao dịch vì hoạt động chỉ hiển thị bên ngoài khi giao dịch được cam kết hoàn toàn.

Việc bạn có thể cập nhật nhiều tài liệu trong nhiều giao dịch càng nhiều càng tốt, điều đó đi kèm với việc giảm hiệu suất so với việc ghi tài liệu đơn lẻ. Bên cạnh đó, cách tiếp cận này chỉ được hỗ trợ cho công cụ lưu trữ WiredTiger do đó sẽ là một bất lợi cho công cụ lưu trữ trong bộ nhớ và MMAPv1.

3. Hiệu suất và Sử dụng dữ liệu

Các ứng dụng được thiết kế khác nhau để đáp ứng các mục đích khác nhau. Có một số chỉ phục vụ cho dữ liệu hiện tại như các ứng dụng tin tức thời tiết. Tùy thuộc vào cấu trúc của một ứng dụng, người ta có thể thiết kế một cơ sở dữ liệu tối ưu tương ứng để phục vụ cho trường hợp sử dụng cần thiết. Ví dụ:nếu một người phát triển một ứng dụng tìm nạp dữ liệu gần đây nhất từ ​​cơ sở dữ liệu, sử dụng bộ sưu tập có giới hạn sẽ là lựa chọn tốt nhất. Bộ sưu tập có giới hạn nâng cao hoạt động thông lượng cao giống như một bộ đệm để khi không gian được cấp phát được khai thác, các tài liệu cũ nhất sẽ bị ghi đè và các tài liệu có thể được tìm nạp theo thứ tự chúng được chèn vào. Xem xét việc truy xuất thứ tự chèn, sẽ không cần sử dụng lập chỉ mục và việc không có chi phí chỉ mục sẽ cải thiện như nhau về thông lượng ghi. Với bộ sưu tập có giới hạn, dữ liệu liên quan là khá nhỏ nên nó có thể được duy trì trong RAM một thời gian. Dữ liệu tạm thời trong trường hợp này được lưu trữ trong bộ đệm ẩn khá dễ đọc hơn là được ghi vào, do đó làm cho hoạt động đọc diễn ra khá nhanh. Tuy nhiên, bộ sưu tập có giới hạn đi kèm với một số nhược điểm như bạn không thể xóa tài liệu trừ khi bỏ toàn bộ bộ sưu tập, bất kỳ thay đổi nào đối với kích thước của tài liệu sẽ không thực hiện được thao tác và cuối cùng là không thể chia nhỏ bộ sưu tập có giới hạn.

Các khía cạnh khác nhau được tích hợp trong mô hình dữ liệu của cơ sở dữ liệu tùy theo nhu cầu sử dụng. Như đã thấy, các ứng dụng báo cáo sẽ có xu hướng được đọc nhiều hơn, do đó thiết kế phải theo cách để cải thiện thông lượng đọc.

4. Làm sắc nét

Hiệu suất thông qua chia tỷ lệ ngang có thể được cải thiện bằng cách sharding vì khối lượng công việc đọc và ghi được phân phối giữa các thành viên cụm. Triển khai một cụm phân đoạn có xu hướng phân vùng cơ sở dữ liệu thành nhiều bộ sưu tập nhỏ với các tài liệu phân tán tùy thuộc vào một số khóa phân đoạn. Bạn nên chọn một khóa phân đoạn thích hợp có thể ngăn cách ly truy vấn bên cạnh việc tăng khả năng ghi. Lựa chọn tốt hơn thường liên quan đến một trường có trong tất cả các tài liệu trong bộ sưu tập được nhắm mục tiêu. Với sharding, bộ nhớ được tăng lên vì khi dữ liệu phát triển, nhiều phân đoạn hơn được thiết lập để giữ một tập hợp con của cụm này.

5. Lập chỉ mục

Lập chỉ mục là một trong những cách tiếp cận tốt nhất để cải thiện khối lượng công việc ghi, đặc biệt là khi các trường xuất hiện trong tất cả các tài liệu. Khi thực hiện lập chỉ mục, người ta nên cân nhắc rằng mỗi chỉ mục sẽ yêu cầu 8KB không gian dữ liệu. Hơn nữa, khi chỉ mục hoạt động, nó sẽ tiêu tốn một số dung lượng đĩa và do đó bộ nhớ cần được theo dõi để lập kế hoạch dung lượng.

Vài người trở thành MongoDB DBA - Đưa MongoDB vào Sản xuất Tìm hiểu về những điều bạn cần biết để triển khai, giám sát, quản lý và mở rộng MongoDBDownload miễn phí

6. Tối ưu hóa bộ nhớ

Nhiều tài liệu nhỏ trong một bộ sưu tập sẽ có xu hướng chiếm nhiều dung lượng hơn so với khi bạn có một vài tài liệu với các tài liệu được nhúng phụ. Do đó, khi lập mô hình, người ta nên nhóm các dữ liệu liên quan trước khi lưu trữ. Với một vài tài liệu, một thao tác cơ sở dữ liệu có thể được thực hiện với một vài truy vấn, do đó làm giảm khả năng truy cập đĩa ngẫu nhiên và sẽ có ít mục nhập khóa liên quan hơn trong chỉ mục tương ứng. Do đó, các cân nhắc trong trường hợp này sẽ là:sử dụng tính năng nhúng để có ít tài liệu hơn, từ đó giảm chi phí trên mỗi tài liệu. Sử dụng tên trường ngắn hơn nếu ít trường liên quan đến bộ sưu tập để không làm cho chi phí tài liệu trở nên đáng kể. Tên trường ngắn hơn làm giảm độ biểu cảm. I.e.

{ Lname : "Briston", score : 5.9 }

sẽ tiết kiệm 9 byte cho mỗi tài liệu hơn là sử dụng

{ last_name : "Briston", high_score: 5.9 }

Sử dụng trường _id một cách rõ ràng. Theo mặc định, các ứng dụng khách MongoDB thêm trường _id vào mỗi tài liệu bằng cách gán một ObjectId 12 byte duy nhất cho trường này. Bên cạnh đó, trường _id sẽ được lập chỉ mục. Nếu các tài liệu khá nhỏ, trường hợp này sẽ chiếm một lượng lớn không gian trong tổng số tài liệu. Để tối ưu hóa bộ nhớ, bạn được phép chỉ định giá trị cho trường _id một cách rõ ràng khi chèn tài liệu vào bộ sưu tập. Tuy nhiên, hãy đảm bảo giá trị được nhận dạng duy nhất vì nó đóng vai trò là khóa chính cho các tài liệu trong bộ sưu tập.

7. Cấu trúc tài liệu và tăng trưởng

Điều này xảy ra do hoạt động đẩy trong đó các tài liệu con được đẩy vào một trường mảng hoặc khi các trường mới được thêm vào tài liệu hiện có. Việc phát triển tài liệu có một số trở ngại, tức là đối với bộ sưu tập có giới hạn, nếu kích thước bị thay đổi thì hoạt động sẽ tự động không thành công. Đối với công cụ lưu trữ MMAPv1, các phiên bản trước 3.0 sẽ định vị lại tài liệu trên đĩa nếu kích thước tài liệu bị vượt quá. Tuy nhiên, các phiên bản sau này kể từ 3.0, có khái niệm Sức mạnh của 2 Phân bổ Kích thước làm giảm cơ hội phân bổ lại như vậy và cho phép tái sử dụng hiệu quả không gian bản ghi đã giải phóng. Nếu bạn mong đợi dữ liệu của mình đang tăng lên, bạn có thể muốn cấu trúc lại mô hình dữ liệu của mình để sử dụng tham chiếu giữa dữ liệu trong các tài liệu riêng biệt thay vì sử dụng mô hình dữ liệu không chuẩn hóa. Để tránh tăng trưởng tài liệu, bạn cũng có thể cân nhắc sử dụng chiến lược phân bổ trước.

8. Vòng đời dữ liệu

Đối với ứng dụng chỉ sử dụng các tài liệu được chèn gần đây, hãy cân nhắc sử dụng bộ sưu tập có giới hạn có các tính năng đã được thảo luận ở trên.

Bạn cũng có thể đặt tính năng Thời gian tồn tại cho bộ sưu tập của mình. Điều này khá áp dụng cho các mã thông báo truy cập trong tính năng đặt lại mật khẩu cho một ứng dụng.

Thời gian để sống (TTL)

Đây là cài đặt thu thập giúp mongod có thể tự động xóa dữ liệu sau một khoảng thời gian được chỉ định. Theo mặc định, khái niệm này được áp dụng cho dữ liệu sự kiện do máy tạo ra, nhật ký và thông tin phiên cần duy trì trong một khoảng thời gian giới hạn.

Ví dụ:

db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )

Chúng tôi đã tạo chỉ mục createAt và chỉ định một số giá trị expireAfterSeconds là 3600, tức là 1 giờ sau thời điểm tạo. Bây giờ nếu chúng ta chèn một tài liệu như:

db.log_events.insert( {
   "createdAt": new Date(),
   "logEvent": 2,
   "logMessage": "This message was recorded."
} )

Tài liệu này sẽ bị xóa sau 1 giờ kể từ thời điểm chèn.

Bạn cũng có thể đặt thời gian cụ thể cho đồng hồ khi bạn muốn xóa tài liệu. Để làm như vậy, trước tiên hãy tạo một chỉ mục, tức là:

db.log_events.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )

Bây giờ chúng ta có thể chèn một tài liệu và chỉ định thời gian khi nó sẽ bị xóa.

db.log_events.insert( {
   "expireAt": new Date(December 12, 2018 18:00:00'),
   "logEvent": 2,
   "logMessage": "Success!"
} )

Tài liệu này sẽ tự động bị xóa khi giá trị expireAt cũ hơn số giây được chỉ định trong expireAfterSeconds, tức là 0 trong trường hợp này.

Kết luận

Mô hình hóa dữ liệu là một công việc rộng rãi cho bất kỳ thiết kế ứng dụng nào nhằm cải thiện hiệu suất cơ sở dữ liệu của nó. Trước khi chèn dữ liệu vào db của bạn, hãy xem xét các nhu cầu của ứng dụng và đâu là các mẫu mô hình dữ liệu tốt nhất mà bạn nên triển khai. Bên cạnh đó, các khía cạnh quan trọng của ứng dụng không thể được thực hiện cho đến khi triển khai một mô hình dữ liệu thích hợp.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Cập nhật thuộc tính tài liệu nhúng trong Mongodb

  2. Cách nhanh nhất để loại bỏ các tài liệu trùng lặp trong mongodb

  3. Nâng cấp nhanh hoặc hàng loạt trong pymongo

  4. Tìm kiếm toàn bộ và một phần văn bản trong MongoDB

  5. Tại sao gặp lỗi mongod dead nhưng subsys bị khóa và Không đủ dung lượng trống cho các tệp tạp chí trên Linux?