Spanner序列 #

一、序列概述 #

1.1 什么是序列 #

序列(Sequence)是Spanner提供的自增数字生成器,用于生成唯一标识符。

text
序列特点:
├── 生成唯一数字
├── 支持位反转
├── 高性能
├── 分布式友好
└── 避免热点问题

1.2 序列类型 #

text
序列类型:
├── 普通序列
│   ├── 顺序递增
│   └── 可能产生热点
│
└── 位反转序列
    ├── 随机分布
    └── 避免热点问题

二、创建序列 #

2.1 基本语法 #

sql
CREATE SEQUENCE sequence_name
[OPTIONS (sequence_kind = 'kind')];

2.2 创建普通序列 #

sql
-- 创建普通序列
CREATE SEQUENCE user_seq;

-- 使用序列
INSERT INTO users (user_id, name)
VALUES (NEXTVAL('user_seq'), 'John Doe');

-- 获取下一个值
SELECT NEXTVAL('user_seq') AS next_id;

-- 获取当前值(不消耗)
SELECT CURRVAL('user_seq') AS current_id;

2.3 创建位反转序列 #

sql
-- 创建位反转序列
CREATE SEQUENCE user_bit_seq
OPTIONS (sequence_kind = 'bit_reversed_positive');

-- 位反转序列生成的ID分布更均匀
-- 避免写入热点

-- 使用位反转序列
INSERT INTO users (user_id, name)
VALUES (GET_NEXT_SEQUENCE_VALUE(SEQUENCE user_bit_seq), 'John Doe');

2.4 序列选项 #

sql
-- 序列选项
CREATE SEQUENCE custom_seq
OPTIONS (
    sequence_kind = 'bit_reversed_positive',
    skip_range_min = 1,
    skip_range_max = 1000
);

-- skip_range: 跳过指定范围的值

三、使用序列 #

3.1 在INSERT中使用 #

sql
-- 创建表
CREATE TABLE users (
    user_id INT64 NOT NULL DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE user_seq)),
    name STRING(100) NOT NULL
) PRIMARY KEY (user_id);

-- 插入数据(自动生成ID)
INSERT INTO users (name) VALUES ('John Doe');
INSERT INTO users (name) VALUES ('Jane Doe');

-- 查询结果
SELECT * FROM users;
-- user_id: 1, name: 'John Doe'
-- user_id: 2, name: 'Jane Doe'

3.2 在DEFAULT中使用 #

sql
-- 创建带默认序列值的表
CREATE TABLE orders (
    order_id INT64 NOT NULL 
        DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE order_seq)),
    user_id INT64 NOT NULL,
    amount FLOAT64
) PRIMARY KEY (order_id);

-- 插入数据
INSERT INTO orders (user_id, amount) VALUES (1, 100.0);

3.3 获取序列值 #

sql
-- 获取下一个值
SELECT NEXTVAL('user_seq') AS next_id;

-- 获取当前值(不消耗)
SELECT CURRVAL('user_seq') AS current_id;

-- 在事务中使用
BEGIN TRANSACTION;
SELECT NEXTVAL('user_seq') AS new_id;
INSERT INTO users (user_id, name) VALUES (new_id, 'Test');
COMMIT;

四、位反转序列 #

4.1 位反转原理 #

text
位反转原理:
├── 原始值: 1, 2, 3, 4, 5, 6, 7, 8
├── 反转后: 1, 3, 5, 7, 2, 4, 6, 8
├── 分布更均匀
└── 避免热点问题

4.2 创建位反转序列 #

sql
-- 创建位反转序列
CREATE SEQUENCE user_bit_seq
OPTIONS (sequence_kind = 'bit_reversed_positive');

-- 使用位反转序列
CREATE TABLE users (
    user_id INT64 NOT NULL 
        DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE user_bit_seq)),
    name STRING(100)
) PRIMARY KEY (user_id);

4.3 位反转优势 #

text
位反转序列优势:
├── 避免写入热点
├── 数据分布均匀
├── 提高写入性能
├── 适合分布式场景
└── 仍然保证唯一性

五、序列管理 #

5.1 查看序列 #

sql
-- 查看所有序列
SELECT * FROM INFORMATION_SCHEMA.SEQUENCES;

-- 查看序列详情
SELECT 
    sequence_name,
    sequence_kind,
    is_generated
FROM INFORMATION_SCHEMA.SEQUENCES
WHERE sequence_name = 'user_seq';

5.2 修改序列 #

sql
-- Spanner不支持ALTER SEQUENCE
-- 需要删除重建

-- 删除序列
DROP SEQUENCE user_seq;

-- 重新创建
CREATE SEQUENCE user_seq
OPTIONS (sequence_kind = 'bit_reversed_positive');

5.3 删除序列 #

sql
-- 删除序列
DROP SEQUENCE user_seq;

-- 如果存在则删除
DROP SEQUENCE IF EXISTS user_seq;

-- 注意: 如果序列被表使用,需要先修改表

六、序列性能 #

6.1 性能考虑 #

text
序列性能因素:
├── 序列类型: 位反转更优
├── 并发访问: 高性能
├── 网络延迟: 影响获取速度
└── 缓存大小: 影响吞吐量

6.2 性能优化 #

text
序列性能优化:
├── 使用位反转序列
├── 批量获取序列值
├── 使用DEFAULT减少调用
├── 避免频繁获取单个值
└── 监控序列使用情况

6.3 批量获取 #

java
// Java批量获取序列值
import com.google.cloud.spanner.DatabaseClient;
import com.google.cloud.spanner.Statement;

DatabaseClient client = spanner.getDatabaseClient(databaseId);

// 批量获取
for (int i = 0; i < 1000; i++) {
    long id = client.singleUse()
        .executeQuery(Statement.of("SELECT NEXTVAL('user_seq')"))
        .next()
        .getLong(0);
    // 使用id
}

七、序列最佳实践 #

7.1 选择序列类型 #

text
序列类型选择:
├── 单区域小规模: 普通序列
├── 多区域大规模: 位反转序列
├── 高写入场景: 位反转序列
└── 需要有序ID: 普通序列

7.2 设计建议 #

text
序列设计建议:
├── 使用位反转避免热点
├── 使用DEFAULT简化代码
├── 合理命名序列
├── 监控序列使用
└── 规划序列数量

7.3 使用建议 #

text
序列使用建议:
├── 使用GET_NEXT_SEQUENCE_VALUE
├── 避免频繁获取单个值
├── 使用DEFAULT自动生成
├── 处理序列耗尽情况
└── 监控序列状态

八、总结 #

序列类型对比:

类型 特点 使用场景
普通序列 顺序递增 小规模、需要有序
位反转序列 随机分布 大规模、高写入

最佳实践:

text
1. 选择合适的序列类型
   └── 根据场景选择

2. 使用位反转序列
   └── 避免热点问题

3. 使用DEFAULT简化
   └── 自动生成ID

4. 监控序列使用
   └── 及时发现问题

5. 规划序列数量
   └── 避免过多序列

下一步,让我们学习用户权限管理!

最后更新:2026-03-27