今天我遇到了我见过的MySQL中最奇怪的事情之一。 我有一个简单的表:mysql auto_increment列按随机值递增
CREATE TABLE `features`
(
`feature_id` mediumint(6) unsigned NOT NULL AUTO_INCREMENT,
`feature_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,
PRIMARY KEY (`feature_id`),
UNIQUE KEY `feature_name_key` (`feature_name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
我里面与Java和MySQL连接器的Java-5.1.15库插入数据。 feature_name中的数据可能会重复,我只想要唯一的值。我可以使用INSERT忽略,但如果数据太长我可能会忽略它,所以我用这个:
pstmt = conn.prepareStatement(
"INSERT INTO features (feature_name) VALUES (?)");
for (String featureName: data4db.keySet())
{
pstmt.setString(1, featureName);
try
{
pstmt.executeUpdate();
}
catch (SQLException se)
{
if (se.getErrorCode() == 1062) // duplicate entry
{
continue; // ignore
}
throw se; // do not ignore anything else
}
}
数据已经被插入到数据库后,我发现有一些问题,我还没有甚至有望。上表中大概有4000条记录可以。唯一的问题是由于重复主键导致一些数据无法插入,所以我查看了这个表的auto inc值的外观。事实证明,对于大多数数据,下一个相邻行的id按预期递增1。由于原因,我不知道有时feature_id增加了3,5,1000,100000 - 完全随机的值。因此,我'在这个表中不合适的位置',因为一旦id达到中等int的最大值,它就不能被插入。
这是怎么发生的? 有没有人遇到过类似的东西? 值得一提的是,只有一个程序只有一个线程写入此表。 我'有更多的表几乎相同 - 列的宽度和名称是不同的。对于这一个也有类似的问题。
顺便说一句 - 一些数据:
谢谢你的任何提示提前。
你是对的。感谢同学们的快速和非常有用的教训。我已经仔细检查过它。因此,基本上数字是两个相邻行中的ID之间的差异,表示在这两行之间存在多少次重复插入尝试。 – Artur 2011-04-19 09:19:41
当重复发现被禁用时会自动增加吗?有解决方法吗?我只想拥有一个带有id和一些唯一字符串的表,并且没有id空位,但不想使用insert ignore(它与autoinc有相同的问题),也不会在插入之前读取整个表以检查哪些值已经存在那里?程序? – Artur 2011-04-19 09:28:38
有很多解决方法,但问题是 - 为什么你需要顺序ID?你在这里使用代理键时,从理论的角度来看,自然键将是更好的选择。您可以将您的feature_name_key作为主键(因此可以立即执行唯一约束),并且您可以创建一个触发器来更新名为sequence_id的列,然后可以按顺序指定整数,而无间隙地分配给您的功能名称。 – 2011-04-19 09:41:57