如果列表很小(少於10個項目),那麼您可以選擇將它建模爲第一個,但是將列約束設置爲將輸入限制爲列表中的值。這會強制條目屬於您的列表,但您的列表不應該經常更改。
例如檢查('Val1','Val2',...'Valn'中的order_type)
如果列表將不斷變化,如果它在多個表中使用,則需要支持多種語言或任何其他設計標準這需要變化性,然後創建你的類型表(這個選擇你總是安全的,這就是爲什麼它是最常用的)。
您可以收集所有這些表變成了「代碼」表一般化的概念
CREATE TABLE Codes (
Code_Class CHARACTER VARYING(30) NOT NULL,
Code_Name CHARACTER VARYING(30) NOT NULL,
Code_Value_1 CHARACTER VARYING(30),
Code_Value_2 CHARACTER VARYING(30),
Code_Value_3 CHARACTER VARYING(30),
CONSTRAINT PK_Codes PRIMARY KEY (Code_Class, Code_Name)
);
insert into codes (code_class, code_name, code_value_1)
values('STATE','New York','NY'),
values('STATE, 'California','CA'),
....);
您可以再放置並根據變化的TABLE.COLUMN應該被限制在狀態列表UPDATE/INSERT觸發器。比方說,僱員表有一列EMP_STATE來存放狀態短表。
觸發會簡單地調用像
SELECT code_name
, code_value_1
INTO v_state_name, v_state_short_name
FROM codes
WHERE code_class = 'STATE'
AND code_value_1 = new.EMP_STATE;
if(not found) then
raise(some error to fail the trigger and the insert);
end if;
這是一個select語句可以擴展到其他類型:
insert into codes (code_class, code_name)
values('ORDER_TYPE','Production'),
values('ORDER_TYPE', 'Sales'),
....);
select code_name
, code_value_1
into v_state_name, v_state_short_name
from codes
where code_class = 'ORDER_TYPE'
and code_name = 'Sales';
這最後一種方法,雖然一般適用可以使用過度。它的缺點是不能使用不同的數據類型(code_name,code_value_ *)。
一般的經驗法則是:創建一個'TYPE'(例如ORDER_TYPE)表(用來保存你想要限制每種類型的屬性的值),使用一個ID作爲主鍵,使用一個序列來生成所有這樣的ID(用於所有'TYPE'表)。許多TYPE表格可能會混淆你的模型,但是你的開發者的意思是清楚的(最終目標)。
你的第一段是離開牆。使用「id」和「ENUM」隱含的數據完整性約束可以在沒有這些條件的情況下很好地實現。以這種方式取代每一個重複的專欄甚至不可能更不用說「完美」或者甚至是合理的。 – sqlvogel 2014-10-17 15:09:35