字符与整数主键


30

我正在设计一个包含多个查找表的数据库,其中包含主要实体的可能属性。我正在考虑使用4或5个字符的键来标识这些查找值,而不是自动递增的整数,这样当我将这些属性ID存储在主表中时,我会看到有意义的值,而不仅仅是随机数。

使用字符字段作为主键而不是整数对性能有何影响?

如果这很重要,我正在使用MySQL。

[编辑]
这些查找表具有很少添加的新记录。它们是手动维护的,基于字符的键也是手动创建的。这是一个例子:

      CUISINES
 ID      Description
-----  --------------
CHNSE  Chinese
ITALN  Italian
MXICN  Mexican

Answers:


22

这取决于您的引擎。普遍的看法是,读取很便宜,在这里和那里只有几个字节不会显着影响中小型数据库的性能。

更重要的是,这取决于您将主键用于什么用途。整数序列具有易于使用和实现的优点。它们也取决于序列化方法的具体实现,具有可快速派生的优点,因为大多数数据库只是将序列号存储在固定位置,而不是动态获取Select max(ID)+1 from foo

问题就变成了:5个字符的键如何为您和应用程序提供“有意义的值”?与找到递增的序列号相比,如何创建此值,并且花费多少时间?尽管以一些整数节省了很少的空间,但是绝大多数系统将忽略这种空间节省。

没有任何性能影响,但字符方案要求永远不要有自动引擎,因为您的“键”是可以理解的。对于您的特定域,不要理会人工密钥,而只需使用中文,日语和泰语作为关键字名称。虽然您不能保证在任何可能的应用程序中都具有唯一性,但在您的范围内,使用它们而不是可怕且强制的5个字符的缩写要合理得多。直到拥有数百万个元组,才不会对性能产生重大影响。

另外,如果您只是按原产国而不是特定的地区美食(广东话,四川,西西里,翁布里亚,卡拉布里亚,尤卡坦,瓦哈卡等)进行跟踪,则始终可以使用ISO 3166代码

如果我有10,000个食谱,那么5个字符和20个字符的键之间的区别就不会开始累加吗?

空间很便宜。当您说要进行OLAP操作的10,000,000条配方时,也许是这样。拥有1万个食谱,您将拥有150k的空间。

但同样,这取决于。如果您有数以百万计的记录,并且正在对它们进行联接,那么可以合理化对这种琐碎的事情的查找规范化(到物化视图中)。出于所有实际目的,现代机器上5个字符的键和可变长度的键之间的相对连接效率是如此相似,以致于相同。幸运的是,我们生活在一个拥有大量CPU和大量磁盘的世界中。讨厌的联接太多,查询效率低下,而不是逐个字符进行比较。如此说来,请务必进行测试

如此级别的P&T事物非常依赖数据库,因此泛化非常困难。构建数据库的两个样本模型,用估计的记录数填充它们,然后查看哪一个更快。以我的经验,字符长度与良好的索引,良好的内存配置和其他关键性能调整元素相比并没有太大的区别。


@ BrianBallsun-Stanton如果您有大量依赖于这些查找表的顺序数据,则存储空间并不便宜(就查询速度而言),因为磁盘读取速度是任何RDB中无法完全缓存在RAM中的瓶颈。我在尝试开发一种可以与时间序列数据库业务中最佳竞争的RDB模式时发现了这一点。完全公开,我与Skyspark没有任何关系,除了他们因使用非常高效的数据库向我的雇主收取大量费用外。
滚刀

8

我认为,很少更改表的性能没有问题。也许将来您会遇到设计方面的问题。我建议您不要因为业务变化而将业务数据用作主键。使用任何其他主键来“链接”模型中的表。任何业务更改都不会影响与此表相关的内容。


3

真正的问题是数据库查询性能对您的应用程序(数据大小)是否完全重要。如果您的查询花费了几微秒的时间,那么使用Int键来节省这些微秒的时间就不值得对可读性/可维护性进行惩罚。但是,如果您的查询花费了几分钟,那么节省其中的一些时间可能值得付出Int键之苦。

以下是我认为整数可以节省您查询时间(占整体查询时间的百分比)的原因,但是SkySpark创始人可以比我更好地解释它。完全披露后,我的雇主向SkySpark支付了很多钱来使用他们的数据库,而我正在尝试构建更好/更快的产品。

如果您有很多顺序数据(日志文件,时间序列,分析数据,文本或语音语料库)具有链接到任何查询表的链接(关系),那么尽管使用@,您会发现存储空间对于查询速度至关重要。 Ballsun-Stanton对美元中便宜空间的正确分析。因为大多数查询时间(用于顺序数据)都花费在读取磁盘上,所以空间在时间上并不便宜(占总查询时间的百分比)。因此,除非您的RDB自动有效地压缩/解压缩所有外键(相关记录的键),否则您将希望所有键都是Int,这对于每单位信息的磁盘空间(和读取速度)而言是最有效的含量(熵)。FYI MyISAM在MySql中有限制关于如何处理压缩数据行(只读)。换句话说,鉴于大多数DB整数字段的最小大小限制较低,因此自动递增的整数已在理论上尽可能地进行了压缩。而且这种压缩没有:

  1. 查询时间压缩/解压缩代价
  2. 查询时间磁盘读取损失
  3. 对压缩数据记录或键的只读或其他数据库限制

有一个原因,为什么像Django这样的流行,高效的ORM 默认将PK的整数自动递增,并且为什么其他SO问题也得出相同的结论。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.