【问题标题】:natural key vs surrogate key an innodb foreign key自然键与代理键一个innodb外键
【发布时间】:2011-12-19 18:30:40
【问题描述】:

一个问题:

我有 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 服务器消化这些不同密钥的方式会有所不同吗?

你的意见是什么?

【问题讨论】:

    标签: mysql database database-design foreign-keys relational-database


    【解决方案1】:

    何时可以衡量,意见并不重要。

    我使用自然键和代理在 PostgreSQL 上实现了这一点。我总共使用了 300,000 种产品、180 种成分,并为 100,000 种随机选择的产品(1053462 行)填充了两个“产品成分”表,每种产品包含 3 到 17 种成分。

    使用自然键选择单个产品的所有成分,返回时间为 0.067 毫秒。使用代理,0.199ms。

    使用在 0.145 毫秒内返回的自然键返回单个产品的所有非 ID 列。使用代理,0.222 ms

    所以自然键在这个数据集上的速度大约快 2 到 3 倍。

    自然键不需要任何连接即可返回此数据。代理键需要两个连接。

    实际的性能差异取决于表的宽度、行数、页面大小和名称的长度等等。会有一个点,代理键开始优于自然键,但很少有人尝试衡量这一点。

    当我为雇主的运营数据库设计数据库时,我构建了一个测试平台,其中包含围绕自然键设计的表和围绕 ID 号设计的表。这两种模式都有超过 1300 万行计算机生成的样本数据。在少数情况下,对 id 编号模式的查询比自然键模式高出 50%。 (因此,一个复杂的查询需要 20 秒的 id​​ 编号,但使用自然键需要 30 秒。)但是 80% 的测试查询对自然键模式具有更快的 SELECT 性能。有时它的速度快得惊人——相差 30 比 1。

    我们预计在未来几年内,自然键的性能将优于我们数据库中的代理。 (除非我们将某些表移至 SSD,在这种情况下,自然键可能永远胜过代理。)

    【讨论】:

      【解决方案2】:

      对于这种情况,我更喜欢代理键,因为

      1. 产品或成分的名称可能会发生变化,尤其是当您的内容是用户生成的(例如,拼写错误或某个项目有多个可能的名称)时
      2. 您的自然键会比自然键长得多,因此效率会降低

      【讨论】:

      • +1 让我注意到名称可能会更改/可能会出现拼写错误的事实。好点子。
      • 啊,但这就是级联更新的目的:自动重命名外自然键。
      • 好点 RarchBoy,希望关键与太多数据无关。
      猜你喜欢
      • 2013-12-01
      • 2012-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-22
      • 2014-06-23
      • 1970-01-01
      • 2011-08-10
      相关资源
      最近更新 更多