我正在将带有InnoDB的MySQL 8与带有mysql2驱动程序的节点服务器一起使用。
我的桌子如下:
CREATE TABLE IF NOT EXISTS users(
id VARCHAR(36) NOT NULL,
name VARCHAR(32) NOT NULL,
email VARCHAR(255) NOT NULL,
...
PRIMARY KEY (id)
)
我不使用自动递增,作为VARCHAR ID,我使用基于时间的UUID。
如果我现在执行SELECT查询:
SELECT * FROM users where id = 'some valid id';
我得到了预期的结果。
如果我这样做:
SELECT * FROM users where id = '0';
我什么也没得到,因为表中没有id的值为'0'。
但是,如果我这样做:
SELECT * FROM users where id = 0;
我得到了最后插入的行,它当然有一个有效的VARCHAR id,它不同于0。
由于我的节点服务器有时会在http查询中将undefined解释为0,因此偶然在我的节点服务器上发生了此行为。 因此,我可以轻松避免在查询中插入0(我现在要做什么),但是我想了解为什么会这样。
答案 0 :(得分:2)
您的id
是varchar()
,因此此比较:
WHERE id = 0
需要类型转换。
根据SQL中的转换规则,id
被转换为字符串。现在,在许多数据库中,如果无法将id
的任何值转换为数字,则会出现错误。
但是,MySQL支持隐式转换没有错误。 (您可以在documentation中了解有关这种转换的信息。)这会将所有前导数字转换为数字-忽略其余的数字。如果没有前导数字,则该值为零。因此,所有这些在MySQL中都是正确的:
'a' = 0
'0a' = 0'
'anything but 0!' = 0
这个故事有两种寓意。
id
是一个数字,请使用数字数据类型(int
,bigint
,decimal
)。