2016-07-22 103 views
1

我有一個分析平臺,有很多用戶和數百個插入點擊/分鐘。如何避免在MySQL中插入重複項?

有時我看到在同一秒內完全相同的點擊被插入到數據庫中,並且它變成了另一個的副本。

我有一個系統,檢查表是否具有相同的值,如果找到一個不讓其他插入。

但是,在這種情況下,它看起來像是他們插入數據庫中完全相同的毫秒。

我能在這裏做什麼?

+4

不檢查然後插入。正如你所發現的那樣,它受到競爭條件的制約。使用一個唯一的密鑰。讓數據庫執行唯一性 –

+0

您有2個選項,在數據庫中有一個重複的鍵並使用ON DUPLICATE KEY UPDATE,另一個是INSERT IGNORE,如果它已經在數據庫中,它將忽略它 – nniicc

+0

如果您正在記錄點擊次數以及何時他們發生了,我想你會想知道有多少,包括那些同時發生的事情。如果是這樣的話,你可能想要插入一個點擊計數並使'ON DUPLICATE'子句增加。 – Uueerdo

回答

2

我最喜歡的:insert ignore myTable (col1, col2, ...) ...

其中唯一密鑰(S)是預先設置禁止插入。看起來你並不在乎它曾經插入過多,因爲你關心的是最終的結果不是愚蠢的。

注:獨特的鍵可以多列鍵(複合材料)

警告有關insert ignore一句:應該不會沒有副作用爲那些需要知道的行敏感系統的認真思考來實現真的已經在那裏了。它是「確保它在那裏」的理想選擇。

選項B:人們可以考慮意向鎖,像here,但製作您的特定用例。指向INNODB的行級鎖定是非常靈活的,當然不是表鎖。大多數情況下都會有一個折衷。鎖定的缺點是併發性降低。

選項C:對於模糊的心(有時是我)。如果被僱傭出去,並且希望稍後不再有同伴反彈,這就是我會做的。執行Insert ... on Duplicate Key UpdateIODKU),並且有一個虛擬列,如touches,這是一個您爲IODKU的更新部分增加的int值。示例如下:

insert myTable (col1, col2, col3) values (p1,p2,p3) 
on duplicate key update touches=touches+1; 

上述內容將採用極簡主義形式。下方的觀點是我在C#使用,我關心的「IODKU的更新部分」多列,但只是爲了顯示,如果它的好處的人:

enter image description here

上IODKU最後一個想法:必須擁有導致「衝突」發生的唯一密鑰(主要或唯一)。因此,該聲明知道是否執行插入或更新。沒有這樣一個唯一的鍵衝突,會插入一個新的行。

回到操作問題,您的系統可能已經有該行的原因是由於高度併發使用而沒有鎖定。

0

如果系統的架構允許它,我會創建兩層解決方案。首先,創建一個臨時表,在其中插入重複數據。臨時表的名稱可以包含分片參數,例如小時數。系統將定期將臨時表中的數據導出到主存儲表中,丟棄重複的數據。然後它可以丟棄臨時表。