我只是想知道最佳解决方案是什么。

假设我有一个规范化的数据库。整个系统的主键是varchar。我想知道的是我应该将这个varchar与一个int相关联以进行规范化还是留下它?离开作为varchar更简单,但它可能更优化

例如我可以

People
======================
name      varchar(10)   
DoB       DateTime    
Height    int  

Phone_Number
======================
name      varchar(10)   
number    varchar(15)

或者我可以

People
======================
id        int Identity   
name      varchar(10)   
DoB       DateTime  
Height    int  

Phone_Number
======================
id        int   
number    varchar(15)  

当然,添加其他几个一对多关系。

你们都在想什么?哪个更好,为什么?

有帮助吗?

解决方案

你真的可以使用名字作为主键吗?是不是有几个人同名的高风险?

如果你真的很幸运,你的名字属性可以用作主键,那么 - 无论如何 - 使用它。但是,通常情况下,您必须制作一些内容,例如customer_id等。

最后:“NAME”是至少一个DBMS中的保留字,因此请考虑使用其他内容,例如全名。

其他提示

我相信大多数开发了大量现实世界数据库应用程序的人都会告诉你,代理键是唯一现实的解决方案。
我知道学术界不同意,但这是理论纯度和实用性之间的差异。

任何合理大小的查询必须在使用非代理键的表之间进行连接,其中某些表具有复合主键很快变得不可维护。

使用任何种类的非合成数据(即来自用户的任何东西,而不是由应用程序生成的)作为PK是有问题的;您必须担心文化/本地化差异,区分大小写(以及其他问题取决于数据库整理),如果/当用户输入的数据发生变化时,可能会导致数据问题等。

使用非用户生成的数据(顺序GUID(如果您的数据库不支持它们,或者您不关心页面拆分,则为非顺序数据)或身份整数(如果您不需要GUID))更容易,更安全。

关于重复数据:我没有看到使用非合成键如何保护您。您仍然遇到用户输入“Bob Smith”的问题。而不是“Bob K. Smith”而不是“Bob K. Smith”。或“史密斯,鲍勃”或或“鲍勃史密斯”无论您的密钥是合成密钥还是非合成密钥,重复管理都是必要的(并且几乎完全相同),非合成密钥还有许多其他潜在问题,合成密钥可以完全避免。

许多项目不需要担心(例如,严格限制的校对选择会避免其中许多项目),但一般来说我更喜欢合成键。这并不是说你无法用有机键成功,显然你可以,但对于许多项目来说,它们不是更好的选择。

我认为如果您的VARCHAR较大,您会注意到您在整个数据库中复制了相当多的数据。如果您使用数字ID列,则在将外键列添加到其他表时,您不会复制几乎相同数量的数据。

此外,文字数据在比较方面是一种巨大的痛苦,当你做 WHERE id = user_id WHERE名称LIKE输入名称时,你的生活会轻松得多(或类似的东西)。

如果是“名称”,字段真的适合作为主键,然后去做。在这种情况下,通过创建代理键,数据库将 not 更加规范化。您将获得一些重复的外键字符串,但这不是规范化问题,因为FK约束保证了字符串的完整性,就像在代理键上一样。

但是你没有解释什么是“名字”。是。在实践中,很少有字符串适合作为主键。如果它是一个人的名字,它不会作为一个PK,因为不止一个人可以有相同的名字,人们可以改变名称等等。

其他人似乎没有提到的一件事是,int字段上的连接往往比连接varchar字段更好。

我绝对会使用代理密钥而不是使用姓名(人或企业),因为它们永远不会是唯一的。例如,在我们的数据库中,我们有164个名称,其中包含100多个同名实例。这清楚地表明了考虑使用名称作为关键领域的危险。

最初的问题不是正常化问题。如果您有一个规范化的数据库,如您所述,那么您不需要为了标准化原因而更改它。

你的问题确实有两个问题。首先是int或varchars是否适合用作主键和外键。第二个问题是你是否可以使用问题定义中给出的自然键,或者是否应该生成合成键(代理键)来代替自然键。

整数比varchars更简洁,对索引处理这样的东西更有效。但差异并不是很大。你可能不应该单独在这个基础上做出决定。

提供的自然键是否真的作为自然键的问题更为重要。 “名称”中重复的问题。列不是唯一的问题。当一个人改名时会发生什么问题。这个问题可能不会出现在您给出的示例中,但它确实存在于许多其他数据库应用程序中。一个例子是学生所有课程四年的成绩单。一个女人可能会结婚并在四年内更改她的名字,现在你被困住了。

您必须保持名称不变,在这种情况下,它不再与现实世界一致,或者在所有课程中追溯更新它,这使得数据库不同意当时制作的印刷名单。

如果确定了合成密钥,则现在必须确定应用程序是否要向用户社区显示合成密钥的值。这是另一整套蠕虫,超出了本讨论的范围。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top