一个问题:
我有2张桌子:
Product
id INT
name VARCHAR(64)
something TEXT
else INT
entirely BOOL
和
Ingredient
id INT
name VARCHAR(64)
description TEXT
现在我还有一个链接表
Products_Ingredients
product_id INT
ingredient_id INT
对于我的多对多关系。
现在,产品和成分都将具有唯一的名称。因此,我可以将名称用作自然键...但是,这是一个好主意吗?
说我有一个产品:
Paint Thinner Supreme
含成分:Butylonitrotetrocycline
在链接表中使用这些名称作为组合键是一个好主意吗?
尽管我了解在代理中使用自然键的想法,但我仍然不禁想到将简单整数用作主键(以及外键)会更快。 MySQL服务器摘要这些不同密钥的方式会有所不同吗?
你有什么意见?
最佳答案
您何时可以衡量意见并不重要。
我在PostgreSQL上使用自然键和代理实现了这一点。我使用了300,000种产品,180种成分,并为10万种随机选择的产品(1053462行)填充了两个“产品成分”表,每种产品包含3至17种成分。
使用自然键选择单个产品的所有成分,返回时间为0.067毫秒。使用代理,0.199ms。
使用在0.145毫秒内返回的自然键返回单个产品的所有非id列。使用代理,0.222毫秒
因此,此数据集上的自然键大约快2到3倍。
自然键不需要任何连接即可返回此数据。代理键需要两个联接。
实际的性能差异取决于表的宽度,行数,页面大小和名称长度以及类似的内容。代理键的性能有时会优于自然键,但很少有人尝试对其进行衡量。
在为雇主的运营数据库设计数据库时,我构建了一个测试床,其中包含围绕自然键设计的表和基于ID号设计的表。这两种模式都有超过1300万行计算机生成的样本数据。在某些情况下,对ID号模式的查询的性能要比自然键模式高50%。 (因此,使用ID号花费20秒的复杂查询用自然键花费30秒。)但是80%的测试查询相对于自然键架构具有更快的SELECT性能。有时它的速度惊人得惊人-相差30比1。
我们希望在 future 的几年中,自然键的性能将超过数据库中的替代值。 (除非我们将某些表移至SSD,否则在这种情况下,自然键可能永远会胜过代理。)