2010-03-16 49 views
3

我有一些非常簡單的要求,但我不知道我是如何實現它們:如何在不使用UNIQUE約束的情況下保證MySQL中的行唯一性?

  • 我有運行相同的查詢
  • 查詢提供了一個「字符串」值的多個併發線程 - 如果它存在表中,查詢應該返回匹配行的id,如果不是,查詢應該插入'string'值並返回最後插入的ID
  • 'string'列是(並且必須是)文本列(它是大於varchar 255),所以我不能將它設置爲唯一 - 唯一性必須通過訪問機制強制執行
  • q uery需要使用存儲過程格式(不支持MySQL中的表鎖)

如何確保'字符串'是唯一的?在另一個線程讀取它並發現沒有匹配的「字符串」項目後,如何防止其他線程寫入表格?

感謝您的任何建議..

回答

0

你必須讀/寫操作創建同步的線程或同步的資源,所以線程不會被允許讀或寫,而另一個正在讀取或寫入。

至於你可以做一個「貪婪」查詢類的字符串:

select distinct string from table where ... 

首次線程執行一個選擇,那麼你緩存結果在一個HashMap或類似的地圖和更新各線程訪問表以添加行。 首先你會檢查HashMap是否存在,然後執行查詢。如果存在HashMap,你可以檢查你的字符串是否在其中。

+0

我剛剛嘗試過這個,但表格很大,我只是無法緩存整個事情 – MalcomTucker 2010-03-16 14:57:14

1

如果您確定無法使用數據庫約束,請在存儲完整字符串的良好加密哈希的另一個字段上使用UNIQUE索引。我猜測MD5或SHA1應該足夠了。幾個源代碼管理系統(如Git,Mercurial,Monotone等)依賴於散列衝突的可能性極低。

0

您可以爲該文本做一個選擇,如果沒有找到,則插入它,否則更新。把它全部包裝在一個單獨的交易中。

0

而不是使用鎖表,因爲它沒有包括在存儲程序的支持,你可以使用

START TRANSACTION; 

    SELECT * FROM .... 

COMMIT; 

你一定要確保你使用事務安全的存儲引擎就像InnoDB

相關問題