我在考虑这个问题。在数据库设计中大多数时候使用代理键,但如何防止数据重复和数据不一致?我的意思是可以有一个由customer_id,姓名,姓氏组成的客户表。什么会阻止我使用不同的customer_id两次插入同一个客户?当然,我可以为姓名和姓氏添加一个唯一的索引,但是如果这样做,那么代理主键的目的是什么?
答案 0 :(得分:2)
如果有自然键,则不能使用代理键替换。您只能添加代理,而不会删除自然。这有利有弊,正如我所描述的here。
不幸的是,在你描述的情况下没有好的自然键,因为两个不同的人可以很容易地拥有相同的名字和姓氏组合。因此,您必须提出一些额外的属性,这些属性代表判断两个人是否“相同”的更好标准,然后创建相应的自然键。发现此类标准是需求收集的一部分,因此我不可能在不了解您的域名的情况下做到这一点。
如果您无法识别这样的自然键,那么您可以单独留下customer_id
。这意味着你决定让两个人在每个方面都相同(除了customer_id
之外),并且仍然被认为是“不同的”。可以说,这样的customer_id
可能不再被称为“代理”,因为它的值现在在您的数据模型中具有意义,可能在UI等中可见。
答案 1 :(得分:1)
你问的是商业问题,而不是技术问题。
“我怎么知道两个同名的人是否是同一个人?”
通常,客户不仅仅通过名称来识别,还有以下其中一个:
......等等。
这个名称根本不是唯一识别特征,它只是客户的一个属性,可能不是唯一的,因此您需要其他东西来帮助识别它们。在数据库中,这是customer表的主键,但出于商业目的,它可以是任意数量的属性。
答案 2 :(得分:1)
你所说的是完全合乎逻辑的。代理键不任何类型的替代自然键(AKA 业务键或域键,即用于标识数据库中的信息并将其与数据库应该建模的现实世界相关联的属性集。如果您关心数据完整性,那么自然键是必不可少的,而定义的代理是可选的和补充的。只有在您发现它们有用的时候和地点添加代理键。
答案 3 :(得分:0)
id 的唯一目的(或称为“代理键”)是唯一标识记录。
首先,假设您将使用名称作为键。如果出现以下情况,您会怎么做:
然后你遇到了大麻烦,因为尽管你可以改变它,
否则,您不仅可以在数据库,备份,日志等的一致性方面,而且还可以在所有引用它的外部资源中造成大麻烦。
其次,你怎么知道你不会得到两个同名的客户?
答案 4 :(得分:0)
你无法阻止人们在数据库中错误地描述世界。你只能阻止他们在数据库中错误地描述世界,如果他们描述它的方式就不会发生。
如果没有以前的"自然"识别存储在数据库中的数据库外的业务中使用的属性然后我们必须选择一个"代理"系统启动后区分标识符。 (有些人不会使用"自然"在系统启动后选择这样的标识符,即使它在数据库外的业务中使用。有些人不会使用&#34 ;代理"用于数据库外业务系统中使用的区分标识符。)