2009-07-01 57 views
14

Tôi nghĩ đã đến lúc phải xem xét cơ sở dữ liệu OO và quyết định sử dụng db4o cho dự án nhỏ tiếp theo của tôi - một thư viện nhỏ.Làm thế nào để thiết kế mối quan hệ nhiều-nhiều trong một cơ sở dữ liệu đối tượng?

Hãy xem xét các đối tượng sau: Sách, Danh mục.

Sách có thể nằm trong danh mục 0-n và Danh mục có thể được áp dụng cho 0-m Sách.

Suy nghĩ đầu tiên của tôi là có một đối tượng tham gia như BookCatecory nhưng sau một chút Googling tôi thấy rằng điều này là không thích hợp cho 'Real OO'.

Cách tiếp cận khác (được nhiều người khuyên dùng) là có danh sách trong cả hai đối tượng: Book.categories và Category.books. Một bên xử lý mối quan hệ: Book.addCategory thêm Category vào Book.categories và Book vào Category.books. Làm thế nào để xử lý các cam kết và rollback khi 2 đối tượng được thay đổi trong một cuộc gọi phương thức?

Suy nghĩ của bạn là gì? Cách tiếp cận thứ hai có lợi thế rõ ràng nhưng, đối với tôi ít nhất, người đầu tiên 'cảm thấy' đúng (tốt hơn chuẩn).

Trả lời

5

Nếu bạn sử dụng cơ sở dữ liệu đối tượng, bạn không cần phải quan tâm cách các mối quan hệ được lưu trữ trong cơ sở dữ liệu. Bạn định nghĩa các lớp và mối quan hệ giữa chúng. Vui lòng đọc tài liệu tham khảo được hướng dẫn đến cơ sở dữ liệu của bạn. Ví dụ về mối quan hệ:

n:n attribute, referencing from the parent 
------------------------------------------------------------------ 
class Person{ 
List addresses; 
} 

class Address{ 
} 


n:n attribute, referencing from the child 
------------------------------------------------------------------ 
class Person{ 
} 

class Address{ 
List persons 
} 

n:n attribute, bidirectional references 
------------------------------------------------------------------ 
class Person{ 
List addresses; 
} 

class Address{ 
List persons 
} 
1

Tôi nghĩ rằng bạn chỉ là một chút treo trên cách suy nghĩ quan hệ db. Danh sách trong mỗi đối tượng là điều đúng OO cần làm. Cam kết và quay lại không có vấn đề gì, chúng xảy ra trong một giao dịch cam kết mọi thứ hoặc cuộn lại mọi thứ.

1

Trong cơ sở dữ liệu OO thuần túy như GemStone, chính các đối tượng có bộ sưu tập các tham chiếu đến các đối tượng khác. Khi đối tượng được tham chiếu từ ứng dụng, OODBMS tạo ra một proxy kết thúc tốt đẹp đối tượng. Giản đồ cho điều này chỉ là đối tượng được lưu giữ và tập hợp các tham chiếu đến các đối tượng mà nó đề cập đến. OODBMS không nhất thiết cần một thực thể liên kết.

Với lớp ánh xạ O/R (giả sử nó đủ thông minh để thực hiện mối quan hệ M: M), mối quan hệ M: M được biểu hiện dưới dạng tập hợp các tham chiếu phụ trên chính đối tượng mà trình vẽ O/R giải quyết liên kết thực thể đằng sau hậu trường. Không phải tất cả những người lập bản đồ O/R đều làm điều này, vì vậy bạn có thể có một đối tượng liên kết riêng biệt.

1

Bạn có lý do cụ thể nào bạn muốn sử dụng ODBMS không? Đối với các cấu trúc dữ liệu đơn giản (chẳng hạn như phân loại sách), bạn thường sẽ không tìm thấy bất kỳ lợi thế nào trong ODBMS trên RDBMS và trên thực tế sẽ có thời gian làm việc dễ dàng hơn trong thế giới RDBMS được chuẩn hóa nhiều hơn. ODBMS có những lợi thế rất hữu hình khi bạn đang làm việc với các kiểu dữ liệu phức tạp hoặc sự lưu giữ/lưu trữ theo nghĩa đen của các đối tượng động. ODBMS cũng được trích dẫn là nhanh hơn và có khả năng mở rộng hơn RDBMS, mặc dù tôi có thể cung cấp một chút thông tin chi tiết về điều này. Dưới đây là một vài trang thảo luận RDBMS vs ODBMS, tuy nhiên:

Whatever Happened to Object-Oriented Databases

Object-Oriented Database vs. Object-Rleational Database (SO)

+0

Tôi muốn xem liệu tôi có thể tránh việc tạo ra một dbschema, tạo bảng, tạo đối tượng, ánh xạ bảng cho đối tượng, v.v. v.v. Có vẻ như một odbms có thể cắt ra rất nhiều công việc lừa ... – paul

+0

Nó có thể cắt ra một số công việc đó, nhưng như vậy sẽ là một lớp ORM phong nha. Tôi không nói rằng ODBMS là sự lựa chọn sai, nhưng có những lựa chọn thay thế có thể phục vụ bạn tốt hay tốt hơn. –

0

tôi sẽ tránh trùng lặp dữ liệu vì sau đó bạn chạy vào tất cả các loại vấn đề với việc sáp nhập sự khác biệt.

mẹo để làm điều này là tham chiếu.

kết quả là tôi sẽ có mỗi đối tượng chứa một tập hợp các tham chiếu đến loại đối tượng khác cũng như có một bộ sưu tập độc lập của các đối tượng khác.

Bảng phù hợp là khái niệm quan hệ, trừ khi lớp kết nối trung gian đó có thể có các thuộc tính không thuộc về một trong hai đối tượng. Nó có đó vì nó cho phép các truy vấn được viết một cách mạnh mẽ vì nó làm giảm mối quan hệ với 2 đến nhiều mối quan hệ và làm giảm đáng kể sao chép dữ liệu. Nếu bạn đã làm điều này trong một cơ sở dữ liệu quan hệ mà không có bảng phù hợp thì mọi thứ sẽ nhận được cái ác rất nhanh chóng - làm thế nào một bản cập nhật sẽ hoạt động? Cá nhân tôi tìm thấy sự hấp dẫn của oo cơ sở dữ liệu được bước ra khỏi điều này

cách mà tôi sẽ buộc tất cả các đối tượng với nhau là thông qua các sự kiện trong mã để xử lý giao dịch một số loại cho phép bộ nhớ đệm của các đối tượng tiểu bang. vì vậy thay vì các đối tượng thao tác với mỗi thuộc tính khác, chúng yêu cầu thay đổi thông qua trình xử lý và chờ kết quả trong cuộc gọi lại.

8

Thực sự chỉ có hai cách tôi có thể nghĩ đến để giải quyết vấn đề này, cả hai đều đã đề cập đến. Cá nhân, tôi sẽ đi với cách tiếp cận đầu tiên (tạo một đối tượng ánh xạ như một thực thể OO). Điều này ngăn cản bạn giữ thông tin dư thừa xung quanh và phải đồng bộ hóa; nó cũng có nghĩa là nếu hiệp hội kết thúc có các lĩnh vực riêng của mình (ngày mà cuốn sách được gán cho thể loại đó, giả sử), chúng có thể được kết hợp một cách dễ dàng. Chúng tôi sử dụng phương pháp này cho một loạt các hiệp hội trong hệ thống của chúng tôi.

Đối tượng OO sẽ trông như thế:

BookCategory { 
Book book 
Category category 
} 
Book { 
Collection <BookCategory> categories 
} 
Category { 
Collection <BookCategory> categories 
} 

Ở đây bạn có để giữ các đối tượng liên quan và hai bộ sưu tập đồng bộ; tuy nhiên, các bộ sưu tập là tùy chọn trong trường hợp này. Thông thường bạn có thể nhận được các thông tin tương tự với một truy vấn ORM, một cái gì đó như: chọn b.book từ BookCategory b nơi b.category = MyCategory

Cách khác là để có một thiết lập như:

Book { 
Collection<Category> categories 
} 

Category { 
Collection<Books> books 
} 

Nếu công cụ ORM/DB của bạn tự động duy trì các liên kết, điều này là tốt; nếu không, bạn đang bị mắc kẹt khi cập nhật cả hai bộ sưu tập. (Trong Hibernate, một bên sẽ có thuộc tính: inverse = true trên ánh xạ; mặt này không được cập nhật, do đó, nói đúng là nó không cần phải được duy trì. Điều này có vẻ như tôi thực hành không tốt.)

Nếu bạn thường chỉ truy cập vào mối quan hệ một cách (ví dụ, nhận tất cả các sách trong một danh mục), bạn có thể loại bỏ bộ sưu tập ở phía bên kia; sau đó tôi nghĩ bạn sẽ phải làm việc xung quanh công cụ ORM và sử dụng truy vấn gốc để truy cập mối quan hệ từ hướng khác.

Chúng tôi sử dụng Hibernate (một công cụ lập bản đồ quan hệ đối tượng dựa trên java) trên dự án của chúng tôi; tài liệu Hibernate là một tài liệu tham khảo tốt cho các vấn đề thiết kế quan hệ/OO, mặc dù bạn có thể phải dành một chút thời gian học Hibernate để làm cho chúng hữu ích: http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#collections-ofvalues

HTH!

+0

Tôi nên đề cập đến rằng tôi không quen thuộc với db40; câu trả lời này áp dụng chung cho vấn đề ORM mà bạn mô tả, tôi hy vọng =) – RMorrisey

+0

+1 cảm ơn câu trả lời và các mẹo ngủ đông – paul