Mysql

添加唯一索引失敗並出現重複條目錯誤,但未找到重複項

  • April 9, 2020

給定表:

CREATE TABLE mytable (
 field_a CHAR(15) NOT NULL DEFAULT '',
 field_b MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
 field_c SMALLINT UNSIGNED NOT NULL DEFAULT 0,
 field_d SMALLINT UNSIGNED NOT NULL DEFAULT 0,
 field_e CHAR(1) NULL DEFAULT '',
 field_f SMALLINT UNSIGNED NOT NULL DEFAULT 0
) ENGINE=MyISAM DEFAULT CHARACTER SET=UTF8 COLLATE utf8_general_ci;

所需索引:

ALTER TABLE mytable ADD UNIQUE INDEX idx_key (field_a, field_b);

數據大小約為 51 Mio。行。以下問題:

嘗試 1:如果我在數據位於表中之後嘗試創建索引,則會失敗並出現重複鍵錯誤。對失敗鍵的選擇僅返回一個(!)行。

[23000][1062] Duplicate entry 'aaaaaaaaaaaaaaa-11111' for key 'idx_key'

SELECT COUNT(*) FROM mytable WHERE field_a='aaaaaaaaaaaaaaa' AND field_b='11111'

返回 1 (!)

嘗試2:如果我在一個空表上創建索引或做一個組合私鑰然後將數據放入表中,該表僅包含51個Mio中的27個。行 (!)。

唯一索引或錯誤是否有某種限制?

我使用 MariaDB 10.0.20。請幫忙。

更新 1

唯一行數

SELECT COUNT(DISTINCT field_a,field_b) from mytable; 

返回 50 個 Mio 行。所以大約有 1 個 Mio 重複項。然而,這並不能解釋嘗試 2 中的 27 Mio 或嘗試 1 中的錯誤異常。

更新 2

嘗試 2 使用的表:

CREATE TABLE mytable (
 field_a CHAR(15) NOT NULL DEFAULT '',
 field_b MEDIUMINT UNSIGNED NOT NULL DEFAULT 0,
 field_c SMALLINT UNSIGNED NOT NULL DEFAULT 0,
 field_d SMALLINT UNSIGNED NOT NULL DEFAULT 0,
 field_e CHAR(1) NULL DEFAULT '',
 field_f SMALLINT UNSIGNED NOT NULL DEFAULT 0,
 UNIQUE KEY idx_key (field_a, field_b)
) ENGINE=MyISAM DEFAULT CHARACTER SET=UTF8 COLLATE utf8_general_ci;

更新 3

嘗試2錯誤已解決

為了填充表,我們使用 INSERT 語句,每個語句中都有多個值行。如果插入的單個值違反了唯一約束,則所有其他值也未插入並導致 27 Mio 行而不是 50 Mio。

方法 1:但是,即使在刪除並重新創建數據庫之後,錯誤的重複條目消息仍然存在,但這是我可以/必須忍受的邪惡。

無法保證aaaaaaaaaaaaaaa-11111消息中的值

[23000][1062] Duplicate entry 'aaaaaaaaaaaaaaa-11111' for key 'mykey'

是實際導致違規的值。似乎是 MariaDB 和 MySQL 中的一個錯誤。

計劃 A:INSERT IGNORE在您的批量插入中 使用。這樣 dup 鍵就不會造成麻煩。

計劃 B: 插入到帶有INDEX,而不是的表中UNIQUE。然後,您可以在決定如何處理它們之前調查重複項。

您知道大多數情況下**總是CHAR(15) utf8佔用 45 個字節嗎?也許會更好?(請不要引用被揭穿的妻子關於在 MyISAM 中變得更好的故事。) ROW_FORMATsVARCHAR(15)``FIXED

或者數據可能是舊的 IPv4 字元串?它們適用於CHARACTER SET ascii- 15 個字節CHAR(15)或 1-16 個字節VARCHAR(15)。那麼,IPv6呢?關於無法比較範圍?

引用自:https://dba.stackexchange.com/questions/106294