2015-07-19 45 views
1

剛剛跳入django 1.8快速項目,我覺得有一個UUIDField模型。是否django的新UUIDField的'默認'屬性照顧的唯一性'

https://docs.djangoproject.com/en/1.8/ref/models/fields/#uuidfield

我用這對外部ID字段,每個模式將不得不暴露的對象。請問default參數是處理唯一性還是必須在保存中寫入?我的意思是我知道價值觀實際上沒有碰撞的可能性,但只是爲了知道它是如何在內部完成的

回答

5

UUID模塊如何保證每次都有唯一的值?

RFC 4122(UUID模塊規範)指定了三個算法來生成UUID:

  1. 使用IEEE 802 MAC地址作爲唯一
  2. 使用僞隨機數
  3. 源使用公知的串結合加密哈希

在所有情況下,種子值與系統時鐘時鐘序列值(以保持時鐘向後設置的唯一性)。因此,根據上述機制生成的UUID將與已經或將要分配的所有其他UUID相同。

從RFC 4122 Abstract摘自:

UUID是128位長,並且可以在空間和時間 保證唯一性。

注:由於UUID的這種唯一性,沒有檢查Django在內部完成(由@FlipperPA提到過),以檢查是否已存在具有相同uuid另一個對象。

+1

謝謝,偉大的洞察力。這非常棒 –

1

不,它沒有。下面是代碼從Django的相關部分:

def get_db_prep_value(self, value, connection, prepared=False): 
    if isinstance(value, six.string_types): 
     value = uuid.UUID(value.replace('-', '')) 
    if isinstance(value, uuid.UUID): 
     if connection.features.has_native_uuid_field: 
      return value 
     return value.hex 
    return value 

正如你可以看到,數據庫準備的價值時,它簡單的調用用的uuid在連字符代替;沒有檢查現有的唯一性。也就是說,UUIDField繼承自類Field,它將遵循Django模型的獨特定義。

+0

那麼在模型對象中,我可以肯定它是唯一的嗎?或者我應該重寫保存並只添加唯一的uuid值 –

2

Django不強制UUID的唯一性。這是因爲UUID的主要用例是提供一個標識符,該標識符可以預期爲唯一的而不需要必須與中央授權機構(如數據庫,這就是unique=True所做的那樣)進行覈對。

(注意的UUID不能保證是唯一的,有剛an astronomically small chance of a collision。)

您當然可以使用數據庫來執行上的UUID的頂部獨特性,如果你想(通過自己場上設置unique=True) ,但我會說這是一個不尋常的,很難證明,配置。

0

我喜歡使用UUID作爲主鍵,我喜歡不提供500錯誤給最終用戶一個簡單的操作,例如創建一個登錄。所以我在我的模型中有以下類方法。我爲生產數據庫上的綜合事務抽取一些預先分配的保留GUID,並且不希望那些衝突發生。宇宙閃電已經發生,以下代碼的一個變體(用於報告碰撞)實際上已經引發了第二次guid賦值嘗試。下面顯示的代碼仍然存在來自不同應用程序服務器的併發寫入衝突的風險,因此如果視圖中的寫入/創建操作失敗,我的視圖將回到此方法。

我做ACK這段代碼是由DB查找的時間成本比較慢,但作爲GUID是我的PK吧當底層DB使用上該領域的B樹索引是不是貴得離譜。

@classmethod 
def attempt_to_set_guid(cls,attemptedGuid=None): 
    while(True): 
     try: 
      if attemptedGuid is None: 
       attemptedGuid = uuid4() 
      elif (attemptedGuid in cls.reserved_guids): 
       attemptedGuid = uuid4() 
       continue 
      alreadyExists = Guid.objects.get(guid=attemptedGuid) 
      break 
     except Exception as e: 
      break 
    return attemptedGuid