我认为“ 需要”是一个很强的词,从严格意义上讲,表可能不需要代理键。
但是,如果这是我的数据库,无论如何我可能都会添加代理键。我可能不一定希望我的数据库设计依赖于一堆第三方(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代码。@James Snell在下面的评论是一个完美的例子,我可能不想担心会影响表的PK。
同样,设计的一致性也很重要。如果您有一个数据库,其中包含数十个均设计一致的代理键的表,然后还有一些将第三方代码用作PK的查找表,则会导致不一致。这不是完全坏,但是需要在文档中格外注意,因此可能不需要保证。他们是查找表,出于善意,仅使用代理键来保持一致性就可以了。
根据进一步的研究更新:
好的,好奇心使我困扰,我决定从问题中提供的链接开始,对IATA机场代码进行一些有趣的研究。
事实证明,国际航空运输协会代码不像问题所表明的那样普遍和权威。根据此页面:
大多数国家/地区在其官方航空出版物中使用四字符国际民航组织代码,而不是国际航空运输协会代码。
此外,IATA代码和ICAO代码与FAA标识符代码不同,后者是识别机场的另一种方法。
我提出这些建议的目的不是要开始辩论哪种代码更好或更通用,更权威或更全面,而要确切表明为什么我不愿意围绕任意第三者标识符设计数据库结构,除非有特定的业务原因要这样做。
在这种情况下,我认为通过放弃IATA代码(或任何第三者,可能会更改的代码)作为主键候选并使用代理键,可以使我的数据库结构更好,更稳定,更灵活。这样,我可以避免由于主键选择而可能出现的任何潜在陷阱。