如果我有一张桌子"用户"对于约会网站,关系列可以是同一个表中另一个用户的主键的外键吗?它是一对一的关系(每个人只能有一个关系伙伴)。值是否为null(此人目前不在关系中)?
在数据库设计中执行此操作的正确方法是什么?
答案 0 :(得分:1)
是的,但是您将无法强制执行这两个人通过约束相互链接。您必须确保代码中存在这种情况。
UserA has relationship with UserB
UserB has relationship with UserA
UserA has relationship with UserB
UserB has no relationship
UserA has no relationship
UserB has relationship with UserA
所有这些都是该领域的有效FK,事实上......
UserA has relationship with UserB
UserB has relationship with UserC
UserA has relationship with UserB
UserC has relationship with UserB
FK也允许。您需要确保在代码中正确设置两者并围绕更新进行适当的事务处理。
您还可以使关系用户唯一,这至少可以防止最后一种情况。
答案 1 :(得分:0)
您可以在表格中放置任何内容。你给出一个声明/含义,并使表中的行成为真。查询的含义是其行按照其表格生成。含义。您只需要使用数据库。
约束遵循给定的陈述和可能出现的情况。您声明它们是为了防止无法出现的状态。
有"包含依赖"约束时某些源列'值集必须是目标列的子集'价值集。如果目标还必须形成其表的一个键,那么就有一个"外键"约束。目标表是否为源表并不重要。在SQL中有一种语法"外键"但是因为它的目标必须是唯一的而不是键,它实际上只定义了一个外国超级键。某些设计方法恰好关注某些约束而牺牲其他约束甚至表格含义。
你想到了一些关系(不一定体现在表格中)
coupled(p,q) // == '[p] & [q] are coupled'
key {p,q}
// plus CHECK-expressible constraints only involving coupled
将此表嵌入另一个表仅意味着这些约束将应用于嵌入表的适当部分。
你也想到了(不一定体现在表格中)
userfact(p,...) // == '...[p] is such that ...'
key {p}
如果您声明
userbig(p,...,q) // == userfact(p,...) and coupled(p,q)
key {p} fk q->p
// plus coupled-like constraints involving select p,q from userbig
然后你不能记录关于没有耦合的p的userfact(p,...)。另外,您必须参与上述选择以查询与用户事实无关的耦合。
如果你让q为null,那么你得到
usernull(p,...,q) // == userfact(p,...) and (q is null and not exists q coupled(p,q) or not q is null and coupled(p,q))
key {p}
// plus coupled-like constraints involving select p,q from usernull where not q is null
不幸的是,现在你必须让上面更复杂的选择参与查询独立于用户事实的耦合。此外,对应于fk q-> p的约束不再是fk约束,而是更复杂,因为q可以为空。此外,任何时候你想要任何部分(甚至全部)usernull,你可能必须测试q的nullness,以确保使用你想要的行。
最糟糕的是,SQL运算符由于其3VL的排序而表现得很复杂,因此涉及空值的所有非常简单的查询的含义都非常复杂。它们并不是表格的简单组合。含义。应该避免空白。
所以你真正想要的只是userfact
和coupled
及其fk p->userfact.p, q->userfact.p
。
在工业上使用现有的SQL DBMS,必须经常选择性能来非声明性地约束并在某些表中使用空值(尽可能接近查询表达式时删除空值)。但首先应该正确设计。