我正在使用MySQL 5.1.56,MyISAM。我的表看起来像这样:
CREATE TABLE IF NOT EXISTS `my_table` (
`number` int(11) NOT NULL,
`name` varchar(50) NOT NULL,
`money` int(11) NOT NULL,
PRIMARY KEY (`number`,`name`)
) ENGINE=MyISAM;
它包含这两行:
INSERT INTO `my_table` (`number`, `name`, `money`) VALUES
(1, 'S. Name', 150), (2, 'Another Name', 284);
现在我想插入另一行:
INSERT INTO `my_table` (`number`, `name`, `money`) VALUES
(2, 'S. Name', 240);
MySQL告诉我这个时不会插入它:
#1062 - Duplicate entry '2-S. Name' for key 'PRIMARY'
我真的不明白。主键位于前两列(两者都是),因此我尝试插入的行是一个唯一的主键,不是吗?
我试图修复表,我试图优化表,一切都无济于事。另请注意,我无法从MyISAM更改为InnoDB。
我错过了什么或者这是MySQL或MyISAM的错误吗?谢谢。
总结并指出我认为的问题所在(尽管不应该存在):Table在两列上有主键。我试图在这两列中插入一个具有新值组合的行,但第一列中的值已经在某行中,第二列中的值已经在另一行中。但它们并没有任何组合,所以我相信这应该有用,我很困惑,看到它没有。
您的代码和架构都可以。您可能尝试使用以前版本的表。
http://sqlfiddle.com/#!2/9dc64/1/0
您的表甚至没有UNIQUE,因此该表上的错误是不可能的。
从该表备份数据,删除并重新创建。
也许你试图运行那个CREATE TABLE IF NOT EXIST
。它没有创建,你有旧版本,但由于IF NOT EXIST
没有错误。
你可以像这样运行SQL来查看当前的表结构:
DESCRIBE my_table;
编辑 - 稍后添加:
试着运行这个:
DROP TABLE `my_table`; --make backup - it deletes table
CREATE TABLE `my_table` (
`number` int(11) NOT NULL,
`name` varchar(50) NOT NULL,
`money` int(11) NOT NULL,
PRIMARY KEY (`number`,`name`),
UNIQUE (`number`, `name`) --added unique on 2 rows
) ENGINE=MyISAM;
如果除了OP之外这对任何人都有帮助,我在使用InnoDB时遇到了类似的问题。
对我来说,真正发生的是外键约束失败。我引用了一个不存在的外键。
换句话说,错误完全消失了。主键很好,插入外键首先解决了问题。不知道为什么MySQL突然出错了。
就我而言,错误是非常误导的。问题是当你单击“make unique”按钮而不是“ALTER IGNORE TABLE”时,PHPMyAdmin使用“ALTER TABLE”,所以我必须手动完成,如:
ALTER TABLE mytbl ADD UNIQUE (columnName);
添加列或使用现有列作为主键时,通常会创建此问题。它不是由于存在从未实际创建的主键或由于表的损坏而创建的。
错误实际表示的是挂起的键值为空。
解决方案是使用唯一值填充列,然后再次尝试创建主键。不能有空白,空值或重复值,否则会出现这种误导性错误。
我有一个类似的问题,但在我的情况下,它发现我使用不区分大小写的排序 - utf8_general_ci
。
因此,当我尝试在区分大小写的比较中插入两个不同的字符串,但在不区分大小写的情况下相同时,MySQL发出错误并且我无法理解什么是问题,因为我使用了区分大小写搜索。
解决方案是更改表的排序规则,例如我使用了区分大小写的utf8_bin
(或者utf8_general_cs
也应该是合适的)。
在查看你的错误#1062 - Duplicate entry '2-S. Name' for key 'PRIMARY'
时,它说你在数字字段中使用主键,这就是它在数字字段上显示重复错误的原因。所以删除这个主键然后它也插入重复。
我知道在这种情况下这不是问题,但在创建复合主键时我遇到了类似的“重复条目”问题:
ALTER TABLE table ADD PRIMARY KEY(fieldA,fieldB);
错误是这样的:
#1062 Duplicate entry 'valueA-valueB' for key 'PRIMARY'
所以我搜索了:
select * from table where fieldA='valueA' and fieldB='valueB'
输出显示只有1行,没有重复!
一段时间后,我发现如果你在这些字段中有NULL值,你会收到这些错误。最后,错误信息有点误导我。
在我的情况下,错误是由过时的模式引起的,一列最初是varchar(50)
但我试图导入的转储是从该模式的修改版本创建的,该模式具有该列的varchar(70)
(以及该字段的一些条目,其中使用超过50个字符)。
在导入过程中,某些键被截断,截断的版本不再是唯一的。花了一段时间来弄明白,我就像“但这个据称重复的钥匙甚至不存在!”。
不太常见的情况,但请记住,根据DOC https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-limitations.html
运行在线ALTER TABLE操作时,运行ALTER TABLE操作的线程将应用从其他连接线程在同一表上并发运行的DML操作的“在线日志”。应用DML操作时,可能会遇到重复的键输入错误(ERROR 1062(23000):重复输入),即使重复的条目只是临时的,并且将被“在线日志”中的后续条目还原。这类似于InnoDB中的外键约束检查的想法,其中约束必须在事务期间保持。
尝试使用自动增量:
CREATE TABLE IF NOT EXISTS `my_table` (
`number` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`money` int(11) NOT NULL,
PRIMARY KEY (`number`,`name`)
) ENGINE=MyISAM;
您的代码在此演示中运行良好:
我想你正在做第二次查询(插入...)两次。尝试
select * from my_table
在插入新行之前,您将获得您的数据是否已存在。
我刚刚尝试过,如果你有数据和表重新生成无法工作,只需将表改为InnoDB并再试一次,它就能解决问题
如果其他人发现我的问题这个线程 - 我在MySQL中使用“整数”列类型。我试图插入的行有一个主键,其值大于整数允许的值。切换到“bigint”修复了问题。
根据您的代码,您的“数字”和“名称”是主键,并且您在两行中都插入了S.NAME,因此会产生冲突。我们使用primarykey来访问完整的数据。在这里,您无法使用主键'name'访问数据。
我是一个初学者,我认为这可能是错误。