2011-10-26 48 views
20

Tôi có nên triển khai chuẩn hóa cơ sở dữ liệu đọc (sử dụng bảng tham gia) hay tôi nên sử dụng loại ENUM cho dữ liệu tĩnh hoặc động?Chuẩn hóa cơ sở dữ liệu MySQL

Ví dụ:

Tôi có một bảng USER với một user_status. Tôi có nên tạo một bảng status bảng hoặc tôi tạo danh sách ENUM với các trạng thái không?

Cảm ơn G

Trả lời

25

IMHO, phần mở rộng enum làm cho nó dễ dàng hơn nhiều để nhúng ngữ nghĩa vào một bảng và cũng cải thiện hiệu quả bằng cách:

  1. giảm số lượng tham gia cần thiết cho một truy vấn
  2. giảm số lượng các bảng mở trong DBMS

những nhược điểm duy nhất tôi biết là

  1. E NUM loại không được thực hiện bởi DBMS khác
  2. nếu bạn chọn để thêm giá trị bổ sung cho bộ ENUM vào một ngày sau đó, bạn đang áp dụng một bản cập nhật DDL - có thể mất một thời gian dài với một bảng rất lớn

HTH

C.

+1

Kiểm tra sự phù hợp: http://www.mysqlperformanceblog.com/2008/01/24/enum-fields-vs-varchar-vs-int-joined-table-what-is-faster/ –

+1

Có các vấn đề khác với 'ENUM '. Đối với một điều, tất cả các cột 'ENUM' có thể có một giá trị" không xác định "đặc biệt của chuỗi rỗng (ngoài' NULL' nếu được phép); hơn nữa, giá trị này sẽ được sử dụng cho bất kỳ gán giá trị không hợp lệ trừ khi sử dụng chế độ SQL nghiêm ngặt. Điều này có thể dẫn đến sự thiếu nhất quán về cơ sở dữ liệu ngoài ý muốn; Ngoài ra, nếu thực tế có giá trị chuỗi rỗng trống trong danh sách 'ENUM', điều này có thể dẫn đến sự nhầm lẫn rất lớn (vì người ta phải kiểm tra giá trị số để xác định loại" chuỗi rỗng nào được lưu trữ "). – eggyal

+1

Hơn nữa, việc chuyển đổi ngầm thành giá trị số trong ngữ cảnh số có thể gây ra sự nhầm lẫn đáng kể - đặc biệt nếu một cố gắng sử dụng các chuỗi biểu diễn các số dưới dạng giá trị 'ENUM'. Tài liệu hướng dẫn đưa ra một ví dụ tốt về danh sách 'ENUM'' ('0', '1', '2') ':" * Nếu bạn lưu trữ '2', nó được hiểu là giá trị chỉ mục và trở thành' '1 ''(giá trị với chỉ số 2). Nếu bạn lưu trữ' '2'', nó khớp với một giá trị đếm, vì vậy nó được lưu trữ dưới dạng' '2''. Nếu bạn lưu trữ' '3'', nó không khớp với bất kỳ giá trị nào Giá trị điều tra, do đó, nó được coi là một chỉ số và trở thành ''2'' (giá trị với chỉ số 3). *" – eggyal

0

Tùy thuộc vào kiến ​​trúc và nhiều yếu tố khác.

Ví dụ: bạn không cho phép đọc/ghi dữ liệu ngoại trừ sử dụng các thủ tục được lưu trữ. Trong trường hợp này, bạn có thể cảm thấy tự do sử dụng kiểu dữ liệu "tinyint". Nếu bạn cho phép đọc/ghi với các truy vấn trực tiếp, tốt hơn nên sử dụng ràng buộc ENUM để tránh trạng thái không đúng (nếu UI hoặc back-end có thể đặt trạng thái "sai" này).

Mặt khác (và có thể) có thể có thay đổi về luồng dữ liệu và có thể bạn sẽ cần thêm trạng thái mới. Trong trường hợp này, bạn sẽ cần: 1) không làm gì nếu bạn có kiểu dữ liệu tĩnh; 2) thay đổi nếu bạn có ENUM.

Vì vậy ... câu trả lời của tôi là: tùy thuộc vào đơn đăng ký và yêu cầu của bạn.

+2

Bạn có thể thi hành trạng thái chính xác bằng cách hạn chế chính nước ngoài cũng như (sử dụng bảng InnoDB.) – Inca

+0

... và tạo một một bảng. Tôi nghĩ rằng "quá bình thường" (để có thêm một bảng cho mỗi tình trạng) không phải là một cách tiếp cận tốt nói chung. – ravnur

+0

Bạn có thể giải thích tại sao không? Không có vấn đề gì với việc có nhiều bảng. (Và chúng cho phép thêm tính linh hoạt như thêm mô tả có thể chỉnh sửa vào trạng thái hoặc vô hiệu hóa mô tả cho hồ sơ mới trong khi vẫn giữ bản ghi cũ.) – Inca

1

Một thứ khác cần được xem xét ...

Một enum chỉ có thể được cập nhật thông qua một sửa đổi của cấu trúc cơ sở dữ liệu ở nơi khác một bảng liên kết cho phép tạo ra năng động của kỷ lục.

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