數據庫引擎內部是否有避免非順序鍵衝突的機制?如果是這樣,它是如何工作的?
假設我創建了一個主鍵具有隨機 uuid 的表。數據庫內部通常有一種機制來優雅地處理衝突嗎?它是如何工作的?
我的腦海中正在想像一些簡單的事情,比如“生成一個密鑰並檢查它是否存在,如果它確實存在則生成另一個”。但是如果你有一個簡單的非順序鍵,你可能會在這個衝突循環中結束相當長的一段時間。
答案是不”。使用適合其要求的方法生成唯一 ID 並在它認為合適的時候處理重複鍵是應用程序的責任。數據庫無法為您決定是否要生成新 ID 或更新現有記錄(或執行完全不同的操作,例如發出警報)。
甚至像
IDENTITY
and之AUTO_INCREMENT
類的東西只是序列的快捷方式,它們會受到環繞和隨後的衝突。
我認為您可能會混淆一些不同的概念,這使得提供令人滿意的答案有點困難,但我會盡力而為。此外,您的里程可能會因可用選項或“通常情況”而異,具體取決於您正在談論的特定數據庫系統。我的回答是基於我對 Microsoft SQL Server 的一般數據庫知識和特定知識。
在列上定義的主鍵約束並不意味著它會自動為該列生成一個值。相反,身份規範通常用於定義列何時自動遞增並自動生成。主鍵只是在其定義的列上強制執行唯一性。
身份規範通常是數字數據類型,因此它可以是增量(或減量 - 取決於您如何定義)值系列。請注意,它不一定需要定義為連續系列,因為“增量”值可以是在系列中產生間隙的值。例如,如果增量值指定為 5,那麼每個新值都將比前一個值大 5,並且您的身份序列可能類似於
(5, 10, 15, 20, 25...)
.由於 Identity 列通常必須是數字的,正如 mustaccio 所提到的,大多數關係數據庫系統不提供自動生成
UUID
值的方法,作為列規範。此外,通常沒有機制可以在發生碰撞時重新生成一個。相反,響應衝突的責任應該在應用層處理,或者至少響應行為需要由開發人員以某種方式定義。回到我關於主鍵的第一段,它們的功能再次是強制唯一性。因此,雖然一
UUID
列可以在其上定義主鍵。所要做的就是防止將重複UUID
值插入到此類列中,通常是通過將錯誤返回給呼叫者。再一次,由呼叫者來處理如何響應這個錯誤,UUID
如果開發人員選擇重新生成一個新的錯誤,這可能是。最後,希望澄清您對 mustaccio 答案的評論,大多數關係數據庫系統確實提供了手動生成
UUID
(順序和非順序)的功能,並且它們確實利用數據庫系統引擎中的算法在生成新值時處理衝突。但同樣,這些都是函式,不能用作列級別的自動生成規範。在某些數據庫系統中,您可能能夠與使用者定義的函式或利用現有函式一起破解某些東西,也許是在電腦列內。但是通常沒有開箱即用的東西,並且破解您自己的版本可能會面臨邊緣情況和/或錯誤的風險。