Cách tốt nhất để lưu trữ một giá trị có thể là nhiều loại


10

Tôi muốn hỏi lại một câu hỏi theo cách trực tiếp và tổng quát hơn:

Làm thế nào để bạn tạo một bảng để lưu trữ các giá trị có thể có nhiều loại khác nhau?

Trong trường hợp của tôi, các giá trị cung cấp chẩn đoán về một sự kiện. Ví dụ: Sự kiện đã xảy ra -> Lưu trữ các bài đọc từ nhiều PLC có chứa thông tin thích hợp về sự kiện. Các PLC có thể giám sát mọi loại dữ liệu.

Một số ví dụ tôi có thể nghĩ ra:

  • Tạo một cột cho mọi loại có thể và tạo một cột khác để cho biết cột nào sẽ sử dụng
    • Vd: Cols: IntVal, StrVal, BoolVal, Type. Vals: null, null, Đúng, "BOOL"
  • Lưu trữ các giá trị không có vấn đề gì

Câu trả lời:


9

Có vẻ như bạn đã được thông báo rằng bạn đang đi lạc xuống mô hình EAV . Hãy xem hình ảnh ở đây để biết lý do tại sao nên tránh mô hình EAV bằng mọi giá.

Bill Karwin, tác giả chịu trách nhiệm cho hình ảnh trên, đã viết một cuốn sách "SQL Antipotype: Tránh những cạm bẫy của lập trình cơ sở dữ liệu" và ông dành chương đầu tiên cho mô hình chống EAV. Anh ta cũng là một người gây hấn lớn trong nhóm này và rất lớn trên StackOverflow (đối với các vấn đề về cơ sở dữ liệu).

Lời khuyên của tôi là nên có một bảng cho từng loại kết quả và sau đó sử dụng VIEWs để kết hợp chúng khi cần thiết.

Ví dụ, bạn có thể có

CREATE TABLE char_result
(
  question_id INT,
  user_id INT,
  cresult CHAR,
  result_correct BOOLEAN (or equivalent in your RDBMS)
  ..
  <other stuff>
  ..
);

Thực hiện tương tự cho num_result, ngoại trừ thay thế nresult INT (FLOAT ... bất cứ điều gì) cho cresult - ý tưởng tương tự cho VARCHAR & c.

Sau đó tạo VIEWs trên các bảng kết quả khác nhau của bạn cho result_correct(và các trường khác - number_of_attempts... & c. - cho dù các trường khác của bạn là gì). Trong trường hợp này, bạn đang so sánh lượt thích với lượt thích và không tính toán tương đương với việc thêm dân số vào độ cao theo hình ảnh vui nhộn được tham chiếu ở trên!


Để đối phó với Bill, tôi đã viết thư ủng hộ EAV tại đây: sqlblog.com/bloss/aaron_bertrand/archive/2009/11/19/19
Aaron Bertrand

Tôi không nghĩ có nhiều loại có thể cho cùng một cột logic tạo thành EAV. Tôi nghĩ rằng anh ấy đang tìm kiếm một loại "biến thể / đối tượng". Điều đó dễ thực hiện hơn với một vài cột so với một bảng cho mỗi loại. Nghe có vẻ rất bất tiện. Và sau khi chế độ xem được tạo, nó thực sự giống như tạo các kiểu trong cùng một bảng ở vị trí đầu tiên.
usr

@usr Tôi rất muốn xem giải pháp của bạn.
Bãi biển Jared

2
Chỉ cần một cột cho mỗi loại có vẻ ổn với tôi. Tôi đã làm nó như thế trong quá khứ. Đó là giải pháp ít tệ nhất. Đây là một đối số khác: Điều gì xảy ra nếu có hai cột được gõ thay đổi. Giải pháp của câu trả lời này đòi hỏi một số lượng bảng bậc hai. Người ta có thể chia nó thành một bảng cơ bản cộng với nhiều bảng hơn N * M ... Điều này có vẻ không đúng.
usr

@usr không phải là một vấn đề với giải pháp của bạn mà không có cột nào trong số đó có thể là NOT NULL? Cá nhân, tôi là một người tin tưởng lớn vào việc có một NOT NULLchòm sao bất cứ khi nào có thể .
Vérace

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.