许多表的数据库模型与同一个表具有零对多关系

时间:2011-07-06 07:50:56

标签: sql database-design postgresql polymorphic-associations

我正在为PostgreSQL 9.0 DB创建一个数据库模式,它将代表许多真实世界的实体,每个实体都有一个表。大多数这些实体可以有0个或更多与之关联的自由文本注释。但是,“note”也有一些属性,所以它需要是自己的表 - 我不能只使用字符串数组。所以,逻辑上:

EntityA -> 0..* Note
EntityB -> 0..* Note
EntityC -> 0..* Note

在数据库中对此进行建模的最佳方法是什么?

到目前为止,我已经提出了3种选择:

  1. Note表中每个实体类型的ID的列,带有外键。这非常难看,因为有很多实体。

  2. 每个实体表的连接表,将其连接到Note。这仍然是丑陋的,因为它会使表的数量加倍,也可能影响性能(额外加入)。

  3. Note表中的通用“entityId”列,逻辑上引用任何表,但不使用外键强制执行。我还可以对所有实体ID使用相同的PostgreSQL序列,这样自动生成的ID对于所有实体都是唯一的,而不仅仅是该类型的实体。但这并非万无一失,因为有人仍然可以手动插入ID。

  4. 到目前为止,我倾向于第三种选择。它保持架构清洁,但没有参照完整性,这是不理想的。任何人都可以提出更好的方法吗?

4 个答案:

答案 0 :(得分:2)

作为第四种选择,您可以考虑为每个实体表设置一个注释表(其外键返回到关联的实体表是正确的)。这样做的缺点是你有多个记事表(每个实体表一个额外的表,确切地说)。

这会成为一个问题吗?它实际上取决于访问此数据库的内容。如果它是一个应用程序,则可以对应用程序本身进行编码,以确定在任何特定时间使用实体表的正确注释表。

我不认为这个选项比单个注释表中的外键和“哪个实体表”类型字段更糟糕。至少会强制执行约束。

答案 1 :(得分:1)

我会选择2,因为它是一个更标准化的结构, 我不会担心加入。

如果你担心它看起来很“难看”,只需创建一个视图。

答案 2 :(得分:1)

提供:

  • “很多”是可管理的实体数量(由您自行决定)
  • 实体之间有一些常见的列(例如EntityName
  • 一个笔记只属于一个实体,一个实体可以有多个笔记。

您可以尝试类似

的内容

enter image description here

修改

在下一个场景中,Entity表只有EntityIDEntityType,而每个E_Type_X表都包含所有列。 Entity表的唯一目的是生成唯一键,然后将其传播到每个E_Type_X表。由于密钥传播,每个E_Type_X表可以直接连接到Notes表。

这是使用相同序列生成密钥的所有E_Type_X表的逻辑等价物 - 非常接近您的解决方案No 3,但可以实现所有外键约束。

答案 3 :(得分:0)

最后我决定不为此创建任何新表,而是创建了一些规​​则。但是,我接受了 Damir Sudrevic 的回答,因为它最接近我的想法(我喜欢他为我绘制图表的事实!)

基本上我想解决两个问题:

  1. 确保删除实体以及所有注释。
  2. 确保在未引用有效实体的情况下无法创建注释。
  3. 第一个问题是通过为每个实体创建规则来解决的(如果我获得足够的实体,我可以编写脚本):

    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语句来添加每个实体行。