Các đối tượng miền dưới dạng id tạo ra một số vấn đề phức tạp / tinh tế:
Tuần tự hóa / giải trừ
Nếu bạn lưu trữ các đối tượng dưới dạng các khóa, nó sẽ làm cho việc tuần tự hóa biểu đồ đối tượng cực kỳ phức tạp. Bạn sẽ gặp stackoverflow
lỗi khi thực hiện tuần tự hóa ngây thơ sang JSON hoặc XML do đệ quy. Sau đó, bạn sẽ phải viết một bộ tuần tự tùy chỉnh để chuyển đổi các đối tượng thực tế để sử dụng id của chúng thay vì tuần tự hóa đối tượng và tạo đệ quy.
Truyền vào các đối tượng để đảm bảo an toàn kiểu nhưng chỉ lưu trữ id, sau đó bạn có thể có một phương thức truy cập lười biếng tải thực thể liên quan khi nó được gọi. Bộ nhớ đệm cấp hai sẽ đảm nhiệm các cuộc gọi tiếp theo.
Rò rỉ tham chiếu tinh tế:
Nếu bạn sử dụng các đối tượng miền trong các hàm tạo như bạn có, bạn sẽ tạo các tham chiếu vòng sẽ rất khó cho phép thu hồi bộ nhớ cho các đối tượng không được sử dụng tích cực.
Tình huống lý tưởng:
Id mờ đục so với int / long:
Một id
nên là một định danh hoàn toàn mờ đục không mang thông tin về những gì nó xác định. Nhưng nó sẽ cung cấp một số xác minh rằng nó là một định danh hợp lệ trong hệ thống của nó.
Các loại nguyên liệu phá vỡ điều này:
int
, long
Và String
là các loại nguyên liệu phổ biến nhất được sử dụng để định danh trong hệ thống RDBMS. Có một lịch sử lâu dài về những lý do thực tế có từ hàng thập kỷ trước và tất cả chúng đều là những thỏa hiệp phù hợp với việc tiết kiệm space
hoặc tiết kiệm time
hoặc cả hai.
Id tuần tự là những kẻ phạm tội tồi tệ nhất:
Khi bạn sử dụng id tuần tự, bạn sẽ đóng gói thông tin ngữ nghĩa tạm thời vào id theo mặc định. Điều này không tệ cho đến khi nó được sử dụng. Khi mọi người bắt đầu viết logic kinh doanh sắp xếp hoặc lọc theo chất lượng ngữ nghĩa của id, thì họ đang thiết lập một thế giới đau khổ cho những người duy trì trong tương lai.
String
Các lĩnh vực có vấn đề vì các nhà thiết kế ngây thơ sẽ đóng gói thông tin vào nội dung, thường là ngữ nghĩa tạm thời.
Những điều này làm cho không thể tạo ra một hệ thống dữ liệu phân tán, bởi vì 12437379123
nó không phải là duy nhất trên toàn cầu. Cơ hội mà một nút khác trong một hệ thống phân tán sẽ tạo ra một bản ghi có cùng số được đảm bảo khá nhiều khi bạn có đủ dữ liệu trong một hệ thống.
Sau đó, hack bắt đầu hoạt động xung quanh nó và toàn bộ điều bị phá hủy thành một đống hỗn độn hấp.
Bỏ qua các hệ thống phân tán lớn ( cụm ) nó sẽ trở thành một cơn ác mộng hoàn toàn khi bạn bắt đầu cố gắng chia sẻ dữ liệu với các hệ thống khác. Đặc biệt là khi hệ thống khác không nằm trong tầm kiểm soát của bạn.
Bạn kết thúc với cùng một vấn đề, làm thế nào để làm cho id của bạn trở nên độc nhất trên toàn cầu.
UUID được tạo và chuẩn hóa vì một lý do:
UUID
có thể bị tất cả các vấn đề được liệt kê ở trên tùy thuộc vào việc Version
bạn sử dụng.
Version 1
sử dụng địa chỉ MAC và thời gian để tạo một id duy nhất. Điều này là xấu vì nó mang thông tin ngữ nghĩa về địa điểm và thời gian. Đó không phải là vấn đề, đó là khi các nhà phát triển ngây thơ bắt đầu dựa vào thông tin đó cho logic kinh doanh. Điều này cũng rò rỉ thông tin có thể bị khai thác trong bất kỳ nỗ lực xâm nhập nào.
Version 2
sử dụng một người dùng UID
hoặc GID
và domian UID
hoặc GUI
thay vì thời gian Version 1
này cũng tệ như Version 1
rò rỉ dữ liệu và mạo hiểm thông tin này được sử dụng trong logic kinh doanh.
Version 3
là tương tự nhưng thay thế địa chỉ MAC và thời gian bằng một MD5
hàm băm của một số mảng byte[]
từ một cái gì đó chắc chắn có ý nghĩa ngữ nghĩa. Không có rò rỉ dữ liệu để lo lắng, byte[]
không thể được phục hồi từ UUID
. Điều này cung cấp cho bạn một cách tốt để tạo một cách xác định UUID
mẫu biểu mẫu và khóa ngoài của một số loại.
Version 4
chỉ dựa trên các số ngẫu nhiên là một giải pháp tốt, nó hoàn toàn không có thông tin ngữ nghĩa, nhưng nó không thể tái tạo một cách xác định.
Version 5
chỉ là thích Version 4
nhưng sử dụng sha1
thay vì md5
.
Khóa miền và khóa dữ liệu giao dịch
Sở thích của tôi đối với id đối tượng miền, là sử dụng Version 5
hoặc Version 3
nếu bị hạn chế sử dụng Version 5
vì một số lý do kỹ thuật.
Version 3
là tuyệt vời cho dữ liệu giao dịch có thể được trải rộng trên nhiều máy.
Trừ khi bạn bị giới hạn bởi không gian, hãy sử dụng UUID:
Chúng được đảm bảo duy nhất, kết xuất dữ liệu từ một cơ sở dữ liệu và tải lại vào cơ sở dữ liệu khác mà bạn không bao giờ phải lo lắng về các id trùng lặp thực sự tham chiếu dữ liệu miền khác nhau.
Version 3,4,5
là hoàn toàn mờ đục và đó là cách họ nên được.
Bạn có thể có một cột duy nhất làm khóa chính với a UUID
và sau đó bạn có thể có các chỉ mục duy nhất ghép cho những gì sẽ là một khóa chính tổng hợp tự nhiên.
Lưu trữ không phải là CHAR(36)
một trong hai. Bạn có thể lưu trữ UUID
trong trường byte / bit / số riêng cho cơ sở dữ liệu đã cho miễn là nó vẫn có thể lập chỉ mục được.
Di sản
Nếu bạn có các kiểu thô và không thể thay đổi chúng, bạn vẫn có thể trừu tượng hóa chúng trong mã của mình.
Sử dụng một Version 3/5
trong số UUID
bạn có thể chuyển vào Class.getName()
+ String.valueOf(int)
dưới dạng a byte[]
và có khóa tham chiếu mờ có thể tái tạo và xác định.