当前位置: 首页 > news >正文

数据库序列(Sequence)

数据库序列(Sequence)是一种生成唯一整数序列对象,主要用于自动生成主键值唯一标识符

核心概念

序列是一个数据库对象,按照指定的规则(起始值、增量、最大值等)生成一系列唯一的整数。每次调用序列时,都会返回下一个值。

主要特点

1. 唯一性保证
序列生成的每个值都是唯一的
即使在高并发环境下也能保证不重复
2. 独立性
序列独立于表存在,可以被多个表共享
不依赖于事务,即使事务回滚,序列值也不会回退
3. 可配置性
起始值(START WITH)
增量(INCREMENT BY)
最小值/最大值(MINVALUE/MAXVALUE)
是否循环(CYCLE/NOCYCLE)
缓存大小(CACHE)

不同数据库的实现

Oracle

-- 创建序列 CREATE SEQUENCE user_seq START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE; -- 使用序列 INSERT INTO users (id, name) VALUES (user_seq.NEXTVAL, '张三'); SELECT user_seq.CURRVAL FROM dual; -- 查看当前值

PostgreSQL

-- 创建序列 CREATE SEQUENCE order_id_seq START WITH 1000 INCREMENT BY 1; -- 使用序列 INSERT INTO orders (id, amount) VALUES (nextval('order_id_seq'), 100.00); -- 或者在表中直接使用 CREATE TABLE products ( id SERIAL PRIMARY KEY, -- 自动创建序列 name VARCHAR(100) );

SQL Server

-- 创建序列 CREATE SEQUENCE employee_seq AS INT START WITH 1 INCREMENT BY 1; -- 使用序列 INSERT INTO employees (id, name) VALUES (NEXT VALUE FOR employee_seq, '李四');

MySQL

MySQL 没有原生的序列对象,但可以通过以下方式实现:

方式1: AUTO_INCREMENT(最常用)

CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) );

方式2: 模拟序列

CREATE TABLE sequence_table ( seq_name VARCHAR(50) PRIMARY KEY, current_value INT ); -- 获取下一个值 UPDATE sequence_table SET current_value = LAST_INSERT_ID(current_value + 1) WHERE seq_name = 'user_seq'; SELECT LAST_INSERT_ID();

序列 vs 自增主键

注意事项

⚠️序列值不连续的情况
事务回滚后,已使用的序列值不会回收
数据库重启可能导致缓存的序列值丢失
高并发下可能出现跳号
⚠️性能考虑
使用CACHE可以提高性能(减少磁盘I/O)
但缓存越大,数据库重启时丢失的序列值越多

序列和索引

序列(Sequence)和索引(Index)是数据库中两个完全不同的概念,它们的用途、工作原理和使用场景都有本质区别。

核心区别对比

详细对比分析

1. 功能目的不同

序列:生成唯一值

-- 创建序列用于生成主键 CREATE SEQUENCE user_id_seq START WITH 1 INCREMENT BY 1; -- 使用序列生成唯一ID INSERT INTO users (id, name) VALUES (user_id_seq.NEXTVAL, '张三');

索引:加速查询

-- 在用户名字段上创建索引,加速查询 CREATE INDEX idx_user_name ON users(name); -- 查询时会使用索引加速 SELECT * FROM users WHERE name = '张三';

2. 工作原理不同

序列的工作方式:

序列内部维护一个计数器: 调用 NEXTVAL → 计数器 +1 → 返回新值 当前值: 100 → 调用 NEXTVAL → 返回 101,计数器更新为 101

索引的工作方式:

索引是数据的有序副本(以B+树为例): 原始数据: 索引结构: id | name B+树索引(idx_user_name) ---|-------- root: [李, 王, 张] 1 | 张三 / | \ 2 | 李四 李四 王五 张三,赵六 3 | 王五 ↑ 4 | 赵六 查询"张三"时,通过树快速定位 查询 "WHERE name='张三'" → 遍历B+树(3层) → 直接定位到数据 → 无需全表扫描

3. 使用场景不同

序列的典型场景:

-- 场景1: 主键自动生成 CREATE TABLE orders ( id NUMBER PRIMARY KEY, order_no VARCHAR2(50), amount NUMBER ); INSERT INTO orders (id, order_no, amount) VALUES (order_seq.NEXTVAL, 'ORD20260506001', 1000); -- 场景2: 订单号生成 SELECT 'ORD' || TO_CHAR(SYSDATE, 'YYYYMMDD') || LPAD(order_seq.NEXTVAL, 8, '0') as order_no FROM dual; -- 结果: ORD2026050600000001 -- 场景3: 多表共享ID生成器 INSERT INTO table_a (id) VALUES (common_seq.NEXTVAL); INSERT INTO table_b (id) VALUES (common_seq.NEXTVAL); -- 保证跨表的ID唯一性

索引的典型场景:

-- 场景1: 加速 WHERE 条件查询 CREATE INDEX idx_email ON users(email); SELECT * FROM users WHERE email = 'test@example.com'; -- 快速定位 -- 场景2: 加速 ORDER BY 排序 CREATE INDEX idx_create_time ON orders(create_time); SELECT * FROM orders ORDER BY create_time DESC; -- 利用索引顺序 -- 场景3: 加速 JOIN 连接 CREATE INDEX idx_order_user_id ON orders(user_id); SELECT u.name, o.order_no FROM users u JOIN orders o ON u.id = o.user_id; -- 连接时使用索引 -- 场景4: 唯一性约束 CREATE UNIQUE INDEX idx_unique_phone ON users(phone); -- 既加速查询,又保证唯一性

4. 性能影响不同

序列的性能特点:

// 序列几乎不影响性能 // INSERT 操作:只是获取一个数字,开销极小 Long id = sequenceGenerator.nextValue(); // 内存操作,非常快 insertUser(id, "张三");

✅ 读取:NEXTVAL 操作非常快(尤其是使用 CACHE 时)
✅ 写入:不增加额外的写入开销
⚠️ 并发:高并发下可能成为瓶颈(可通过 CACHE 优化)

索引的性能特点:

-- 查询性能提升明显 -- 无索引: 全表扫描 1000万条记录 → 耗时 5秒 SELECT * FROM users WHERE phone = '13800138000'; -- 有索引: B+树查找只需3-4次I/O → 耗时 5毫秒 CREATE INDEX idx_phone ON users(phone); SELECT * FROM users WHERE phone = '13800138000'; -- 但写入性能下降 INSERT INTO users (...) VALUES (...); -- 需要同时更新数据和所有相关索引

✅ 查询:大幅提升 SELECT 性能
❌ 写入:每次 INSERT/UPDATE/DELETE 都要维护索引,降低写入性能
⚠️ 存储:索引占用额外的磁盘空间

5. 维护成本不同

序列的维护:

-- 几乎不需要维护 -- 查看序列状态 SELECT sequence_name, last_number, cache_size FROM user_sequences WHERE sequence_name = 'USER_ID_SEQ'; -- 修改序列(很少需要) ALTER SEQUENCE user_id_seq INCREMENT BY 2;

索引的维护:

-- 需要定期维护 -- 重建索引(碎片整理) ALTER INDEX idx_user_name REBUILD; -- 分析索引使用情况 SELECT index_name, leaf_blocks, distinct_keys FROM user_indexes WHERE table_name = 'USERS'; -- 删除无用索引(减少写入开销) DROP INDEX idx_unused_column;

总结

http://www.jsqmd.com/news/773201/

相关文章:

  • 工业级蓝光三维扫描仪在孔位与3D尺寸测量的应用
  • 开源合规风险暴涨300%?AISMM模型如何在72小时内重构企业开源决策中枢,
  • 第31篇:Vibe Coding时代:LangGraph + Celery 后台任务实战,解决 Agent 长任务阻塞接口和服务超时问题
  • 开发者在多模型间切换时如何利用Taotoken保持API调用统一
  • 拯救程序员双眼:Spyder深色模式终极配置指南(2026新版)
  • Flutter+开源鸿蒙实战|校园易生活Day4 闲置详情页开发+路由传参+大图轮播+收藏功能+新手避坑
  • 基于人工智能优化算法的宽带多频功率放大器【附代码】
  • 【内含安装包】ArcGIS 10.8安装包速领:中文版详细安装步骤
  • 5个技巧让你轻松下载快手无水印视频:KS-Downloader完全指南
  • 别再只盯着main函数了!手把手带你用MAP文件分析STM32启动文件(startup_stm32xxx.s)的内存占用
  • 自由调音:FxSound音效调节功能详解
  • 如何快速使用Manga OCR:日语漫画文字识别的终极指南
  • Matlab画图进阶:除了Location,用这些技巧让你的图例更专业(2024版)
  • 【2026奇点智能技术大会权威解码】:AISMM框架落地的3大文化断层与组织级修复指南
  • Grok赋能OpenClaw:智能机器人抓取系统的AI感知与决策实践
  • 逻辑中涉及到了簇(Cluster)、簇转数组以及数组元素“或”操作,这说明在 LabVIEW 中你是在通过逻辑运算判断这 6 个故障字中是否有任意一个不为 0
  • 初创团队如何利用Taotoken实现多模型API的成本可控与灵活选型
  • 告别截图转文字:用Python的pytesseract+OpenCV搞定图片里的表格和复杂排版
  • 远程终端管理平台XTerminal 有点牛逼!!!一款颜值、功能都很能打的 SSH 客户端工具,支持Linux、Windows、MacOS
  • 2025届学术党必备的十大AI写作网站横评
  • 通过 curl 命令快速测试 taotoken 提供的各种大模型接口
  • 从用量看板分析Taotoken如何帮助团队实现API成本透明化
  • 面向平面任务的机器人最优轨迹规划逆运动学【附代码】
  • 大段文本转Excel(通过HTML直接排版,一键下载Excel)
  • 手机端内核刷入的革命性突破:告别电脑的终极解决方案
  • 月涨粉5000+,“银发网红”速成课正在成为一门好生意?
  • 一键永久备份QQ空间:GetQzonehistory完整指南与使用教程
  • 2026届毕业生推荐的AI辅助论文工具横评
  • AISMM模型赋能行业联盟建设(国家级试点白皮书首次解密)
  • Windows热键冲突终极解决方案:Hotkey Detective深度解析