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

如果重要的话,我正在使用MySQL。

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

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


#1 楼

这取决于您的引擎。普遍的看法是,读取很便宜,这里的几个字节不会对中小型数据库的性能产生重大影响。

更重要的是,它取决于您将数据放入数据库的用途。首要的关键。整数序列具有易于使用和实现的优点。它们还取决于序列化方法的特定实现,具有可快速派生的优点,因为大多数数据库只是将序列号存储在固定位置,而不是即时使用Select max(ID)+1 from foo派生。

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

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

或者,如果您仅按原产国而不是特定的区域美食(广东话,四川,西西里,翁布里亚, Calabrian,Yucatecan,Oaxacan等),您总是可以使用ISO 3166代码。


如果我有10,000个食谱,则5个字符和20个字符之间没有区别键开始累加?


空间便宜。当您说要进行OLAP操作的10,000,000条配方时,也许就可以了。拥有10k的食谱,您正在寻找150k的空间。

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

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

评论


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

–滚刀
13年3月20日在21:15



#2 楼

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

#3 楼

真正的问题是数据库查询性能对您的应用程序(数据大小)是否完全重要。如果您的查询耗时数微秒,那么使用Int键保存这些微秒数就不值得付出可读性/可维护性的代价。但是,如果您的查询需要几分钟,那么保存其中的一些时间可能值得Int键的麻烦。

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

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


查询时压缩/解压缩惩罚
查询时磁盘读取惩罚
只读或其他数据库对压缩数据记录的限制或键

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