Mysql

MySQL:對大列的唯一約束

  • October 23, 2012

我正在嘗試創建一個 InnoDB 表,其中包含一個VARCHAR最多可容納 3071 個字元的列。我想UNIQUE對該列的數據實施約束。

MySQL 似乎使用索引來強制執行約束。VARCHAR(3071)在 InnoDB 中,索引大小似乎被限制為 767 字節——對於保存數據的列來說還不夠。

關於如何讓數據庫強制數據的唯一性,而不影響最大數據長度或 InnoDB 的使用的任何想法?

你不想要一個巨大的gen_clust_index(內部聚集索引)。即使對於二級索引,這個大小也是非常大的。

您可能不得不求助於觸發器或儲存過程來提前檢查密鑰。

您還可以考慮使用該欄位執行SHA1函式呼叫。SHA1將返回一個 40 個字元的欄位。此雜湊可能正是您需要索引的內容。VARCHAR(3071)

假設你有這個

CREATE TABLE mytable
(
   id int not null auto_increment,
   txt VARCHAR(3071),
   primary key (id)
) ENGINE=InnODB;

並且您想UNIQUE在 txt 上建立索引。嘗試SHA1方法

CREATE TABLE mytablenew LIKE mytable;
ALTER TABLE mytable ADD txtsha1 CHAR(40);
ALTER TABLE mytable ADD UNIQUE KEY (txtsha1);
INSERT INTO mytablenew (id,txt,txtsha1)
SELECT id,txt,SHA1(txt) FROM mytable;

然後,數一數

SELECT COUNT(1) FROM mytable;
SELECT COUNT(1) FROM mytablenew;

如果計數相同,恭喜!現在你有一個長度為 40 的唯一索引。你可以完成:

ALTER TABLE mytable RENAME mytableold;
ALTER TABLE mytablenew RENAME mytable;
DROP TABLE mytableold;

正如以下評論中所指出的,這可能更加原子化:

RENAME TABLE mytable TO mytableold, mytablenew TO mytable;
DROP TABLE mytableold;

在您打算擁有這個大列的任何表上執行此操作。您必須記住將數據的SHA1與上的數據一起添加INSERT

重複鍵的機率是 2 的 1 的 160 次方(即 1.4615016373309029182036848327163e+48。如果我得到確切的數字,我會在某天發布)。

試一試 !!!

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