本页面讨论了在 使用默认值表达式创建表。这些策略具有以下特点 好处:
- 防止出现热点
- 简化来自其他数据库的迁移
- 将关键逻辑封装在数据库中,这样您就不必担心 如何在应用中管理它
您可以在包含 DEFAULT
表达式的列中使用以下策略:
- 一个 UUID 函数,用于生成 UUID 版本 4 的值。
- 具有
bit_reversed_positive
的架构对象SEQUENCE
选项。SEQUENCE
适用于 GoogleSQL 和 PostgreSQL。
自动生成主键的方法
通用唯一标识符 (UUID)
Spanner 可以自动生成 UUID 版本 4 字符串 用作主键。UUID 非常适合 多行。它们大致均匀分布在键空间中, 以防止出现大规模热点。UUID 生成大量的值 (2122), 实际上每个值都是唯一的例如,您需要 2.71×1018 值表示冲突概率为 50%,或 每秒 10 亿次,持续 86 年。这可确保在 大型表格。无论您是在数据库中生成 UUID,还是在 客户端。我们建议您尽可能使用 UUID。你可以放心 包含客户端和 Spanner 生成的 UUID, 客户端生成的 UUID 会按照以下规则序列化为小写 RFC 4122。
对于需要默认值的列,您可以使用 GENERATE_UUID
函数来生成它们。以下示例展示了如何创建
一个表,其中“FanId
”键列的值包含 GENERATE_UUID
列作为其默认值。此示例中的 GoogleSQL 使用 36 个字符
STRING
和 PostgreSQL varchar
属性,因为 UUID 具有 36 个字符。
当您使用 INSERT with THEN RETURN
语句插入到
Fans
表中,GENERATE_UUID
会为 FanId
生成并返回 UUID 值。
GoogleSQL
CREATE TABLE Fans (
FanId STRING(36) DEFAULT (GENERATE_UUID()),
Name STRING(MAX),
) PRIMARY KEY (FanId);
PostgreSQL
CREATE TABLE Fans (
FanId varchar(36) DEFAULT spanner.generate_uuid(),
Name text,
PRIMARY KEY (FanId)
);
GoogleSQL
INSERT INTO Fans (Name) VALUES ('Melissa Garcia')
THEN RETURN FanId;
PostgreSQL
INSERT INTO fans (name) VALUES ('Melissa Garcia')
RETURNING (fanid);
此语句会返回类似于以下内容的结果:
FanId |
---|
6af91072-f009-4c15-8c42-ebe38ae83751 |
如需详细了解 GENERATE_UUID()
函数,请参阅 GoogleSQL
或 PostgreSQL 参考页面。
位反转序列
位倒序序列是一种架构对象,可生成一系列 并对它们进行位反转。此对象会对私有文件使用位反转, 内部 Spanner 计数器以确保唯一性。生成的 位倒序值 有助于避免在主键中使用时产生大规模热点。
在 Spanner 中,您使用 SEQUENCE
DDL 语句以及
bit_reversed_positive
属性来创建、修改或删除
产生位反正正值的序列(GoogleSQL 或
PostgreSQL)。
每个序列都会维护一组内部计数器,并使用这些计数器生成 值。序列计数器提供位反转算法的输入。
通过使用 GoogleSQL 的 DEFAULT
表达式定义列时
GET-NEXT-SEQUENCE-VALUE
或
PostgreSQL nextval
函数作为其默认值,Spanner
自动调用函数,并将位反转的输出值
。位反转序列对于主键特别有用,
因为位反转值均匀分布在键中
以免造成热点
以下示例展示了如何创建位反序序列和表 其中,其键列使用序列作为默认值:
GoogleSQL
CREATE SEQUENCE SingerIdSequence OPTIONS (
sequence_kind="bit_reversed_positive"
);
CREATE TABLE Singers (
SingerId INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE SingerIdSequence)),
Name STRING(MAX),
Rank INT64,
) PRIMARY KEY (SingerId);
PostgreSQL
CREATE SEQUENCE SingerIdSequence bit_reversed_positive;
CREATE TABLE Singers (
SingerId bigint DEFAULT nextval('SingerIdSequence'),
Name text,
PRIMARY KEY (SingerId)
);
然后,您可以使用以下 SQL 语句插入并返回主 键值:
GoogleSQL
INSERT INTO Singers (Name) VALUES ('Melissa Garcia')
THEN RETURN SingerId;
PostgreSQL
INSERT INTO Singers (name) VALUES ('Melissa Garcia')
RETURNING (SingerId);
此语句会返回类似于以下内容的结果:
SingerId |
---|
3458764513820540928 |
将 UUID 和序列用作主键默认值的场景
UUID 和序列的情况包括:
- 新应用
- 迁移
以下部分介绍了每种情况。
新应用
如果您的现有应用需要在 GoogleSQL 中拥有 INT64
密钥,或者 bigint
密钥,Spanner 提供反转正数,
序列架构对象(PostgreSQL 或 GoogleSQL)。否则,对于新的
建议您使用
通用唯一标识符 (UUID)。对于
如需了解详情,请参阅使用通用唯一标识符 (UUID)。
迁移
要将表迁移到 Spanner,您有以下几种选择:
- 如果您在源数据库中使用 UUID,则在 Spanner 上,
您可以使用
STRING
类型的键列和GENERATE_UUID()
函数(GoogleSQL 或 PostgreSQL)作为其默认值。 - 如果您使用的是整数主键,并且您的应用只需要
键是唯一的,则可以在
INT64
中使用键列,并使用 为主键默认值的正序列。 请参阅迁移位反转键列。 Spanner 不支持生成单调值的方法。
如果您使用的是单调键(例如 PostgreSQL
SERIAL
类型),或者 MySQLAUTO_INCREMENT
属性,并且您需要新的单调键 Spanner 中,您可以使用复合键。请参阅 交换键的顺序和对唯一键进行哈希处理,并将写入分布到逻辑分片中。如果您的应用在 GoogleSQL 中手动对
INT64
密钥进行位反转 或bigint
键,则可以使用位反转正序列 (GoogleSQL 或 PostgreSQL),并让它针对 。请参阅迁移位反转键列。
后续步骤
- 详细了解如何使用序列实现精细的访问权限控制。
- 了解适用于 GoogleSQL 或 PostgreSQL 的 DDL
SEQUENCE
语句。 - 了解 GoogleSQL 或 PostgreSQL 中的序列函数。
- 了解 GoogleSQL 中的 INFORMATION_SCHEMA 中的序列或 PostgreSQL。
- 了解适用于 GoogleSQL 的 INFORMATION_SCHEMA 中的序列选项。