关系数据库devise问题 – 代理键或自然键?
哪一个是最佳实践, 为什么 ?
a)types表,代理/人工密钥
外键是从user.type
到type.id
:
b)types表,自然键
外键是从user.type
到type.typeName
:
我相信在实践中,使用自然钥匙很less是最好的select。 我可能会去你的第一个例子中的代理键方法。
以下是自然键方法的主要缺点:
-
您可能有一个不正确的types名称,或者您可能只是想要重命名types。 编辑它,你将不得不更新所有将使用它作为外键的表。
-
int
字段上的索引比varchar
字段上的索引要紧凑得多。 -
在某些情况下,可能很难拥有一个独特的自然键,这是必要的,因为它将被用作主键。 这可能不适用于你的情况。
第一个是更多的未来certificate,因为它允许你改变表示types的string,而不需要更新整个用户表。 换句话说,您使用代理键 ,为了灵活性引入了一个额外的不可变标识符。
使用代理键(而不是像名称这样的自然键)的一个很好的理由是,当自然键在唯一性方面不是一个好的select时。 在我的一生中,我认识不下4“克里斯·史密斯”。 人名不是唯一的。
我更喜欢使用代理键。 人们常常会认定和使用一段时间会好的自然钥匙,直到他们决定改变价值。 然后问题开始了。
你可能总是使用一个ID号码(这样,如果你改变types名称,你不需要更新用户表),它也可以让你保持你的datasize下降,因为充满INT的表比INT小得多充满45个字符的变化。
如果typeName是一个自然键,那么它可能是更好的select,因为它不需要连接来获取值。
当名称可能改变时,您应该只使用代理键(id)。
替代我的钥匙,请。
另一个可能会更容易,当你需要敲出一些代码,但最终会更困难。 当天,我的技术老板决定使用电子邮件地址作为主键是个好主意。 毋庸置疑,当人们想要改变他们的地址时,它真的很糟糕。
每当他们工作时使用自然键。 名称通常不起作用。 他们太可变了。
如果你正在发明自己的数据,那么你也可以发明一个合成密钥。 如果您正在构build其他人或其软件提供的数据的数据库,请分析源数据以了解他们如何识别需要识别的事物。
如果他们能够很好地pipe理数据,那么他们将拥有为重要的东西工作的自然键。 对于不重要的东西,适合自己。
以及我认为,当你没有任何唯一标识的键值相关且有意义的主密钥时,超大密钥是有帮助的。此外,超大密钥更容易实现,维护费用更less。
但另一方面,通过连接表有时候会使额外的成本增加。 想想“用户”…我有
UserId varchar(20), ID int, Name varchar(200)
作为表结构。
现在考虑我想在许多表上作为谁插入logging的轨道…如果我使用Id
作为主键,然后[1,2,3,4,5..]
等将在外国表和每当我需要知道谁插入数据,我已经join用户表,因为1,2,3,4,5,6
是没有意义的。 但如果我使用UserId
作为唯一标识的主键,那么在其他外部表[john, annie, nadia, linda123]
等将被保存,这有时易于区分和有意义。 所以我不需要每次当我查询时join用户表。
但介意,它需要一些额外的物理空间,因为varchar保存在外部表中,这需要额外的字节..并ofcourse索引有一个重大的性能问题,其中int执行更好,而不是varchar
代理键是对自然主键的替代。 它只是可用于表的主键的每一行的唯一标识符或编号。 代理主键的唯一要求是它对表中的每一行都是唯一的。
这很有用,因为自然主键(即Customer表中的Customer Number)可以更改,这会使更新变得更加困难。