2010-11-11 69 views
6

這可能是一種常見情況,但我無法在SO或Google上找到具體的答案。在MySQL中維護一個唯一值的大表格

我有一個很大的表(> 1000萬行)的MySQL數據庫上的朋友關係,這是非常重要的,需要保持這樣,沒有重複的行。該表存儲用戶的uid。表的SQL是:

CREATE TABLE possiblefriends(
id INT NOT NULL AUTO_INCREMENT, 
PRIMARY KEY(id), 
user INT, 
possiblefriend INT) 

表的工作方式是每個用戶大約有1000左右的「可能朋友」被發現並需要存儲,但重複「可能朋友」需避免。

問題是,由於程序的設計,在一天的過程中,我需要向表中添加100萬行或更多的行,可能或不是重複的行條目。簡單的答案似乎是檢查每一行以查看它是否重複,如果不是,則將其插入表中。但是,隨着表格大小增加到1億行,10億行或更多(我預計它很快),這種技術可能會變得非常緩慢。

什麼是最好的(即最快)的方式來維護這個獨特的表?

我並不需要一張只有唯一值的表格。我只需要每天一次的批量作業。在這種情況下,我應該創建一個插入所有可能行(包含重複行和所有行)的單獨表,然後在一天結束時創建第二個表來計算第一個表中的所有唯一行嗎?

如果不是,該表格的長期最佳方式是什麼?

(如果指標是最好的長期解決方案,請告訴我要使用的索引)

+0

問題,做u需要查詢表'possiblefriends'?我只是想你可能會根據用戶分割桌子,當你查詢時它將會有所幫助,但是它可能會在長時間內變成維護災難 – ajreal 2010-11-11 09:12:56

+0

@ajreal:你的意思是每個用戶都有自己的桌子嗎?將會有近一百萬用戶左右,所以這可能會使事情變得非常複雜。 – eric 2010-11-11 10:04:34

+0

是的,這是我提到它可能會變成維護災難,如何使用每桌約1k用戶?想象一下,你把所有的數據放在一張桌子上,發生桌子墜毀,無法恢復,甚至可以恢復,你能忍受多久的停機時間? – ajreal 2010-11-11 12:48:50

回答

7

添加一個唯一索引(user, possiblefriend)然後使用一個:

to en確保您在嘗試插入重複行時不會收到錯誤。

您可能還想考慮是否可以放棄自動遞增主鍵並使用(user, possiblefriend)作爲主鍵。這將減少表的大小,並且主鍵也將用作索引,從而使您不必創建額外的索引。

參見:

+1

我讀過這個問題。 INSERT IGNORE或INSERT ... ON DUPLICATE KEY UPDATE對於一般具有數百行數百行的表有效嗎? – eric 2010-11-11 08:33:14

+1

@eric:我想象'INSERT IGNORE'是最快的,但我只是猜測。爲了確保你可以對所有三種方法進行性能測試。對於我鏈接到的問題,頂級投票答案建議使用「INSERT ... ON DUPLICATE KEY UPDATE」。 – 2010-11-11 08:36:20

+1

注意 - 它必須是唯一索引! – symcbean 2010-11-11 12:33:27

2

唯一索引會讓你確信領域的確是獨一無二的,你可以添加一個唯一索引,像這樣:

CREATE TABLE possiblefriends( 
id INT NOT NULL AUTO_INCREMENT, 
PRIMARY KEY(id), 
user INT, 
possiblefriend INT, 
PRIMARY KEY (id), 
UNIQUE INDEX DefUserID_UNIQUE (user ASC, possiblefriend ASC)) 

這也將顯着提高您的表訪問。

你的其他問題與大衆插入有一點比較麻煩,你可以使用內置的ON下面重複鍵更新功能:

INSERT INTO table (a,b,c) VALUES (1,2,3) 
    ON DUPLICATE KEY UPDATE c=c+1; 

UPDATE table SET c=c+1 WHERE a=1; 
+0

謝謝。使用索引總是更好嗎?使用我應該考慮的較大表格的索引會有什麼代價嗎? – eric 2010-11-11 08:47:28

相關問題