我正在考虑索引我的数据的最佳方法。使用时间戳作为主键是个好主意吗?我要保存它,我想保存一些列。出于性能考虑,时间戳应该是一个整数,而不是datetime列。此外,我不希望在短时间内(两秒钟之间)受到数据量的限制。因此,我考虑添加一个AUTO_INCREMENT列。现在我有一个唯一的键(时间戳和AI),我可以通过使用命令& LAST_INSERT_ID"轻松获得当前插入的id。是否有可能重置AI计数器每秒/当有一个新的时间戳?或者是否可以检测是否存在具有相同时间戳的数据集并增加AI值(我仍然希望能够使用LAST_INSERT_ID)。
请分享你的想法。
时间戳应该是一个整数,而不是datetime列,因为性能。
我认为您认为datetime
是作为字符串存储的。它以数字形式存储,效率很高,而且比整数形式存储的范围更广,精度更高。
使用整数可能会降低性能,因为数据库可能无法正确地将其索引为时间戳。它将使查询复杂化,因为如果不首先将整数转换为日期时间,您将无法使用完整的日期和时间函数。
使用适当的日期/时间类型,索引它,并让数据库优化它。
此外,我不想在短时间内(两秒之间)受到数据量的限制。因此,我考虑了一个[额外的]auto_increment列。
这似乎破坏了"保存一些专栏"的意义。现在你的主键是两个整数。更糟糕的是,它是一个复合键,它要求所有引用同时存储两个值,这会增加存储需求并使连接复杂化。
确定下一个主键所需的所有额外工作都可以在插入触发器中完成,但现在您为每次插入增加了复杂性和额外的工作。
使用时间戳作为主键是一个好主意吗?
主键应该是A)唯一的,B)不可变的。时间戳不是唯一的,您可能需要更改它。
主键不太可能成为性能或存储瓶颈。除非有很好的理由,否则请坚持使用简单的、自动递增的大整数。一个大整数因为20亿比你想象的要小。
MySQL将其封装在serial
中,即bigint unsigned not null auto_increment unique
。
TIMESTAMP
和DATETIME
作为PRIMARY KEY
是有风险的,因为PK必须是唯一的。
否则,将它们用于PK或索引是可以的。但这里有一些注意事项:
- 使用复合索引(多列)时,将
=
测试的内容放在首位; - 在选择PK时越小越好,
TIMESTAMP
和DATETIME
占用5字节(不包括微秒);INT
是4字节;BIGINT
是8. - 一个PK值与另一个PK值比较所需的时间不显著。这包括角色pk。例如,
country_code CHAR(2) CHARACTER SET ascii
只有2个字节——比将其"正常化"并替换为4个字节的cc_id INT
要好。 - 所以,不,不要用INT代替TIMESTAMP。
- 根据我的经验,2/3的餐桌上都有"天然的";PK,不需要auto_increment PK。 使用auto_inc最糟糕的地方之一是在多对多映射表上。它可能会使大多数操作减慢2倍。
你暗示了PRIMARY KEY(timestamp, ai)
:
- 你需要添加
INDEX(ai)
来保持AUTO_INCREMENT
的快乐。 - 它为临时"近"行提供了引用的局部性。但
ai
本身也是如此。 - 不,没有实用的方法可以每秒重置ai。(MyISAM有这样的引擎,但不要使用该引擎。)相反,一定要声明
ai
足够大,以便在溢出之前"永远"持续下去。 - 但是我想不出一个没有更好的方法的用例。