我有一个类似于以下的数据模式:
用户:
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_type
和record_id
一起是另一个表中记录的外键吗?这是反模式吗? (注意:new_value
,我们要记录的所有内容都是相同的数据类型,字符串)。
答案 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这样的表,它可能不是我系统功能的核心,而我只是在进行一些临时查询以查看发生了什么,那么我可能不想放入额外的努力并增加复杂性,从而提高阅读效率。不过,我不确定我会不会跳过它。这是一种反模式,但根据用途可能没问题。
为了强调这一点,我只会在系统从未查询过表格时这样做;如果只查看数据的人是管理员正在运行针对它的即席查询,那么它可能没问题。
干杯 -