【问题标题】:Choosing a string primary key vs using a join table with corresponding integer id选择字符串主键与使用具有相应整数 id 的连接表
【发布时间】:2017-05-21 21:09:40
【问题描述】:

我有一个大型传感器数据计数表,说 SENSORS_COUNT 带有一个字符串 SID,它引用另一个具有相同主键 SID 的表 SENSOR_DEFINITIONS。由于有数百万个数据点,字符串主键上的索引变得 1) 臃肿 2) 缓慢。传感器的总数非常少(

我可以考虑 3 种不同的方法来加快查询速度:

  1. 使用连接表将字符串键转换为相应的整数键,并在所有查询中通过连接引用它
  2. 将字符串/整数转换作为哈希加载到程序内存中并在代码中引用它
  3. 在字符串主 ID 上使用索引(虽然会比整数慢)

我正在尝试为各种传感器构建一个系统,这些传感器可能具有不同类型的字符串 ID(但架构相同)。最好的建议是什么?

编辑 1:这是架构。是的(感谢更正),在 SENSORS_COUNT 表中,SID 不是主键

TABLE: SENSOR_DEFINITIONS (2000 records)
SID : VARCHAR(20), PRIMARY KEY
SNAME: VARCHAR(50)

TABLE: SENSORS_COUNT (N million records)
SID: VARCHAR(20)
DATETIME: TIMESTAMP
VALUE: INTEGER

【问题讨论】:

  • 你怎么知道它比较慢?您是否运行过任何性能基准测试?
  • 感谢指正。它不是慢,而是慢。我正在尝试找到一种比目前更快的方法。此外,问题更倾向于数据库管理员使用的最佳实践。或者推荐非 DBA 开发人员可以使用的资源。
  • 性能问题应该包括 EXPLAIN ANALYZE 和一些关于表大小、索引、当前时间性能、期望时间等的信息。慢是一个相对术语,我们需要一个真正的值来比较。 MySQL 也请阅读How-to-Ask
  • 注意:如果SIDSENSORS_COUNT的主键并且SID只有2000个不同的值,则sensor_count中的记录不能超过2000条。请显示表格的真实定义。
  • 这里“字符串”的确切定义会对性能产生很大影响,例如CHAR(4) CHARACTER SET latin1 在一个案例中足够大,可以容纳 2000 个传感器标识符,并且应该与 32 位整数一样有效。 VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci 效率会降低。

标签: mysql database postgresql database-design


【解决方案1】:

对于“大”表,规范化变得更加重要。特别是当表太大而无法缓存时。

因此,我同意选择使用 SMALLINT UNSIGNED(2 字节,0..64K)作为 2000 个传感器名称,而不是 VARCHAR(...)

如果没有看到 (1) SHOW CREATE TABLE 和 (2) 一些关键的 SELECTs,很难给出进一步的建议。

“复合”PRIMARY KEY 可能比AUTO_INCREMENT 更好。可能是(sensor_id, datetime),但首先查看选择会有所帮助。

是否有两个具有相同架构的表(没有充分的理由)。

【讨论】:

  • 使用SMALLINT UNSIGNED 与规范化有什么关系?
  • 规范化是建立一个映射到整数的字符串表,然后使用大表中的整数。我推荐“整数”的特定变体最适合您的目的。
  • 废话。数据库上下文中的规范化是指分解关系以唯一且明确地表示依赖关系。引入代理键有时可以用于规范化过程,但仅仅引入代理键作为另一个域的紧凑表示与规范化没有任何关系。
  • @reaanb - 有这样的技术名称吗?
  • 我不知道它的既定术语。如果我不得不造一个,我可能会称之为域索引。
猜你喜欢
  • 1970-01-01
  • 2021-12-20
  • 2011-08-16
  • 2011-05-05
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 2019-10-27
相关资源
最近更新 更多