我正在设计一个包含多个查找表的数据库,其中包含主要实体的可能属性。我正在考虑使用 4 或 5 个字符的键来识别这些查找值,而不是自动递增的整数,这样当我将这些属性 ID 存储在主表上时,我会看到有意义的值,而不仅仅是随机数。
使用字符字段作为主键而不是整数对性能有何影响?
如果这很重要,我正在使用 MySQL。
[编辑]
这些查找表很少添加新记录。它们是手动维护的,基于字符的键也是手动创建的。这是一个例子:
CUISINES
ID Description
----- --------------
CHNSE Chinese
ITALN Italian
MXICN Mexican
这取决于你的引擎。普遍的看法是读取很便宜,这里和那里的几个字节不会显着影响中小型数据库的性能。
更重要的是,它取决于您将主键用于何种用途。整数序列具有易于使用和实现的优点。根据序列化方法的具体实现,它们还具有可快速派生的优点,因为大多数数据库只是将序列号存储在固定位置,而不是
Select max(ID)+1 from foo
即时派生。问题变成了:5 个字符的密钥如何为您和应用程序呈现“有意义的价值”?这个值是如何产生的,与查找递增的序列号相比,它需要更多或更少的时间。虽然在某些整数中节省了微不足道的空间,但绝大多数系统会忽略这种空间节省。
没有性能影响,除了字符方案要求永远不会有自动引擎,因为你的“键”是不可取的。对于您的特定域,不要使用人工键,只需使用中文、日文和泰文作为键名。虽然您不能保证任何可能的应用程序的唯一性,但在您的范围内,使用它们而不是可怕的和强制的 5 字符缩写更合理。在达到数百万个元组之前,不会对性能产生重大影响。
或者,如果您只是按原产国而不是特定区域美食(广东菜、四川菜、西西里菜、翁布里亚菜、卡拉布里亚菜、尤卡特坎菜、瓦哈卡菜等)进行跟踪,则可以始终只使用ISO 3166 代码。
空间很便宜。当您谈论 10,000,000 个您正在对其进行 OLAP 操作的食谱时,也许。使用 10k 食谱,您将看到 150k 的空间。
但同样,这取决于。如果您有数百万条记录,并且正在对它们进行连接,那么将这种微不足道的查找非规范化(进入物化视图)是有意义的。出于所有实际目的,现代机器上 5 个字符密钥和可变长度密钥之间的相对连接效率非常相似,几乎完全相同。令人高兴的是,我们生活在一个拥有大量 CPU 和大量磁盘的世界中。令人讨厌的是太多的连接和查询效率低下,而不是逐个字符的比较。话虽如此,总是 test。
这个级别的 P&T 事物非常依赖于数据库,因此概括起来非常困难。构建数据库的两个示例模型,用估计的记录数填充它们,然后查看哪个更快。以我的经验,与良好的索引、良好的内存配置和其他关键的性能调整元素相比,字符长度并没有太大的区别。
我认为,很少更改的表的性能没有问题。也许您将来会遇到设计问题。建议您不要因为业务变化而将业务数据作为主键。使用任何其他主键来“链接”模型中的表。任何业务更改都不会影响与此表相关的。
真正的问题是数据库查询性能对您的应用程序(数据大小)是否重要。如果您的查询需要几微秒,那么通过使用键节省一些微秒
Int
是不值得的可读性/可维护性损失。但是,如果您的查询需要几分钟,那么保存其中的一些分钟可能值得花Int
键的痛苦。以下是我认为整数可以节省查询时间(占总查询时间的百分比)的原因,但 SkySpark 的创始人可以比我更好地解释它。完全披露,我的雇主向 SkySpark 支付了很多钱来使用他们的数据库,而我正在努力构建更好/更快的东西。
如果您有大量顺序数据(日志文件、时间序列、分析、文本或语音语料库)与您的任何查找表有链接(关系),您会发现存储空间对于查询速度至关重要,尽管@ Ballsun-Stanton 对空间在美元中的廉价程度的正确分析。因为大部分查询时间(对于顺序数据)都花在读取磁盘上,所以空间在时间方面并不便宜(占总查询时间的百分比)。因此,除非您的 RDB 自动有效地压缩/解压缩所有外键(相关记录的键),否则您会希望所有键都是
Int
,这在每单位信息的磁盘空间(和读取速度)方面是最有效的内容(熵)。MySql中的 FYI MyISAM设置限制关于您可以使用压缩数据行做什么(只读)。换句话说,考虑到大多数 DB 整数字段的最小最小大小限制,自动递增的整数已经在理论上尽可能地压缩了。这种压缩没有:像Django 这样流行的、高效的 ORM 默认为 PK 自动递增整数以及为什么其他SO 问题得出相同的结论是有原因的。