背景

我有这个表

+-------------------------+  +------------------------+
|Airport                  |  |Country                 |
|-------------------------|  |------------------------|
|airport_code string (PK) |  |country_code string (PK)|
|address string           |  |name string             |
|name  string             |  +------------------------+
+-------------------------+

+-------------------------+
|Currency                 |
|-------------------------|
|currency_code string (PK)|
|name string              |
+-------------------------+
.

airport_code Iata(国际航空运输协会) 机场代码,当您乘飞机旅行时,您可以在行李标签中看到它们。

country_code ISO 3166-1 A3标准国家/地区代码,您可以在奥运会中看到它们。

currency_code IS0 417标准3字符货币代码,您可以在国际货币兑换展示板中看到它们。

问题

这些天然pks足够好吗?

正在使用世界尊重的标准,这些标准由整个行业接受足够好的PKS?

此表无论是什么需要代理吗?

有帮助吗?

解决方案

否,他们没有。那些钥匙肯定足够好!

它们是唯一的,不是 很少要更改,而意义,这是一个替代代理键。这几乎是一个好pk的定义。

对pks是不可变的,数字 - 整数的限制不是关系模型(codd)或任何SQL标准(ANSI或其他)。

其他提示

我认为需要是一个非常强大的词,并且在严格的意义上,表格可能不会需要代理键

但是,如果是我的数据库,我可能会添加代理键。我可能不一定希望我的数据库设计依赖于一堆第三方(IATA,ISO),无论他们的标准如何稳定。或者,我可能不想依靠特定标准(有其他货币代码标准?我不知道)。我可能会用替代键模拟我的表:

+-------------------------+  +------------------------+
|Airport                  |  |Country                 |
|-------------------------|  |------------------------|
|airport_id       int (PK)|  |country_id     int (PK) |
|iata_airport_code string |  |iso_country_code string |
|icao_airport_code string |  +------------------------+
|faa_identifier    string |  
|address           string |  
|name              string |  
+-------------------------+

+-------------------------+
|Currency                 |
|-------------------------|
|currency_id int (PK)     |
|iso_currency_code string |
|name string              |
+-------------------------+
. 换句话说,除非这些行业标准代码是固有的重要,否则我的应用程序不会将它们作为我的表的PK。他们只是标签。无论如何,我的大多数其他表都可能有代理键,并且此设置将增加我的数据模型的一致性。 “添加”代理键的成本很少。

更新,基于一些评论:

不知道示例表的上下文,不可能知道IATA机场代码等重要事项使用数据库是如何应用程序。显然,如果IATA代码在整个应用程序中普遍存在并普遍存在中,则可能是正确的决定,在适当的分析后,将代码作为表格的PK。

但是,如果表只是在应用程序的几个角落中使用的查找表,则IATA代码的相对重要性可能无法在数据库基础架构中证明如此突出的位置。当然,您可能必须在这里和那里进行一些疑问,但随着要做的努力,这种努力可能会琐碎,以确保您充分了解使IATA代码的含义来确保您完全理解制造IATA代码的含义主键字段。在某些情况下,不仅我不关心,而且我不想为IATA代码感染。 @JamesSnell的评论下面是我可能不想担心影响我表的PK的完美示例。

还,设计的一致性很重要。如果您有一个具有数十个表的数据库,则所有这些表都具有一致设计的代理键,然后使用3个使用第三方代码作为PK的一些查找表,这引入了不一致。这并不糟糕,但它需要提高文档,这可能不需要。他们是查找表为善良缘故,只需使用代理键进行一致性是完全良好的。

基于进一步研究的更新:

好的,好奇心位我和我决定在IATA机场守则上进行一些研究,以获得乐趣,从问题提供的链接开始。

事实证明,IATA代码不是普遍且权威,因为该问题使它们成为现实。根据此页

大多数国家使用四个字符 官方航空出版物。

此外,IATA代码和ICAO代码与 faa标识符代码不同是识别机场的另一种方法。

我的意思是,带来这些不是开始辩论,关于哪个代码更好或更具普遍或更具权威或更全面的,而是展示为什么在任意第三方标识周围设计数据库结构不是我会的选择Do,除非有特定的经营理由这样做

在这种情况下,通过将IATA代码(或任何第三方,可能改变的代码)作为主要关键候选者来说,我的数据库将更好地结构,更稳定,更灵活,更好地结构,更稳定,更灵活。并使用代理键。通过这样做,我可以放弃可能由于主键选择而造成的任何潜在陷阱。

同时在字段上具有代理键是罚款的,并且无法对索引页面大小本身的东西没有问题。

因为这是一个关系数据库,您可以做大量的连接,并且具有数值类型的代理键可能使得数据库更容易处理,即索引页面大小将更小,从而更快地搜索槽。如果这是一个小项目,它无关紧要,如果申请越大,较大的申请会越大,你就会想要减少瓶颈。

具有一个bigint,int,smallint,tinyint或无论什么整数的数据类型可能会节省您的一些麻烦。

只是我的2美分

更新:

小项目 - 由几个人使用,也许甚至是几十人。小规模,演示项目,个人使用项目,在没有经验的情况下呈现你的技能时要添加到投资组合的东西。

大型项目 - 数千,数万,数百万,每日用户。您为国家/国际公司提供的东西,拥有庞大的用户群。

通常会发生什么是经常选择的少数记录,并且服务器缓存了快速访问的结果,但是每一个现在都需要访问一些较少使用的记录,那么服务器必须倾向进入索引页面。 (在上面的例子与机场名称中,人们经常飞行国内航空公司,说克希克 - >洛杉矶,但人们多久从波士顿飞往 - >津巴布韦)

如果使用varchar,这意味着间距不均匀,否则数据始终相同的长度(炭炭值更有效)。这使得搜索索引较慢,并且随着服务器已经忙于处理数千和数千个每秒查询,现在它必须浪费时间越均匀索引,并在加入上再次执行相同的事情(比常规选择在未优化的表上,拍摄DW,作为尽可能少的连接以加速数据检索的示例。如果您使用UTF也可以使用数据库引擎(我已经看到了一些情况)。

亲自,从我自己的经验,适当组织的索引可以增加〜70%的加入速度,并在整数列上进行连接可以加快大约25%的连接(取决于数据)。由于主表开始生长并且这些表会用于它们,您宁愿拥有一个整数数据类型占用具有几个字节VS的列,该列具有varchar / char字段将占用更多空间。它归结为节省磁盘空间,提高性能和关系数据库的整体结构。

也,正如詹姆斯·斯奈的那样:

主要键也必须是不可变的,IATA机场代码绝对不是。它们可以在IATA的呼吁改变。

所以考虑到这一点,您宁愿必须更新绑定到数字的记录,VS必须更新一个记录加上您加入的表中的所有记录。

如果您拍摄“我所有时间使用代理键”的方法,您可以绕过这种关注的问题。这可能不是一件好事,因为为您的数据提供一些想法是很重要的,但它肯定节省了大量的时间,绿色和努力。如果有人采取接受这一规则,所列的例子肯定有资格,因为它需要一个近“国会法案”来改变。

与这些自然钥匙的数据库的临时查询肯定有用。创建通过包括查找表可以使用相同的操作的视图。现代数据库与这种类型的东西做得更好,这是一个可能无关紧要的地点。

有一些特定于美国的案例,其中标准急剧改变:邮政编码从5 - 9位扩展,状态缩写到一致的2个字母并摆脱了这个时期(记住伊利诺伊州生病了。),而且世界上的大多数都必须处理Y2K。如果您在包含数十亿个记录的世界各地的数据传播数据的实时应用程序,则级联更新不是最好的主意,但我们不应该在面临这些挑战的地方工作吗?使用该数据集,您可以为自己测试它并提出更差异的答案。

许可以下: CC-BY-SA归因
scroll top