2008-12-08 24 views
6

Tôi có một bảng trong DB (Postgres based), hoạt động giống như một siêu lớp trong lập trình hướng đối tượng. Nó có một cột 'type' để xác định, các cột bổ sung nào sẽ có mặt trong bảng (các thuộc tính lớp con). Nhưng tôi không muốn bảng bao gồm tất cả các cột có thể (tất cả các thuộc tính của tất cả các loại có thể). Vì vậy, tôi quyết định tạo một bảng, tiếp theo các cột 'then chốt' và 'giá trị' (tức là 'tên tệp' = '/ tệp', hoặc 'some_value' = '5'), có chứa bất kỳ thuộc tính có thể có nào của đối tượng, không được bao gồm trong bảng superclass. Và cũng đã tạo một bảng liên quan để chứa các giá trị 'chìa khóa' có sẵn.Cấu trúc DB tối ưu cho các trường bổ sung thực thể

Nhưng có một vấn đề với kiến ​​trúc như vậy - cột 'giá trị' phải thuộc loại dữ liệu chuỗi theo mặc định, để có thể chứa bất kỳ thứ gì. Nhưng tôi không nghĩ chuyển đổi sang và từ dây là một quyết định tốt. Cách tốt nhất để vượt qua giới hạn này là gì?

Trả lời

10

Thiết kế bạn đang thử nghiệm là một biến thể của Entity-Attribute-Value và nó đi kèm với rất nhiều vấn đề và không hiệu quả. Nó không phải là một giải pháp tốt cho những gì bạn đang làm, ngoại trừ một phương sách cuối cùng.

Điều gì có thể là giải pháp tốt hơn là những gì được mô tả trong mô tả: tạo bảng "loại phụ" cho từng loại phụ của bạn. Điều này là không sao nếu bạn có một số lượng nhỏ các kiểu con, có vẻ giống như những gì bạn có. Sau đó, các thuộc tính loại con cụ thể của bạn có thể có các kiểu dữ liệu và cũng có ràng buộc NOT NULL nếu thích hợp, điều này là không thể nếu bạn sử dụng thiết kế EAV.

Một điểm yếu còn lại của thiết kế bảng con là bạn không thể thực thi hàng đó tồn tại trong bảng loại phụ chỉ vì hàng chính trong bảng siêu lớp cho biết. Nhưng đó là một điểm yếu nhẹ hơn so với những người được giới thiệu bởi thiết kế EAV.

chỉnh sửa: Về thông tin bổ sung của bạn về nhận xét đối với bất kỳ thực thể nào, vâng đây là một mẫu khá phổ biến. Hãy coi chừng một giải pháp bị hỏng gọi là "hiệp hội đa hình" là một kỹ thuật mà nhiều người sử dụng trong tình huống này.

0

Cách giải quyết duy nhất (trong khi vẫn giữ strucure của bạn) là phải có bảng riêng biệt:

create table IntProps(...); 
create table StringProps(...); 
create table CurrencyProps(...); 

Nhưng tôi không nghĩ rằng đây là một ý tưởng tốt ...

0

Một cách tiếp cận thông thường là có bảng khóa-giá trị chứa nhiều cột, một cho mỗi loại dữ liệu, ví dụ: StringValue, DecimalValue, v.v.

Chỉ biết bạn đang giao dịch với khả năng truy vấn và hiệu suất cho lược đồ cơ sở dữ liệu mà bạn không cần thay đổi. Bạn cũng có thể xem xét ánh xạ ORM hoặc một cơ sở dữ liệu đối tượng.

2

Cách này thay thế ... mỗi loại phụ sẽ có bảng DB của riêng nó. Và cơ sở/siêu bảng chỉ có một cột varchar giữ tên của bảng DB loại phụ. Sau đó, bạn có thể có một cái gì đó như thế này ...

Entity 
------ 
ID 
Name 
Type 
SubTypeName (value of this column will be 'Dog') 


Dog 
--- 
VetName 
VetNumber 
etc 

Nếu bạn không muốn tên bảng con của bạn là giá trị varchar trong bảng cơ sở, bạn cũng có thể chỉ có bảng con có khóa chính sẽ nằm trong bảng cơ sở.

0

Bạn có thể có bảng khóa/giá trị cho mỗi loại. Bảng có sẵn sẽ cần phải mã hóa tính khả dụng của cặp khóa/loại cụ thể để trỏ đến bảng khóa/giá trị được nhập chính xác.

Điều này có vẻ như một kiến ​​trúc rất kém hiệu quả trong một cơ sở dữ liệu quan hệ dựa trên hàng.

Có lẽ bạn nên xem xét cơ sở dữ liệu quan hệ cột theo định hướng?

0

Cảm ơn câu trả lời. Tôi sẽ giải thích thêm một chút về những gì tôi cần. Có nhu cầu lập trình một blog + trang web diễn đàn, và tôi đã xem WordPress DB structure.

Có nhu cầu mạnh mẽ về khả năng đặt nhận xét cho bất kỳ loại 'đối tượng' nào, như mục nhập blog hoặc tệp đính kèm tệp video. Cấu trúc DB ở trên rất dễ mở rộng và đáp ứng tất cả các nhu cầu của chúng tôi là lý do lựa chọn của nó.

Nhưng đó không phải là muộn để thay đổi nó, gây ra điều này là trong giai đoạn đầu kỹ thuật. Ngoài ra mô hình của chúng tôi có mùi bây giờ giống như một DB dựa trên phân cấp hoàn toàn cây. Bây giờ tôi sẽ chấp nhận Bill Karwin's and fallen888 answers, nhưng có lẽ tôi đang đi theo một hướng hoàn toàn sai lầm?

0

về việc người dùng có thể thêm trường mới vào bảng:

Tôi ngưỡng mộ tất cả những người này đưa ra nhận xét.

Tôi đã từng quan tâm đến loại điều này một vài năm trước, nhưng đã viết ít mã gần đây (ngoài một chút PHP và MYSQL).

Tôi nghĩ sẽ ổn nếu bạn muốn tiếp tục - bạn có thể kết thúc với một điều gì đó mới mẻ.

Xin lỗi vì đã đổ nước lạnh vào chương trình này - tôi rất ngưỡng mộ những nỗ lực của bạn. Niềm tin cá nhân của tôi là nếu bạn đi đủ xa theo hướng này, bạn sẽ kết thúc với một hệ thống diễn giải nhiều ngôn ngữ tự nhiên hơn so với SQL. (Khoảng năm 1970, SQL thực sự được viết cho phần tiếp theo, và nó thực sự là "ngôn ngữ truy vấn tiếng Anh có cấu trúc", nhưng sau khi chúng chuẩn hóa nó vào những năm 1970 - tôi nghĩ ai đó nói rằng Oracle là triển khai thương mại đầu tiên, 19079, "tiếng Anh" bị bỏ rơi, bởi vì tôi đoán họ đã quyết định rằng đó chỉ là một phần nhỏ của tiếng Anh

Tôi đã hết hơi trong khu vực này, bởi vì tôi không có việc làm. nơi tôi có thể thử nghiệm với những ý tưởng, đó là một chút khó khăn để tập trung vào lĩnh vực này.

Lời chúc tốt nhất cho tất cả.

0

xin lỗi, tôi đã viết 19.079 trên, tôi có nghĩa là năm 1979. Oracle có lệnh hợp đồng đầu tiên của họ nhập cơ sở dữ liệu cho CIA.

Các vấn đề liên quan