Postgresql
ENUM 和 ID 作為外鍵
使用 PostgreSQL 11。
我已經嘗試通過 Stack Overflow 和此處進行探勘,但無法找到最佳實踐的答案。
我正在研究數據庫設計,並得出了一個使用通用“連接表”的模式。此連接表包含五列:
CREATE TABLE many_joins_table ( id PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, object_id int NOT NULL, object_table joins_object_t NOT NULL, parent_id int NOT NULL, parent_table joins_parent_t NOT NULL);
我一直在使用此表來表示數據庫中對象之間的相鄰關係和多對多關係。一個這樣的例子是標籤。
CREATE TABLE tag ( id PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, name text NOT NULL UNIQUE); CREATE TABLE comment ( id PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY); CREATE TYPE joins_object_t AS ENUM ('tag'); CREATE TYPE joins_parent_t AS ENUM ('comment');
將標籤添加到評論表時,我將在此連接表中插入一個新行,其中包含以下欄位:
INSERT INTO many_joins_table VALUES(1, 'tag'::joins_object_t, 1, 'comment'::joins_parent_t);
除了列舉的不靈活性之外,PostgreSQL 9.1 https://stackoverflow.com/questions/1771543/adding-a-new-value-to-an-existing-enum-type/7834949#7834949解決了這個問題。
這種方法有什麼明顯的缺點或優點嗎?我擔心我錯誤地實現了反模式。有沒有我可以應用的最佳實踐來改進這個實現(索引或約束)?
謝謝!
**注意:**我知道有更好的方法來實現標籤,即使用 intarrays。我只是以標籤為例,因為它很容易理解。https://stackoverflow.com/questions/23508551/integer-array-lookup-using-postgres
**編輯:**刪除了 UUID,因為它可能會分散問題的注意力。
首先,不要對此類事情使用列舉。列舉值永遠不能被刪除,所以只有在您確定永遠不需要時才使用它們,這裡似乎不是這種情況。
無論如何,我會說你的設計太複雜了,仍然缺乏參照完整性這一關鍵特徵。
為每對可以關聯的對象使用聯結表。這樣,你
- 明確哪些對象可以關聯
- 可以具有參照完整性
擁有許多表是數據庫所擅長的。如果你聲稱你有 1000 個表並且每個對像都可以相互關聯,那麼表就太多了。但是在這種情況下,您可能應該選擇一個模型,無論如何您都沒有每個對像類型的表。