首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

Hibernate 主鍵生成策略全解析:原理、適用場景與選型指南

     編輯:DB2 教學

Hibernate 主鍵生成策略全解析:原理、適用場景與選型指南

Hibernate 提供豐富的主鍵生成策略(<generator>),通過在映射文件中配置即可將主鍵生成邏輯委託給框架或數據庫。本文系統梳理 11 種常用策略的原理、優缺點、適用數據庫及選型建議,助你在不同業務場景做出最優決策。

策略速查表

策略底層依賴類型適用數據庫集群安全推薦指數
incrementHibernate 內存計數器long/short/int所有❌ 單進程⭐
identity數據庫自增列long/short/intMySQL, SQL Server, DB2, Sybase✅⭐⭐⭐
sequence數據庫 Sequencelong/short/intOracle, PostgreSQL, DB2, SAP DB✅⭐⭐⭐
hilo數據庫表 + 內存算法long/short/int所有✅⭐⭐
seqhiloSequence + HiLo 算法long/short/intOracle, PostgreSQL 等支持 Sequence✅⭐⭐
uuid.hexHibernate 128-bit UUIDString(32)所有✅⭐⭐⭐⭐
uuid.stringHibernate 16-bit UUIDString(16)所有✅⭐⭐
guid數據庫 GUIDStringSQL Server, MySQL✅⭐⭐
native自動選擇 identity/sequence/hilo視底層而定所有✅⭐⭐⭐⭐
assigned應用程序手動賦值任意所有視業務而定⭐
foreign關聯表主鍵(一對一)任意所有✅⭐⭐

重點策略深度解析

1. identity — 數據庫原生自增

原理:依賴數據庫 AUTO_INCREMENT (MySQL) 或 IDENTITY(1,1) (SQL Server)。插入時不指定主鍵,數據庫自動生成。

MySQL:    CREATE TABLE t(id INT AUTO_INCREMENT PRIMARY KEY, ...);
SQL Server: CREATE TABLE t(id INT IDENTITY(1,1) PRIMARY KEY, ...);

優點:零配置、性能高、無需額外表/序列。
缺點:Oracle 不支持;批量插入需 session.flush() 才能獲取生成的 ID;跨庫移植性稍弱。

2. sequence — Oracle/PostgreSQL 首選

原理:調用數據庫 SEQUENCE 對象(seq_name.NEXTVAL)。Hibernate 默認查找 hibernate_sequence,建議顯式指定:

<generator class="sequence">
  <param name="sequence">MY_SEQ</param>
</generator>

優點:支持批量獲取 ID(配合 allocationSize)、高併發性能優異。
缺點:MySQL/SQL Server 不支持;需額外創建 Sequence 對象。

3. native — 跨數據庫通用首選

原理:根據 dialect 自動選擇:MySQL/SQL Server → identity;Oracle/PostgreSQL → sequence;其他 → hilo。

優點:一套映射文件適配多種數據庫,遷移極其方便。
注意:若使用 Sequence/HiLo,所有表共享同一 Sequence/表,可能成為熱點。

4. uuid.hex — 去中心化、極致移植性

原理:128-bit UUID(IP + JVM 啟動時間 + 系統時間 + 計數器),編碼為 32 位十六進制字符串。完全在 JVM 內生成,無任何數據庫交互。

優點:絕對唯一、無鎖競爭、分庫分表、微服務架構下最佳選擇。
缺點:主鍵長度 32 字符,索引體積大、範圍查詢無序、不利於人工閱讀。

5. hilo / seqhilo — 高性能批量生成

原理:Hi/Lo 算法將 ID 拆分為「高位(數據庫)」+「低位(內存)」。
hilo 需建表 hibernate_unique_key(next_hi INT);
seqhilo 則用 Sequence 提供高位。
每次從數據庫取一個高位值,內存中可生成 max_lo(默認 32768)個 ID,極大減少數據庫往返。

適用場景:極高併發寫入、跨數據庫遷移但不想用 UUID。現代架構較少直接使用,多被封裝在分布式 ID 生成器(Snowflake、Leaf)中。

6. assigned — 業務主鍵/自然鍵

應用層手動 entity.setId(value),Hibernate 不再干預。強烈不推薦用於代理主鍵,僅適用於業務主鍵(如身份證號、訂單號)且業務保證唯一性的場景。

7. foreign — 共享主鍵一對一

配合 <one-to-one constrained="true"> 使用,從表主鍵同時作為外鍵指向主表主鍵。典型場景:用戶表 User 与擴展信息表 UserProfile 共享 ID。

選型決策樹(生產環境建議)

  1. 微服務/分庫分表/極高併發 → uuid.hex 或 Snowflake 類分布式 ID。
  2. 單庫、MySQL/SQL Server、常規業務 → identity(簡單高效)。
  3. 單庫、Oracle/PostgreSQL、高併發批量寫入 → sequence(配合 allocationSize=50~100)。
  4. 多數據庫部署、不想維護多套映射 → native(最省心)。
  5. 業務主鍵(自然鍵) → assigned(但建議重構為代理鍵)。

性能與鎖競爭補充

  • identity 在極高併發下可能引發表級鎖/頁鎖爭用(MySQL 8.0+ 已優化)。
  • sequence 配合 CACHE 參數可大幅降低序列獲取開銷。
  • UUID 無鎖但索引分裂嚴重,InnoDB 建議配合 UUID_TO_BIN/BIN_TO_UUID (MySQL 8.0) 或有序 UUID(COMB)優化。

總結:沒有銀彈,只有場景最優解。理解各策略底層機制,結合數據庫特性、併發量、遷移需求、團隊技術棧綜合決策,才是架構師的正確姿勢。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved