简体   繁体   English

Mysql 时间戳和 AUTO_INCREMENT 作为主键

[英]Mysql timestamp and AUTO_INCREMENT as primary key

I am thinking about the best way to index my data.我正在考虑为我的数据编制索引的最佳方式。 Is it a good idea to use the timestamp as my primary key?使用时间戳作为我的主键是个好主意吗? I am saving it anyway and I though about saving some columns.无论如何我都在保存它,我想保存一些列。 The timestamp should be an integer not a datetime column, because of performance.由于性能原因,时间戳应该是 integer 而不是日期时间列。 Moreover I don't want to be restricted on the amount of data in a short time (between two seconds).此外,我不想在短时间内(两秒之间)限制数据量。 Therefore, I thought about an additionary AUTO_INCREMENT column.因此,我想到了一个额外的 AUTO_INCREMENT 列。 Now I have a unique key (timestamp and AI) and I can get the current inserted id easily by using the command "LAST_INSERT_ID".现在我有一个唯一的键(时间戳和 AI),我可以使用命令“LAST_INSERT_ID”轻松获取当前插入的 id。 Is it possible to reset the AI counter every second / when there is a new timestamp?是否可以每秒/有新时间戳时重置 AI 计数器? Or is it possible to detect if there is a dataset with the same timestamp and increase the AI value (I still want to be able to use LAST_INSERT_ID).或者是否可以检测是否存在具有相同时间戳的数据集并增加AI值(我仍然希望能够使用LAST_INSERT_ID)。

Please share some thoughts.请分享一些想法。

The timestamp should be an integer not a datetime column, because of performance.由于性能原因,时间戳应该是 integer 而不是日期时间列。

I think you are of the belief that datetime is stored as a string.我认为您相信datetime时间存储为字符串。 It is stored as numbers quite efficiently and with a wider range andmore accuracy than an integer.与 integer 相比, 它以数字形式存储非常有效,范围更广,准确性更高。

Using an integer may decrease performance because the database may not be able to correctly index it for use as a timestamp.使用 integer 可能会降低性能,因为数据库可能无法正确索引它以用作时间戳。 It will complicate queries because you will not be able to use the full suite of date and time functions without first converting the integer to a datetime.这将使查询复杂化,因为如果不先将 integer 转换为日期时间,您将无法使用全套日期和时间函数

Use the appropriate date/time type, index it, and let the database optimize it.使用适当的日期/时间类型,对其进行索引,然后让数据库对其进行优化。

Moreover I don't want to be restricted on the amount of data in a short time (between two seconds).此外,我不想在短时间内(两秒之间)限制数据量。 Therefore, I thought about an [additional] AUTO_INCREEMENT column.因此,我考虑了一个 [附加] AUTO_INCREEMENT 列。

This would seem to defeat the point of "saving some columns".这似乎违背了“保存一些列”的观点。 Now your primary key is two integers.现在你的主键是两个整数。 Worse, it's a compound key which requires all references to store both values increasing storage requirements and complicating joins.更糟糕的是,它是一个复合键,它需要所有引用来存储这两个值,这增加了存储要求和复杂的连接。

All the extra work necessary to determine the next primary key could be done in an insert trigger , but now you'd added complexity and extra work to every insert.确定下一个主键所需的所有额外工作可以在插入触发器中完成,但现在您为每个插入增加了复杂性和额外工作。

Is it a good idea to use the timestamp as my primary key?使用时间戳作为我的主键是个好主意吗?

A primary key should be A) unique and B) immutable.主键应该是 A) 唯一且 B) 不可变的。 A timestamp is not unique, and you might need to change it.时间戳不是唯一的,您可能需要更改它。

Your primary key is unlikely to be a performance or storage bottleneck.您的主键不太可能成为性能或存储瓶颈。 Unless you have a good reason, stick with a simple, auto-incrementing big integer.除非您有充分的理由,否则请坚持使用简单、自动递增的大 integer。 A big integer because 2 billion is smaller than you think.一个大的 integer 因为 20 亿比你想象的要小。

MySQL encapsulates this in serial which is bigint unsigned not null auto_increment unique . MySQL 将其封装在serial中,它是bigint unsigned not null auto_increment unique

TIMESTAMP and DATETIME are risky as a PRIMARY KEY since the PK must be Unique. TIMESTAMPDATETIME作为PRIMARY KEY是有风险的,因为 PK 必须是唯一的。

Otherwise, it is fine to use them for the PK or an index.否则,可以将它们用于 PK 或索引。 But here are some caveats:但这里有一些警告:

  • When using composite indexes (multi-column), put the things tested with = first;使用复合索引(多列)时,把测试的东西用=放在前面; put the datetime last.把日期时间放在最后。
  • Smaller is slightly better when picking a PK.选择PK时,越小越好。 TIMESTAMP and DATETIME take 5 bytes (when not including microseconds); TIMESTAMPDATETIME占用 5 个字节(不包括微秒时); INT is 4 bytes; INT为 4 个字节; BIGINT is 8. BIGINT为 8。
  • The time taken for comparing one PK value to another is insignificant.将一个 PK 值与另一个进行比较所花费的时间是微不足道的。 That includes character PKs.这包括角色 PK。 For example, country_code CHAR(2) CHARACTER SET ascii is only 2 bytes -- better than 'normalizing' it and replacing it with a 4-byte cc_id INT .例如, country_code CHAR(2) CHARACTER SET ascii只有 2 个字节——比“规范化”它并用 4 字节cc_id INT替换它要好。
  • So, no, don't bother using INT instead of TIMESTAMP.所以,不,不要费心使用 INT 而不是 TIMESTAMP。
  • In my experience, 2/3 of tables have a "natural" PK and don't need an auto_increment PK.根据我的经验,2/3 的表具有“自然”PK,不需要 auto_increment PK。
  • One of the worst places to use a auto_inc is on a many-to-many mapping table.使用 auto_inc 最糟糕的地方之一是在多对多映射表上。 It is likely to slow down most operations by a factor of 2.它可能会使大多数操作减慢 2 倍。

You hinted at PRIMARY KEY(timestamp, ai) :您暗示了PRIMARY KEY(timestamp, ai)

  • You need to add INDEX(ai) to keep AUTO_INCREMENT happy.您需要添加INDEX(ai)以保持AUTO_INCREMENT满意。
  • It provides locality of reference for temporarily 'near' rows.它为临时“近”行提供参考位置。 But so does ai , by itself.但是ai本身也是如此。
  • No, there is no practical way to reset the ai each second.不,没有实用的方法可以每秒重置 ai。 (MyISAM has such, but do not use that engine.) Instead be sure to declare ai big enough to last 'forever' before overflowing. (MyISAM 有这样的,但不要使用那个引擎。)相反,一定要声明ai足够大以在溢出之前持续“永远”。
  • But I can't think of a use case where there isn't a better way.但我想不出没有更好方法的用例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM