2014-09-29 70 views
1

我相信這對很多人來說都是簡單的東西,所以我希望您能夠輕鬆地提供幫助。MySQL - 在「一對多」關係的「許多」方面聚集索引

如果我有一個「多」側的MySQL表「一對多」的關係 - 是這樣的:

Create Table MyTable(
ThisTableId int auto_increment not null, 
ForeignKey int not null, 
Information text 
) 

由於該表將始終通過使用一個連接使用ForeignKey的,它會將ForeignKey設置爲聚集索引似乎很有用,這樣外鍵總是可以在相同的源記錄中進行相鄰排序。但是,ForeignKey並不是唯一的,所以我認爲要將它作爲聚集索引是不可能的或不好的做法?如果我嘗試使用(ForeignKey,ThisTableId)來創建組合主鍵以實現有用的集羣和唯一性,那麼會出現錯誤「只能有一個自動列,並且必須將其定義爲鍵」。

我想也許我正在接近這個錯誤的,在這種情況下,什麼是最好的方式來索引上表的最大速度?

+1

我懷疑你是過早過度優化你的數據結構。 'ForeignKey'的索引應該沒問題。 'ThisTableId'應該聲明爲'主鍵'。 – 2014-09-29 15:54:30

回答

0

InnoDB要求如果您有一個自動增量列,它必須是第一個列中的一個鍵。

因此,您不能將主鍵定義爲(ForeignKey,ThisTableId) - 如果ThisTableId是自動遞增的。

如果ThisTableId只是一個常規列(而不是自動增量),那麼您可以這樣做,但是您將負責在ForeignKey中爲具有相同值的其他行分配至少唯一的值。

我見過的一種方法是使列BIGINT UNSIGNED,並使用BEFORE INSERT觸發器從函數UUID_SHORT()中爲列分配一個值。


@ypercube正確地指出另一種解決方案:InnoDB的規則是自動增量列應該是一些的第一欄,如果你創建了一個普通二級鑰匙,那是不夠的。這使您可以創建一個表如下所示:

CREATE TABLE `MyTable` (
    `ForeignKey` int(11) NOT NULL, 
    `ThisTableId` int(11) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`ForeignKey`,`ThisTableId`), 
    KEY (`ThisTableId`) 
) ENGINE=InnoDB; 

而自動遞增按預期工作:

mysql> INSERT INTO MyTable (ForeignKey) VALUES (123), (234), (345), (456); 

mysql> select * from MyTable; 
+------------+-------------+ 
| ForeignKey | ThisTableId | 
+------------+-------------+ 
|  123 |   1 | 
|  234 |   2 | 
|  345 |   3 | 
|  456 |   4 | 
+------------+-------------+ 
+1

但是你也可以在'(ThisTableId)'中有'(ForeignKey,ThisTableId)'作爲PK和唯一的(或簡單的)鍵 - 並且在'ThisTableId'中仍然有自動增加屬性。對? – 2014-09-29 17:29:41

+0

@ypercube,其實你是對的。這是我忽視的一點。我將編輯上述內容。 – 2014-09-29 17:40:35