2010-06-25 40 views
7

Tôi cố gắng để cân nhắc những ưu và khuyết điểm tương đối của một cấu trúc cơ sở dữ liệu đơn giản như thế này:thiết kế cơ sở dữ liệu: tính linh hoạt so với sự đơn giản

1.

CREATE TABLE x (
    my_id INT PRIMARY KEY, 
    ..., 
    text_attribute_blah TEXT, 
    text_attribute_blah_blah TEXT 
); 

vs:

2.

CREATE TABLE x (
    my_id INT PRIMARY KEY, 
    ... 
) 

CREATE TABLE attributes (
    my_id INT, /* foreign key to x.my_id */ 
    text_attribute_type INT, 
    text_attribute TEXT 
) 

Trường hợp attribute_type có thể là blah hoặc blah_blah.

Tùy chọn 1 cung cấp sự đơn giản - bảng dễ đọc/ghi; Tùy chọn 2 cung cấp tính linh hoạt (nếu chúng tôi muốn thêm thuộc tính khác như blah_blah_blah, chúng tôi không cần thực hiện thay đổi lược đồ và có thể ít thay đổi về mã hơn.)

Có câu trả lời đúng/sai cho câu hỏi này không? Một trong những tùy chọn này có được coi là thực hành tốt hơn các phương pháp khác không? Bạn có thể chỉ cho tôi đọc thêm có thể giúp xác định con đường phía trước không?

+2

Tính linh hoạt được đánh giá quá mức, nếu bạn thực hiện thay đổi lược đồ công việc của bạn nên hiếm. Trong thời gian hết hạn của tôi, người dùng ghét sử dụng các chương trình "linh hoạt" ngay cả khi đó là những gì họ nói họ muốn. – HLGEM

Trả lời

10

Tôi hầu như luôn chọn # 1 - Tôi chỉ muốn có các thuộc tính dưới dạng các cột trong bảng - làm cho truy vấn, lập chỉ mục cho hiệu suất và xử lý chung dễ dàng hơn và minh bạch hơn nhiều.

cáC# 2 tùy chọn được gọi là EAV - Entity Attribute Value - và nó có một số nhược điểm lớn - xem

+1

Tôi sẽ thêm liên kết này http://www.simple-talk.com/opinion/opinion-pieces/bad-carma/ – HLGEM

+2

Dừng sự điên rồ của EAV! –

2

Tùy chọn 1 gần như mọi lúc. Phương án 2 rất kém hiệu quả. Nó cũng khá vụng về để truy vấn dễ dàng khi bạn phải làm điều gì đó hiệu quả hơn. Có nói rằng, tôi đã thấy một số sản phẩm mà làm điều này cho người dùng xác định thuộc tính. Ví dụ về các hệ thống sử dụng kỹ thuật tùy chọn 2 là AgressoKalido.

Nếu bạn đang thực hiện một ứng dụng riêng biệt, cách tốt nhất để thêm thuộc tính chỉ đơn giản là mở rộng giản đồ cơ sở dữ liệu khi bạn cần. Khi thay đổi sẽ được kèm theo các sửa đổi đối với mã, nó có thể được thực hiện như là một phần của quá trình phát hành.

Nếu bạn đang làm một ứng dụng đóng gói mà bạn dự định khách hàng tự cấu hình bạn có ba phương pháp tiếp cận rộng mà bạn có thể thực hiện.

  1. Cấu trúc EAV như tùy chọn 2. Điều này linh hoạt, nhưng không hiệu quả khi truy vấn, đặc biệt khi truy vấn phức tạp với nhiều lần tham gia.

  2. Tạo một nhóm trường 'Người dùng' (User1, User2, v.v.) trên các bảng. Điều này giới hạn bạn với một số hữu hạn, nhưng điều này có thể khá lớn (bạn có thể có User01-User99 nếu bạn muốn). Tuy nhiên, đây là truy vấn đơn giản và hiệu quả nhất. Con khác là các trường có phần mờ đục. Bạn phải có quyền truy cập vào thông tin cấu hình để biết ý nghĩa của 'User3'. Nó cũng hy sinh một số loại an toàn. Tuy nhiên, về sự cân bằng, cơ chế trường người dùng của bạn sẽ có một số siêu dữ liệu của riêng nó và một khuôn khổ chung của một số loại, do đó, một số loại an toàn có thể được cung cấp thông qua điều này.

    Điều này có vẻ không phù hợp nhất nhưng là cách tốt nhất để làm điều này trong hầu hết các trường hợp vì nó có hiệu suất tốt nhất và truy vấn đơn giản nhất. Đây là cách dễ nhất để làm việc với nó.

  3. XML. Điều này là vô cùng linh hoạt nhưng hầu hết các công cụ xung quanh cơ sở dữ liệu làm một công việc nghèo nàn khi làm việc với XML. Nó cũng lưu trữ XML trong các đơn vị phân bổ riêng biệt từ bảng chính, vì vậy nó có thể gây ra các vấn đề quan trọng với hiệu năng truy vấn. Các chiến lược dựa trên XML rất tập trung vào ứng dụng với chi phí của những người tiêu dùng dữ liệu khác.

    Theo kinh nghiệm của tôi, lưu trữ một lượng lớn dữ liệu trong các trường XML trong cơ sở dữ liệu sẽ làm tăng đáng kể TCO của ứng dụng của bạn. Không được đề xuất cho các trường dữ liệu người dùng trong hầu hết các trường hợp.

3

Thật thú vị khi bạn không đề cập đến hiệu suất hoặc tính toàn vẹn của dữ liệu là mối quan tâm. Đối với những gì nó có giá trị, mô hình # 1 là cách tiếp cận tốt nhất cho những cân nhắc.

Tính linh hoạt được đánh giá quá mức so với các mô hình dữ liệu. Hầu hết các cấu trúc bảng đều được biết đến khi bắt đầu phát triển và duy trì ổn định trong suốt thời gian tồn tại của một cơ sở dữ liệu. Nếu bạn có một ứng dụng mà mô hình thực sự là chất lỏng và không thể biết được thì có lẽ bạn không nên sử dụng một RDBMS chút nào. Chọn một trong các sản phẩm NoSQL thay thế.

Vì vậy, đó là một phiếu bầu khác cho # 1.

+1

Vì hiệu suất và tính toàn vẹn dữ liệu là hai yếu tố quan trọng nhất của thiết kế cơ sở dữ liệu (bảo mật là thứ ba) bạn nhận được +1 từ tôi. – HLGEM

1

@marc_s Tôi không tin rằng người ta có thể "hầu như luôn" thực hiện bất kỳ lựa chọn nào trong số các tùy chọn ở trên. Có một trường hợp để hỗ trợ cả hai giải pháp.

Tùy chọn # 1 Đi cho điều này khi thực thể X được xác định rõ nghĩa là bạn biết chính xác những gì bạn cần chụp để xác định X. Trong trường hợp này, một bản ghi X duy nhất thu hút mọi thứ một thể hiện của X là viết tắt của.

Tùy chọn # 2 Đi cho điều này khi một thực thể X không thể được xác định hoàn toàn tức là bạn không biết thuộc tính nào được yêu cầu để xác định "hoàn toàn".

Ví dụ: lấy một ví dụ về hồ sơ nhân viên như được đề cập trong bài viết "Năm lỗi thiết kế cơ sở dữ liệu đơn giản mà bạn nên tránh" [liên kết được cung cấp bởi @marc_s]. Vâng!!! bạn sẽ bị cám dỗ để có lựa chọn 1 nhưng nếu bạn xem xét trường hợp nhân viên làm việc trong các tổ chức lớn, một khi ghi lại thông tin nhân viên - cả định nghĩa và nội dung của nó đều rất năng động và kết hợp tùy chọn # 1 và tùy chọn # 2.

+1

Tôi vẫn tin rằng trong hơn 90% các trường hợp, tôi không thể thấy bất kỳ lý do chính đáng nào cho lựa chọn # 2, xem xét tất cả các từ khóa phủ định (tính toàn vẹn dữ liệu, hiệu suất, truy vấn vụng về) ... nếu bạn không cần thuộc tính cụ thể - làm cho nó không có giá trị. Nếu bạn có các khối thuộc tính cho một số nhân viên nhất định - nhưng chúng trong một bảng được liên kết FK riêng biệt - tôi vẫn chưa tìm được lý do thực sự hấp dẫn cho EAV ... –

+0

Câu trả lời của tôi cho nhận xét của bạn là câu trả lời tiếp theo. – shreeneewas

3

Mọi giải pháp đều có vấn đề cần giải quyết. # 1 sẽ là một cách tiếp cận tốt nếu bạn biết các cột mà bạn cần trả trước. Tuy nhiên, trong một số trường hợp, các cột không được biết trước. Ví dụ: các trường tùy chỉnh mà người dùng thêm vào một chức năng.

Có nói rằng, EAV có nhiều vấn đề. Khi được sử dụng đúng cách, IMO, chúng hữu ích.

  1. Đảm bảo bạn không tạo EAV cho mọi thứ. Nó chỉ dành cho "mục không xác định".
  2. Hãy nhớ rằng EAV không có mối quan hệ ngoại khóa phụ thuộc vào.
  3. Hiệu suất thấp vì các truy vấn không tầm thường và việc bảo trì có thể cao hơn.
  4. Hãy nhớ rằng các EAV phải được xoay vòng để làm cho nó có ý nghĩa (tốt, thường xuyên nhất).
0

Như đã nói ở trên, điều đó tùy thuộc vào yêu cầu của bạn. Bạn nên chọn # 2 chỉ khi bạn cần, ví dụ, thêm các loại thuộc tính mới như là một phần của quy trình làm việc của chương trình của bạn. Làm điều này với việc thêm các cột mới trong các bảng của bạn chắc chắn tệ hơn là có thêm một bảng và thêm một tham gia vào các truy vấn của bạn.

1

@marc_s

Mặc dù tôi đã đề cập đến ví dụ về hồ sơ nhân viên Tôi chắc chắn rằng điều đó không thuyết phục lắm.

Đây là ví dụ từ miền tài chính.

Nếu bạn muốn nắm bắt tất cả các thuộc tính của giao dịch thì nó phụ thuộc vào loại công cụ của nó. Nó dễ dàng hơn nhiều để nắm bắt hầu hết ngoại hối, thị trường tiền ngay cả các công cụ Bond khi chúng rất có cấu trúc. Nhưng khi chúng ta chuyển sang các sản phẩm phái sinh, nó trở nên rất cồng kềnh. Chúng rất kỳ lạ trong tự nhiên và tiếp tục thay đổi về cấu trúc (do đó ý nghĩa của nó vv). Để nắm bắt một thông tin thay đổi động như vậy, chúng tôi nên lựa chọn không cho EAV. Ofcourse trong khi thực hiện sự lựa chọn này ta nên nhận thức được rằng nó mang lại rất nhiều tiêu cực được liệt kê ở trên trong bình luận của bạn.

Tôi không thể nói về các miền khác, nhưng tôi chắc chắn bạn sẽ thấy rằng các hệ thống CNTT trong nhiều lĩnh vực kinh doanh phải đối mặt với tình huống này và do đó có hiểu biết tốt về chiến lược EAV - như trái ngược với sự từ chối hoàn toàn của nó ý tưởng tốt.

Shrini

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