Mysql Doc
DATETIME或TIMESTAMP值可以包括精度高达微秒(6位(的小数秒部分。特别是,插入DATETIME或TIMESTAMP列的值中的任何小数部分都将被存储,而不是丢弃。包含小数部分时,这些值的格式为"YYYY-MM-DD hh:MM:ss[.fraction]",DATETIME值的范围为"1000-01-01 00:00:00.00000000"到"9999-12-31 23:59:59.999999",
CREATE TABLE `dt_test` (
`trade_date` datetime NOT NULL,
PRIMARY KEY (`trade_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
mysql> insert into dt_test select '2022-01-01 00:00:00.000000';
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> insert into dt_test select '2022-01-01 00:00:00.120000';
ERROR 1062 (23000): Duplicate entry '2022-01-01 00:00:00' for key 'dt_test.PRIMARY'
我认为2022-01-01 00:00:00.000000
和2022-01-01 00:00:00.120000
不同,所以两者都应该成功插入。但实际上只能插入一个?原因是什么?
此行为在https://dev.mysql.com/doc/refman/8.0/en/fractional-seconds.html.当您尝试插入的值不是"0"时,该值将被四舍五入;fit":
- 将具有小数秒部分的
TIME
、DATE
或TIMESTAMP
值插入到相同类型但小数位数较少的列中会导致舍入
您不会收到任何错误或警告:
发生这种舍入时,不会发出警告或出现错误。此行为遵循SQL标准。
这意味着,即使将2022-01-01 00:00:00.120000
指定为值,它也会在DATETIME(0)
列中四舍五入为2022-01-01 00:00:00
。值2022-01-01 00:00:00.000000
也会发生这种情况,这将导致重复的密钥错误消息。
有趣的是,这句话
特别是,插入DATETIME或TIMESTAMP列的值中的任何小数部分都将被存储,而不是丢弃。
https://dev.mysql.com/doc/refman/8.0/en/datetime.html是误导性的,因为分数部分没有存储(或者它是存储的,但你不能以任何方式使用它(。