我正在为PostgreSQL 9.0 DB创建一个数据库模式,它将代表许多真实世界的实体,每个实体都有一个表。大多数这些实体可以有0个或更多与之关联的自由文本注释。但是,“note”也有一些属性,所以它需要是自己的表 - 我不能只使用字符串数组。所以,逻辑上:
EntityA -> 0..* Note
EntityB -> 0..* Note
EntityC -> 0..* Note
在数据库中对此进行建模的最佳方法是什么?
到目前为止,我已经提出了3种选择:
Note表中每个实体类型的ID的列,带有外键。这非常难看,因为有很多实体。
每个实体表的连接表,将其连接到Note。这仍然是丑陋的,因为它会使表的数量加倍,也可能影响性能(额外加入)。
Note表中的通用“entityId”列,逻辑上引用任何表,但不使用外键强制执行。我还可以对所有实体ID使用相同的PostgreSQL序列,这样自动生成的ID对于所有实体都是唯一的,而不仅仅是该类型的实体。但这并非万无一失,因为有人仍然可以手动插入ID。
到目前为止,我倾向于第三种选择。它保持架构清洁,但没有参照完整性,这是不理想的。任何人都可以提出更好的方法吗?
答案 0 :(得分:2)
作为第四种选择,您可以考虑为每个实体表设置一个注释表(其外键返回到关联的实体表是正确的)。这样做的缺点是你有多个记事表(每个实体表一个额外的表,确切地说)。
这会成为一个问题吗?它实际上取决于访问此数据库的内容。如果它是一个应用程序,则可以对应用程序本身进行编码,以确定在任何特定时间使用实体表的正确注释表。
我不认为这个选项比单个注释表中的外键和“哪个实体表”类型字段更糟糕。至少会强制执行约束。
答案 1 :(得分:1)
我会选择2,因为它是一个更标准化的结构, 我不会担心加入。
如果你担心它看起来很“难看”,只需创建一个视图。
答案 2 :(得分:1)
提供:
EntityName
)您可以尝试类似
的内容
修改强>
在下一个场景中,Entity
表只有EntityID
和EntityType
,而每个E_Type_X
表都包含所有列。 Entity
表的唯一目的是生成唯一键,然后将其传播到每个E_Type_X
表。由于密钥传播,每个E_Type_X
表可以直接连接到Notes
表。
这是使用相同序列生成密钥的所有E_Type_X
表的逻辑等价物 - 非常接近您的解决方案No 3,但可以实现所有外键约束。
答案 3 :(得分:0)
最后我决定不为此创建任何新表,而是创建了一些规则。但是,我接受了 Damir Sudrevic 的回答,因为它最接近我的想法(我喜欢他为我绘制图表的事实!)
基本上我想解决两个问题:
第一个问题是通过为每个实体创建规则来解决的(如果我获得足够的实体,我可以编写脚本):
CREATE OR REPLACE RULE rl_somentity_delete_note
AS ON DELETE TO someentity
DO ALSO DELETE FROM note WHERE entity_id = OLD.id
第二个问题没有解决。我决定让用户创建“孤立”笔记的风险比用一个额外的表和每个实体表额外的FK复杂化模式,这需要额外的INSERT
语句来添加每个实体行。