このページでは、デフォルト値の式を使用してテーブル内の主キー値を生成する方法について説明します。これらの戦略には、次の利点があります。
- ホットスポット化を防止する
- 他のデータベースからの移行を簡素化する
- キーロジックをデータベースにカプセル化し、アプリケーション内での管理について懸念する必要がないようにする
DEFAULT
式を含む列では、次の戦略を使用できます。
- UUID バージョン 4 の値を生成する UUID 関数。
bit_reversed_positive
オプションを持つスキーマ オブジェクトSEQUENCE
。SEQUENCE
は Google SQL と PostgreSQL の両方で使用できます。
主キーを自動的に生成する方法
Universally Unique Identifier(UUID)
Spanner は、主キーとして使用する UUID バージョン 4 の文字列を自動的に生成できます。UUID は、多数の行がある新しいアプリケーションやテーブルで適切に機能します。これらはキー空間全体にほぼ均一に分散されるため、大規模なホットスポット化を防止できます。UUID の生成では非常に多くの値(2122)が生成され、各値は実質的に一意です。たとえば、50% の衝突確率では 2.71×1018、86 年間では 1 秒あたり 10 億が必要です。これにより、大きなテーブルで使用するときに一意の値が確保されます。UUID は、データベースとクライアントのどちらで生成するかに関係なく、一意です。可能であれば、UUID を使用することをおすすめします。クライアントが生成した UUID が RFC 4122 に従って小文字としてシリアル化されている場合は、クライアントで生成された UUID と Spanner で生成された UUID を同じテーブルに安全に混在させることができます。
デフォルト値が必要な列の場合は、GENERATE_UUID
関数を使用して生成できます。次の例は、FanId
キー列の値列のデフォルト値として GENERATE_UUID
を持つテーブルを作成する方法を示しています。この例では、UUID は 36 文字であるため、GoogleSQL の STRING
属性と PostgreSQL の varchar
属性に 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 では、bit_reversed_positive
属性とともに SEQUENCE
DDL ステートメントを使用して、ビット反転した正の値(GoogleSQL、または PostgreSQL)を生成するシーケンスを作成、変更、または削除します。
各シーケンスは一連の内部カウンタを保持し、値を生成するために使用します。シーケンス カウンタは、ビット反転アルゴリズムへの入力を可能にします。
GoogleSQL GET-NEXT-SEQUENCE-VALUE
関数または PostgreSQL nextval
関数をデフォルト値として使用する DEFAULT
式を含む列を定義すると、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
キーまたは PostgreSQL の bigint
キーが必要な場合、Spanner はビット反転した正のシーケンス スキーマ オブジェクト(PostgreSQL または GoogleSQL)を提供します。それ以外の場合は、新しいアプリケーションの場合は、Universally Unique Identifier(UUID)を使用することをおすすめします。詳細については、Universally Unique Identifier(UUID)を使用するをご覧ください。
移行
Spanner にテーブルを移行する場合は、いくつかのオプションがあります。
- ソース データベースで UUID を使用している場合、Spanner では
STRING
型のキー列とGENERATE_UUID()
関数(GoogleSQL または PostgreSQL)をデフォルト値として使用できます。 - 整数の主キーを使用しており、アプリケーションが一意のキーのみを必要とする場合は、
INT64
でキー列を使用し、ビット反転した正のシーケンスを主キーのデフォルト値として使用できます。ビット反転キー列の移行をご覧ください。 Spanner は単調な値を生成する方法をサポートしていません。
PostgreSQL
SERIAL
タイプや MySQLAUTO_INCREMENT
属性などの単調なキーを使用しており、Spanner で新しい単調なキーが必要な場合は、複合キーを使用できます。キーの順序を入れ替えると一意キーをハッシュして、論理シャード間に書き込みを分散するをご覧ください。アプリケーションで GoogleSQL の
INT64
キーまたは PostgreSQL のbigint
キーを手動でビット反転する場合は、ビット反転した正のシーケンス(GoogleSQL またはPostgreSQL)を使用して、新しいキー値を生成できます。ビット反転キー列の移行をご覧ください。
次のステップ
- きめ細かいアクセス制御によるシーケンスの使用について詳細を確認する。
- GoogleSQL または PostgreSQL の DDL
SEQUENCE
ステートメントについて確認する。 - GoogleSQL または PostgreSQL のシーケンス関数について確認する。
- GoogleSQL または PostgreSQL の INFORMATION_SCHEMA 内のシーケンスについて確認する。
- GoogleSQL の INFORMATION_SCHEMA のシーケンス オプションについて確認する。