今天我遇到了我見過的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