关系数据库:间接引用“外键”

时间:2014-08-10 19:48:25

标签: database database-design foreign-keys relational-database foreign-key-relationship

我有一个类似于以下的数据模式:

用户

id
name
email
phone number
...

照片

id
width
height
filepath
...

我有一个审核表,可以对系统进行任何更改

日志

id
acting_user
date
record_type (enum: "users", "photos", "...")
record_id
record_field
new_value

是否有此设置的名称,其中一个字段中的enum引用另一个表的名称?实际上,record_typerecord_id一起是另一个表中记录的外键吗?这是反模式吗? (注意:new_value,我们要记录的所有内容都是相同的数据类型,字符串)。

2 个答案:

答案 0 :(得分:1)

  

这是一种反模式吗?

是。任何使您手动强制执行参照完整性的模式 1 都是反模式。

Here这就是为什么使用FOREIGN KEY非常重要,here就像你这样的情况一样。

  

是否有此设置的名称,其中一个字段中的枚举引用另一个表的名称?

我所知道的没有标准术语,但我听到有人称之为“通用”或“多态”FK。


1 与内置于DBMS的FOREIGN KEY相反。

答案 1 :(得分:0)

实际上,我认为'Anti-Pattern'对于这个设置来说是一个非常好的名字,但它可能是一个现实的方法 - 特别是在这个例子中。

我将添加一个类似的示例,其中包含一个新表,用于记录用户照片的LIKES等,并说明它为什么不好。然后我会解释为什么它对你的LOGS例子来说可能不是太糟糕。

LIKES表是:

Id
LikedByUserId
RecordType ("users", "photos", "...")
RecordId

这与LOGS表几乎相同。这样做的问题是你不能使RecordId成为USERS表以及PHOTOS表以及任何其他表的外键。如果喜欢用户1234,除非有ID为1234的照片等,否则无法插入。出于这个原因,我所知道的所有RDBMS都不会让外键被多个主键定义 - 毕竟,主要意味着“只有一个”。

所以你必须创建没有关系完整性的LIKES表。这有时可能不是一个糟糕的问题,但在这种情况下,我认为我想要一个像LIKES这样的重要表格来获得有效的条目。

要正确地做LIKES,我会将表创建为:

Id
LikedByUserId (allow null)
PhotoId (allow null)
OtherThingId (allow null)

...并创建相应的外键。这实际上会使读取数据的查询更容易阅读和维护,也可能更有效。

然而,对于像LOGS这样的表,它可能不是我系统功能的核心,而我只是在进行一些临时查询以查看发生了什么,那么我可能不想放入额外的努力并增加复杂性,从而提高阅读效率。不过,我不确定我会不会跳过它。这是一种反模式,但根据用途可能没问题。

为了强调这一点,我只会在系统从未查询过表格时这样做;如果只查看数据的人是管理员正在运行针对它的即席查询,那么它可能没问题。

干杯 -