2008-09-18 101 views
2

我在MySQL中有一個表,它有3個字段,我想在兩個字段之間執行唯一性。下面是表DDL在MySQL中強制唯一行

CREATE TABLE `CLIENT_NAMES` (
`ID` int(11) NOT NULL auto_increment, 
`CLIENT_NAME` varchar(500) NOT NULL, 
`OWNER_ID` int(11) NOT NULL, 
PRIMARY KEY (`ID`), 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

ID字段是一個代理鍵(這個表被加載與ETL)。 CLIENT_NAME是一個包含客戶名稱的字段 OWNER_ID是一個id表示客戶的所有者。

我以爲我可以與CLIENT_NAMEOWNER_ID唯一索引強制執行此,

ALTER TABLE `DW`.`CLIENT_NAMES` 
ADD UNIQUE INDEX enforce_unique_idx(`CLIENT_NAME`, `OWNER_ID`); 

但MySQL的給我一個錯誤:

Error executing SQL commands to update table. Specified key was too long; max key length is 765 bytes (error 1071)

任何人有什麼想法?

回答

9

MySQL不能對長度超過765個字節的密鑰實施唯一性(顯然500個UTF8字符可以超過此限制)。

  1. CLIENT_NAME真的需要500個字符嗎?似乎有點過分。
  2. 添加一個散列的新(較短)列(CLIENT_NAME)。取而代之,讓MySQL強制執行該散列的唯一性。
+0

Unicode是一種可變長度編碼。字符的大小可以是1到4個字節,只有原始的128個ASCII字符被編碼在一個字節中。 – 2008-09-18 17:37:56

+2

喬,我認爲你的意思是UTF8,而不是Unicode ...? – Gili 2008-09-18 20:26:12

0

你看過CONSTRAINT ... UNIQUE嗎?

-1

Here。對於UTF8字符集,MySQL可能每個字符最多使用3個字節。 CLIENT_NAME是3 x 500 = 1500字節。將CLIENT_NAME縮短爲250.

更高版本: +1創建名稱的哈希值並將其用作關鍵字。

0

這張桌子有點奇怪,我會考慮重構它。 ID和OWNER_ID引用了什麼,它們之間的關係是什麼?

會是有意義的有

CREATE TABLE `CLIENTS` (
`ID` int(11) NOT NULL auto_increment, 
`CLIENT_NAME` varchar(500) NOT NULL, 
# other client fields - address, phone, whatever 
PRIMARY KEY (`ID`), 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

CREATE TABLE `CLIENTS_OWNERS` (
`CLIENT_ID` int(11) NOT NULL, 
`OWNER_ID` int(11) NOT NULL, 
PRIMARY KEY (`CLIENT_ID`,`OWNER_ID`), 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

我真的會避免在500字符串添加這樣一個獨特的密鑰。在兩個整數上強制執行唯一性會更有效率,再加上表中的id應該真正指向需要id的內容;在您的版本中,ID字段似乎只能識別客戶端/所有者關係,因爲它只是一個映射,所以它確實不需要單獨的ID。