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

Sử dụng UUID thay vì ObjectID trong MongoDB

Sử dụng UUID trong Mongo chắc chắn là có thể và được hỗ trợ hợp lý. Ví dụ:tài liệu Mongo liệt kê UUID là một trong những tùy chọn phổ biến cho _id trường.

Cân nhắc

  • Hiệu suất - Như các câu trả lời khác đã đề cập, điểm chuẩn hiển thị UUID gây giảm hiệu suất cho các lần chèn. Trong trường hợp xấu nhất được đo (đi từ 10 triệu đến 20 triệu tài liệu trong một bộ sưu tập), chúng chậm hơn khoảng 2-3 lần - sự khác biệt giữa việc chèn 2.000 (UUID) và 7.500 (ObjectID) tài liệu mỗi giây. Đây là một sự khác biệt lớn nhưng ý nghĩa của nó phụ thuộc hoàn toàn vào trường hợp sử dụng của bạn. Bạn sẽ chèn hàng triệu tài liệu cùng một lúc chứ? Đối với hầu hết các ứng dụng mà tôi đã xây dựng, trường hợp phổ biến là chèn các tài liệu riêng lẻ. Các điểm chuẩn giống nhau cho thấy rằng, đối với kiểu sử dụng đó, sự khác biệt là nhiều nhỏ hơn (6.250-chọi- 7.500; ~ 20%). Không đáng kể .. nhưng cũng không phải đất rung chuyển.
  • Tính di động - Nhiều nền tảng DB khác có hỗ trợ UUID tốt nên tính di động sẽ được cải thiện. Ngoài ra, vì UUID lớn hơn (nhiều bit hơn) nên có thể đóng gói lại một ObjectID thành "hình dạng" của một UUID. Cách tiếp cận này không tốt bằng tính di động trực tiếp nhưng nó cung cấp cho bạn một cách để "ánh xạ" giữa các ObjectID và UUID hiện có.
  • Phân cấp - Một trong những điểm bán hàng lớn của UUID là chúng hoàn toàn độc đáo. Điều này làm cho nó thực tế để tạo chúng ở bất cứ đâu, theo cách phi tập trung (trái ngược với, ví dụ:giá trị tự động tăng dần, yêu cầu một nguồn xác thực tập trung để xác định giá trị "tiếp theo"). Tất nhiên, các ID đối tượng Mongo cũng tuyên bố lợi ích này. Sự khác biệt là, UUID dựa trên tiêu chuẩn 15+ tuổi và được hỗ trợ trên (gần như?) Tất cả các nền tảng, ngôn ngữ, v.v. Điều này làm cho chúng rất hữu ích nếu bạn cần tạo các thực thể (hoặc cụ thể là các bộ liên quan các thực thể) trong các hệ thống rời rạc, không tương tác với cơ sở dữ liệu. Bạn có thể tạo tập dữ liệu với các ID và khóa ngoại tại chỗ, sau đó ghi toàn bộ biểu đồ vào cơ sở dữ liệu tại một thời điểm nào đó trong tương lai mà không bị xung đột. Mặc dù điều này cũng có thể thực hiện được với Mongo ObjectID, nhưng việc tìm kiếm mã để tạo chúng / làm việc với định dạng thường sẽ khó hơn.

Sửa chữa

Trái ngược với một số câu trả lời khác:

  • UUID có hỗ trợ Mongo gốc - Bạn có thể sử dụng UUID() hoạt động trong Mongo Shell giống hệt như cách bạn sử dụng ObjectID(); để chuyển đổi một chuỗi UUID thành đối tượng BSON tương đương.
  • UUID không đặc biệt lớn - Khi được mã hóa bằng kiểu con nhị phân 0x04 chúng là 128 bit, so với 96 bit của ObjectID. (Nếu được mã hóa dưới dạng chuỗi, chúng sẽ khá lãng phí, chiếm khoảng 288 bit.)
  • UUID có thể bao gồm dấu thời gian - Cụ thể, UUIDv1 mã hóa một dấu thời gian với độ chính xác 60 bit, so với 32 bit trong ObjectID. Đây là độ chính xác cao hơn 6 bậc, vì vậy nano giây thay vì giây. Nó thực sự có thể là một cách tốt để lưu trữ tạo dấu thời gian với độ chính xác hơn so với hỗ trợ đối tượng Mongo / JS Date, tuy nhiên ...
    • Bản dựng trong UUID() hàm chỉ tạo UUID v4 (ngẫu nhiên), do đó, để tận dụng điều này, bạn sẽ dựa vào ứng dụng hoặc trình điều khiển Mongo của mình để tạo ID.
    • Không giống như các ObjectID, do cách phân chia các UUID, dấu thời gian không cung cấp cho bạn một thứ tự tự nhiên. Điều này có thể tốt hoặc xấu tùy thuộc vào trường hợp sử dụng của bạn. (Các tiêu chuẩn mới có thể thay đổi điều này; xem bản cập nhật năm 2021 bên dưới.)
    • Đưa dấu thời gian vào ID của bạn đôi khi là một Ý tưởng Xấu. Bạn sẽ làm rò rỉ thời gian đã tạo của tài liệu ở bất kỳ nơi nào ID bị lộ. (Tất nhiên các ObjectID cũng mã hóa một dấu thời gian nên điều này cũng đúng với chúng một phần.)
    • Nếu bạn thực hiện việc này với UUID v1 (tuân thủ đặc điểm kỹ thuật), bạn cũng đang mã hóa một phần địa chỉ MAC của máy chủ, có thể có khả năng được sử dụng để xác định máy. Có lẽ không phải là một vấn đề đối với hầu hết các hệ thống nhưng cũng không phải là lý tưởng. (Các tiêu chuẩn mới có thể thay đổi điều này; xem bản cập nhật năm 2021 bên dưới.)

Kết luận

Nếu bạn nghĩ về Mongo DB của mình một cách riêng biệt, thì ObjectID là sự lựa chọn rõ ràng. Chúng hoạt động tốt và là một mặc định hoàn toàn có khả năng. Sử dụng UUID thay vào đó không thêm một số khó khăn, cả khi làm việc với các giá trị (cần chuyển đổi sang kiểu nhị phân, v.v.) và về hiệu suất. Liệu sự bất tiện nhỏ này có đáng để sở hữu một định dạng ID chuẩn hóa thực sự hay không phụ thuộc vào tầm quan trọng của bạn đối với tính di động và lựa chọn kiến ​​trúc của bạn.

Bạn sẽ đồng bộ hóa dữ liệu giữa các nền tảng cơ sở dữ liệu khác nhau chứ? Bạn sẽ di chuyển dữ liệu của mình sang một nền tảng khác trong tương lai chứ? Bạn có cần tạo ID bên ngoài cơ sở dữ liệu, trong các hệ thống khác hoặc trong trình duyệt? Nếu không phải bây giờ vào một thời điểm nào đó trong tương lai? UUID có thể đáng gặp rắc rối.

Cập nhật tháng 8 năm 2021

IEFT gần đây đã xuất bản bản cập nhật nháp cho thông số UUID sẽ giới thiệu một số phiên bản mới của định dạng.

Cụ thể, UUIDv6 và UUIDv7 dựa trên UUIDv1 nhưng lật các khối dấu thời gian để các bit được sắp xếp từ quan trọng nhất đến ít quan trọng nhất. Điều này cung cấp cho các giá trị kết quả một thứ tự tự nhiên (nhiều hơn hoặc ít hơn) phản ánh thứ tự mà chúng được tạo ra. Các phiên bản mới cũng loại trừ dữ liệu lấy từ địa chỉ MAC của máy chủ, giải quyết những lời chỉ trích lâu nay về các UUID v1.

Sẽ mất thời gian để những thay đổi này chuyển sang triển khai nhưng (IMHO) chúng hiện đại hóa và cải thiện đáng kể định dạng.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Mongoose Query để lọc một mảng và điền nội dung liên quan

  2. Cách tối ưu hóa hiệu suất của ClusterControl và các thành phần của nó

  3. Xóa đối tượng khỏi mảng lồng nhau theo nhiều tiêu chí

  4. Tham chiếu các tài liệu khác theo chuỗi thay vì đối tượng

  5. $ bỏ qua và $ giới hạn trong khuôn khổ tổng hợp