簡體   English   中英

為 SQL 插入生成 ID 的最佳方法是什么?

[英]What is the best way to generate an ID for a SQL Insert?

生成將在 INSERT 語句中立即使用的 ID 號的最佳、獨立於 DBMS 的方法是什么,使 ID 大致按順序排列?

DBMS 獨立? 那是個問題。 兩種最常見的方法是自動遞增列和序列,大多數 DBMS 只做其中之一,但不會同時做這兩個。 因此,獨立於數據庫的方法是擁有另一個表,其中一列具有您鎖定的一個值,select,更新和解鎖。

通常我會說“與 DBMS 無關”,並使用 PostgreSQL 中的序列或 MySQL 中的自動增量列來實現。 就我的目的而言,支持兩者都比試圖找出一種適用於任何地方的方法要好。

如果您可以使用您選擇的編程語言創建全局唯一標識符(GUID) - 將其視為您的 id。

在進行故障排除時,它們更難使用(輸入 INT 的where條件要容易得多),但也有一些優點。 通過在本地將 GUID 分配為您的鍵,您可以輕松地建立父子記錄關系,而無需先將父項保存到數據庫並檢索 id。 並且由於 GUID,根據定義,是唯一的,您不必擔心增加服務器上的密鑰。

有自動遞增或順序

這有什么意義,這是你最不擔心的?

您將如何處理 SQL 本身? MySQL 有限制,

SQL 服務器有頂,

Oracle 有等級

然后還有一百萬個其他的東西,比如觸發器、改變表語法等

是的,原始 SQL (以及我的偏好順序)中的明顯方法是 a) 序列 b) 自動增量字段。 更好、更現代、更獨立於 DBMS 的方法是根本不碰 SQL,而是使用(好的)ORM。

沒有通用的方法可以做到這一點。 如果有,每個人都會使用它。 SQL 根據定義厭惡這個想法 - 它是基於集合的邏輯的反模式(盡管在許多實際情況下很有用)。

您嘗試從其他地方插入標識值的最大問題是,當 SQL 語句涉及多個記錄時,必須同時生成多個值。

如果您需要它,請將其作為您的選擇要求的一部分,以便數據庫與您的應用程序一起使用。 任何嚴肅的 DBMS 產品都會提供自己的使用機制,並且很容易圍繞 DML 中的差異進行編碼。 變化幾乎都在 DDL 中。

對於 DB 特定的解決方案,我總是使用 go,但如果你真的必須這樣做的通常方法是實現你自己的序列。 您的 RDBMS 必須支持事務。

您創建一個包含 int 列的序列表並使用第一個數字作為種子,然后您的事務邏輯看起來像這樣

begin transaction
update tblSeq set intID = intID + 1
select @myID = intID from tblSeq

inset into tblData (intID, ...) values (@myID, ...)
end transaction

事務強制寫鎖,這樣下一個排隊的插入不能在記錄插入到 tblData 之前更新 tblSeq 值。 只要所有通過此事務插入 go ,那么您生成的 ID 就是按順序生成的。

只有 SQL,以下可能是方法之一:

  1. 創建一個表以包含您需要的起始 id
  2. 首次部署應用程序時,應用程序應讀取其上下文中的值。
  3. 此后,根據需要遞增 id(以線程安全方式) 3.1 將 id 寫入數據庫(以線程安全方式)始終保持更新值 3.2 不要將其寫入數據庫,只需在 memory(線程- 安全的方式)
  4. 如果由於任何原因服務器出現故障,請將當前 id 值寫入數據庫
  5. 當服務器再次啟動時,它將從上次離開的位置進行選擇。

使用自動遞增的 id 列。

他們真的有理由必須按順序排列嗎? 如果您只是將其用作 ID,那么您應該只能使用 UUID 的一部分或 md5(now()) 的前幾個數字。

你可以花時間按摩它。 它相當於類似的東西

DateTime.Now.Ticks

所以它就像 YYYYMMDDHHMMSSSS

它可能有點橫向方法,但一個好的 ORM 類型庫可能至少能夠隱藏差異。 For example, in Ruby there is ActiveRecord (commonly used in but not exclusively tied to the Ruby the Rails web framework) which has Migrations. 在與平台無關的代碼中聲明的表定義中,數據類型、順序 id 生成和索引創建等實現細節被推到您的視野之下。

我在 SQLite 上透明地開發了一個模式,然后在 MS SQL 服務器上實現了它,后來移植到 Oracle。 無需更改生成我的架構定義的代碼。

正如我所說,它可能不是您想要的,但封裝變化的最簡單方法是使用已經為您完成封裝的庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM