MyISAM 唯一键在 64 字节处被截断,导致冲突
我有一个 MySQL 表,它将 url 存储为唯一键。我的键开始发生冲突,因为键本身似乎只是任何 url 的前 64 个字节(如果您愿意,也可以是字符,它是 latin-1 整理的)。因此,如果 url 超过 64 个字符,并且我已经获得了类似的 url,则会引发错误。
例如:
SELECT l.link_id FROM mydb.links l WHERE
url = 'http://etonline.com/tv/108475_Charlie_Sheen_The_People_Have_Elected_Me_as_Their_Leader/index.html'
抛出此错误:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
'http://etonline.com/tv/108475_Charlie_Sheen_The_People_Have_Elec' for key 'url'
MyISAM 不应该有 1000 字节的密钥长度吗?
编辑: CREATE TABLE STATUS 调用上似乎没有列出前缀长度,它看起来像这样:
CREATE TABLE `links` (
`link_id` int(11) NOT NULL AUTO_INCREMENT,
`url` varchar(500) NOT NULL,
PRIMARY KEY (`link_id`),
UNIQUE KEY `url` (`url`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
我尝试将一个前缀长度设置为 256,如下所示:
ALTER TABLE `mydb`.`links`
DROP INDEX `url`, ADD UNIQUE INDEX `url` (`url`(256) ASC) ;
我收到以下错误:
ERROR 1062: Duplicate entry '<...64-byte key...>' for key 'url'
SQL Statement:
ALTER TABLE `mydb`.`links`
DROP INDEX `url`, ADD UNIQUE INDEX `url` (`url`(256) ASC)
ERROR: Error when running failback script. Details follow.
ERROR 1050: Table 'links' already exists
我认为回退只是因为我跑了通过 MySQL Workbench 的 ALTER TABLE。
I've got a MySQL table that stores urls as unique keys. I'm starting to get collisions on my keys because it seems the keys themselves are only the first 64 bytes (or characters if you prefer, its a latin-1 collated) of any url. So if a url is over 64 characters and I've already got a similar url it throws an error.
For example:
SELECT l.link_id FROM mydb.links l WHERE
url = 'http://etonline.com/tv/108475_Charlie_Sheen_The_People_Have_Elected_Me_as_Their_Leader/index.html'
Throws this error:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
'http://etonline.com/tv/108475_Charlie_Sheen_The_People_Have_Elec' for key 'url'
Isnt MyISAM supposed to have 1000-byte key lengths?
EDIT: There doesn't seem to be a prefix length listed on the CREATE TABLE STATUS call it looks like this:
CREATE TABLE `links` (
`link_id` int(11) NOT NULL AUTO_INCREMENT,
`url` varchar(500) NOT NULL,
PRIMARY KEY (`link_id`),
UNIQUE KEY `url` (`url`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
I tried to set one at 256 like this:
ALTER TABLE `mydb`.`links`
DROP INDEX `url`, ADD UNIQUE INDEX `url` (`url`(256) ASC) ;
and I got the following error:
ERROR 1062: Duplicate entry '<...64-byte key...>' for key 'url'
SQL Statement:
ALTER TABLE `mydb`.`links`
DROP INDEX `url`, ADD UNIQUE INDEX `url` (`url`(256) ASC)
ERROR: Error when running failback script. Details follow.
ERROR 1050: Table 'links' already exists
I think the fallback is just because I ran the ALTER TABLE through MySQL Workbench.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为错误消息仅显示前 64 个字符,但这并不意味着限制仅限于 64 个字符。
如果您的
SHOW CREATE TABLE
输出准确,则索引位于所有 500 个字符上,并且您将找到完全相同的重复项。I think the error message is only showing you the first 64 characters, but that doesn't mean the constraint is limited to 64 characters.
If your
SHOW CREATE TABLE
output is accurate, then the index is on all 500 characters, and you are hitting an exact duplicate.当您创建仅使用前缀的索引(通过指定索引的长度)时,前缀可以最多1000字节(请参阅7.5.1 列索引)。使用
显示创建表
找出索引的实际长度。When you create an index that only uses a prefix (by specifying the length of the index), then the prefix can be up to 1000 bytes (see 7.5.1 Column Indexes). Use
SHOW CREATE TABLE
to find out the actual length of the index.