2013-08-19 120 views
0

我想爲每一天創建唯一的訂單號。因此,理想情況下,例如在PostgreSQL中,我可以創建一個序列並讀取這些唯一的數字,因爲回讀都爲我提供了新的數字,並且是原子的。然後在一天結束時,我會重置序列。sqlite3 autoincrement - 我錯過了什麼?

但是,在sqlite3中,我只看到整數字段類型的自動增量。所以說,我建立了一個帶有自動增量字段的表格,並插入了一個記錄來獲得新的數字(似乎是一種非常低效的方法,但無論如何...)當我去閱讀最大值後,誰是說另一個任務沒有進入並插入另一個記錄,從而導致我回讀一個未命中,我的第一個太高級了(和另一個任務回讀的副本)。

從概念上講,我要求:

  • 快速鎖定與等待其他任務
  • 增量數
  • 檢索數
  • 解鎖

......我只是不知道如何用sqlite3來做到這一點。任何人都可以啓發我嗎?

回答

1

在SQLite中,自動增量字段旨在用作其記錄的實際主鍵。 您應該將它作爲您的訂單表的ID。

如果您確實想擁有一個獨立於相應表記錄的原子計數器,請使用具有單個記錄的表。 酸是確保了交易:

BEGIN; 
SELECT number FROM MyTable; 
UPDATE MyTable SET number = ? + 1; 
COMMIT; 
+0

我不認爲這回答了這個問題,否則我不理解它:假設我這樣做,然後獲取結果,但在得到結果之前,其他一些進程再次執行該操作?如何讓我的計數器增量的結果在讓任何其他進程再次遞增之前給我提供多個增量的結果?請記住,這不是一個計數器,它是一個orderID;我必須得到一個唯一的號碼,當我得到它時我必須知道它是什麼。 – fyngyrz

+0

來詳細說明:1)我增加2)其他進程增量3)我讀取並獲得雙倍增量,4)其他進程讀取並獲得相同的雙倍增量。看到問題了嗎? – fyngyrz

+0

交易是[原子](http://www.sqlite.org/atomiccommit.html);當所有依賴語句都在一個事務中時,您不會發生衝突。 –

0

好吧,看起來像SQLite的要麼沒有我需要什麼,或者我很想念它。以下是我想出了:

  • 聲明ZORDER作爲整數主鍵自動遞增,南荷蘭整數訂單表

    這意味着每個新行的上升數字,從1開始

  • 產生一個隨機數:

    rnd = int(隨機。隨機的()* 1000000)#種子選手Python使用系統時間

  • 創造新的秩序(只是SQL爲簡單起見):

    'INSERT INTO訂單(老城)VALUES(' + STR(RND)+') '

  • 發現使用隨機數,準確的順序號:

    ' SELECT ZORDER FROM訂單WHERE的Zuid =「+ STR(RND)

  • 包遠離該號碼作爲新的順序號(newordernum )

  • 撞隨機數,以減少碰撞危險

    'UPDATE命令SET南荷蘭= 0 WHERE ZORDER =' + STR(newordernum)

...現在我有一個獨特的新訂單,我知道正確的訂單號碼是什麼,讀取碰撞的風險降低到可以忽略不計,我可以準備該訂單,而不用擔心我正在踐踏另一個新創建的訂單。

只是去告訴你爲什麼DB作者實現序列,哈哈。

+0

這不保證唯一性;衝突的可能性相當高(參見生日悖論),並且兩個同時運行的Python腳本具有相同的系統時間值*會進一步提高概率。 –