Sử dụng khóa ngoài để bảng tra cứu là cách tiếp cận tôi sử dụng. Trong thực tế, tôi sử dụng điều này ngay cả khi tôi sử dụng cơ sở dữ liệu hỗ trợ ENUM (ví dụ: MySQL).
Để đơn giản, tôi có thể bỏ qua "id
" cho bảng tra cứu và chỉ sử dụng giá trị thực tế tôi cần trong bảng chính làm khóa chính của bảng tra cứu. Bằng cách đó bạn không cần phải tham gia để có được giá trị.
CREATE TABLE BugStatus (
status VARCHAR(20) PRIMARY KEY
);
INSERT INTO BugStatus (status) VALUES ('NEW'), ('OPEN'), ('FIXED');
CREATE TABLE Bugs (
bug_id SERIAL PRIMARY KEY,
summary VARCHAR(80),
...
status VARCHAR(20) NOT NULL DEFAULT 'NEW',
FOREIGN KEY (status) REFERENCES BugStatus(status)
);
Phải thừa nhận rằng, tàng trữ chuỗi mất nhiều không gian hơn việc thực hiện các ENUM
MySQL, nhưng trừ khi các bảng trong câu hỏi có hàng triệu hàng, nó hầu như không quan trọng.
lợi thế khác của các bảng tra cứu được rằng bạn có thể thêm hoặc loại bỏ một giá trị từ danh sách với một đơn giản INSERT
hoặc DELETE
, trong khi với ENUM
bạn phải sử dụng ALTER TABLE
để xác định lại danh sách.
Cũng thử truy vấn danh sách giá trị được phép hiện tại trong một số ENUM
, ví dụ để điền danh sách lựa chọn trong giao diện người dùng của bạn. Đó là một khó chịu lớn! Với bảng tra cứu, thật dễ dàng: SELECT status from BugStatus
.
Ngoài ra, bạn có thể thêm các cột thuộc tính khác vào bảng tra cứu nếu cần (ví dụ: để đánh dấu lựa chọn chỉ có sẵn cho quản trị viên). Trong một số ENUM
, bạn không thể chú thích các mục nhập; chúng chỉ là những giá trị đơn giản.
Một tùy chọn khác bên cạnh một bảng tra cứu sẽ được sử dụng CHECK
chế (được cung cấp cơ sở dữ liệu hỗ trợ họ - MySQL không):
CREATE TABLE Bugs (
bug_id SERIAL PRIMARY KEY,
summary VARCHAR(80),
...
status VARCHAR(20) NOT NULL
CHECK (status IN ('NEW', 'OPEN', 'FIXED'))
);
Nhưng sử dụng này là một hạn chế CHECK
bị so với cùng bất lợi là ENUM
: khó thay đổi danh sách giá trị mà không cần ALTER TABLE
, khó truy vấn danh sách các giá trị được phép, khó chú thích các giá trị.
PS: toán tử so sánh bình đẳng trong SQL là một =
. Các đôi ==
không có ý nghĩa trong SQL.
Nếu đây là bản sao, vui lòng trở nên tốt đẹp. Tôi đã tìm câu trả lời trên StackOverflow trước khi tôi hỏi. – epochwolf