需要有关2 DB设计的建议
假设我们有2个表Artefact
和User
。 Artefact引用了创建它的用户。但是在我们的遗留系统中很长一段时间,这个引用被存储为一个字符串名称,所以现在它不可能为所有人工制品恢复创建者(来自User
表的一些相应记录已经消失)。
因此,有两种选择:
Artefact
表创建一个可为空的UserId列,并为已经删除了创建者的人工制品填充null。User
表中,并从Artefact
表中引用所有包含未知创建者的记录。目前我想知道哪个选项更好?
第二种方法的优点
isnull()
和left joins
)Artefact
实体始终拥有父User
,您可以依赖第二种方法的缺点
所以,我想知道关于上述两种数据库设计方法的任何其他优点和缺点,以便在我的案例中做出更好的决定。
答案 0 :(得分:1)
重申第二种方法的优点:
- 更简单的sql谓词(没有无尽的
醇>isnull()
和left joins
)
不幸的是,你仍然有另一种无穷无尽的习语:用户<> '非现有用户'。 (在Artefact和User之间加入时,唯一的节省就是LEFT这个词。)
- 更一致的解决方案 -
醇>Artefact
实体始终拥有父User
,您可以依赖
但SQL允许在非空时检查从Artefact(用户)到User的外键。
简单的关系设计是有一个单独的表:
ArtefactUser(artefact, user)
pk (artefact, user)
fk artefact references Artifact not null
fk (user) references User not null
你可能会对此感到满意。然后,保存连接的简单SQL版本是让用户成为Artefact中的可空列。这是您的选择1.
你必须要注意使用null的习惯用法(因为SQL 3VL并发症)将它们尽可能地移到查询表达式的叶子附近。
重申其缺点:
原则上在列中有特殊值没有错。但在SQL中,没有数据类型支持这样做。
例如:我们不希望“非现有用户”#39;永远被视为用户名。因此,让User user为varchar(n)并且Artefact用户为varchar(n)U {non_existing_user}会很高兴,其中non_existing_user是某个值/ token / enum,与任何字符串不同。并且对FK的相应约束将是(select user from Artefact where user<>non_existing_user) <= (select user from User)
。 SQL中最接近的是使用空值。但是NULL在查询中不作为正常值处理。 (也不像任何意义&#34;未知&#34;或&#34;不适用&#34;。)
例如:在您的邮件和评论中,您一直拼错了“非现有用户”#39; (还有&#34;神器&#34;。)没有类型检查。
所涉及的两列确实接受不同的值集。除此之外,如果NULL不涉及3VL,那么它只是一个不是任何类型的值,但是列也可以保持。这基本上是你的选择2.所以做选项2并不可怕。(用户应该被限制为拥有用户&lt;&gt;&#39;非现有用户&#39;。)
在其他类型和其他目的中,并不总是特别使用的值。
(别忘了考虑选择单独的表格。)