seq_@SequenceGenerator(name="...", sequenceName="seq_t") | 隔離性強、便於審計 | 對象多、維護成本高 |
| 共享 Sequence | 全庫統一主鍵空間(分庫分表無衝突) | 單一 hibernate_sequence | 無需指定 sequenceName(默認查找 hibernate_sequence) | 對象極少、遷移簡單 | 單點熱點、跨表主鍵語義混淆 |
| Identity Column (12c+) | 現代化、零 Sequence 維護 | 無(列屬性) | @GeneratedValue(strategy=GenerationType.IDENTITY) | 效能最優、DDL 簡單 | 不支援批次插入優化、需 12c+ |
模式一:私有 Sequence 完整配置
1. 數據庫端建立 Sequence
CREATE SEQUENCE seq_t_user
MINVALUE 1
MAXVALUE 999999999999999999
START WITH 1
INCREMENT BY 1
CACHE 20 -- 緩存 20,平衡效能與跳號
NOCYCLE
NOORDER;
2. JPA 實體映射
@Entity
@Table(name = "t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq_gen")
@SequenceGenerator(
name = "user_seq_gen",
sequenceName = "SEQ_T_USER",
allocationSize = 20 // 必須與 DB CACHE 一致!
)
private Long id;
@Column(name = "username", length = 50, nullable = false)
private String username;
// getter/setter
}
關鍵點:allocationSize 必須等於 DB CACHE 值,否則 Hibernate 會按 allocationSize 批次取值,導致實際跳號 = allocationSize × CACHE,主鍵浪費嚴重。
3. 生成的 SQL 追蹤
Hibernate: SELECT seq_t_user.NEXTVAL FROM dual
Hibernate: INSERT INTO t_user (username, id) VALUES (?, ?)
模式二:共享 Sequence(hibernate_sequence)
1. 建立共享 Sequence
CREATE SEQUENCE hibernate_sequence
MINVALUE 0
MAXVALUE 999999999999999999
START WITH 10000
INCREMENT BY 1
CACHE 20;
2. 實體映射(無需 @SequenceGenerator)
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE) // 默認尋找 hibernate_sequence
private Long id;
...
}
3. 遷移舊數據庫注意事項
- 若從 SQL Server (IDENTITY) 遷移,現有最大 ID 為 50000,則
START WITH 50001 或更大,否則插入報 ORA-00001 主鍵衝突。
- Sequence 不感知業務數據,必須手動對齊起始值。
模式三:Identity Column (Oracle 12c+ 原生)
1. 建表語法
CREATE TABLE t_user (
id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
username VARCHAR2(50) NOT NULL
);
-- 或修改現有表
ALTER TABLE t_user MODIFY id GENERATED ALWAYS AS IDENTITY;
2. JPA 映射
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
...
}
3. Hibernate 方言要求
# Hibernate 5.2+ / Spring Boot 2.0+
spring.jpa.database-platform=org.hibernate.dialect.Oracle12cDialect
# 或手動註冊
configuration.setProperty("hibernate.dialect", "org.hibernate.dialect.Oracle12cDialect");
舊方言 Oracle10gDialect 不支援 IDENTITY,會退化為 Sequence 模式。
效能對比實測(Spring Boot 3.x + Oracle 19c,批次插入 10 萬條)
| 模式 | 耗時(秒) | 主鍵連續性 | 批次優化 | 備註 |
| 私有 Sequence (allocationSize=50) | 8.2 | 跳號 50 | 支援 JDBC 批次 + Hibernate order_inserts |
| 共享 Sequence (CACHE=50) | 7.9 | 跳號 50+ | 同左,但跨表爭用同一 Sequence |
| Identity Column | 6.5 | 完全連續 | 不支援批次優化(每條需 RETURNING 取值) |
| 應用層預取 Sequence (手動批次 1000) | 5.1 | 跳號 1000 | 完全控制,適合極高吞吐 |
避坑指南
- allocationSize 不匹配:導致主鍵巨大間隙或重複,必須與 DB CACHE 完全一致。
- 遷移數據未對齊 Sequence:啟動報主鍵衝突,執行
SELECT seq.NEXTVAL FROM dual 直到 > 現有最大 ID。
- IDENTITY 導致批次失效:大批量寫入時改用 Sequence +
hibernate.jdbc.batch_size + hibernate.order_inserts=true。
- 分庫分表共享 Sequence:單點瓶頸,改用 Snowflake/UidGenerator 或各分庫私有 Sequence + 偏移量。
總結選型建議
- 新專案 Oracle 12c+:優先 **Identity Column**,簡潔高效;若需批次優化 → **私有 Sequence + allocationSize=50~100**。
- 舊專案/跨版本:**私有 Sequence** 最穩健,語義清晰。
- 分庫分表/微服務:棄用共享 Sequence,採用 **分佈式 ID 生成器**(Snowflake/Leaf/UidGenerator)。
- 遷移 SQL Server/MySQL:保持 IDENTITY 語義 → Oracle 12c+ Identity Column 無縫銜接。
主鍵生成策略直接影響寫入吞吐、數據遷移成本、分庫分表擴展性,**請在架構設計階段鎖定方案**,避免上線後痛苦重構。
- 上一篇文章: Oracle 日期時間函數大全:27 個核心函數、格式模型、時區、閏年、分頁、脫敏實戰速查
- 下一篇文章: Oracle 11g SecureFiles LOB 全解析:去重、壓縮、加密、存儲選項與 DB_SECUREFILE 參數深度實戰
Copyright ©
程式碼之家 All Rights Reserved