このページでは、デフォルト値の式を使用してテーブル内の主キー値を生成する方法について説明します。このページの情報は、GoogleSQL 言語データベースと PostgreSQL 言語データベースの両方に適用されます。これらの戦略には次のようなメリットがあります。
- ホットスポットを回避する
- 他のデータベースからの移行を簡素化する
- キーロジックをデータベースにカプセル化し、アプリケーション内での管理について懸念する必要がないようにする
- ほとんどの場合、独自のシーケンスを作成して管理する必要がなくなります
主キーを自動生成する方法
主キー値を自動生成するには、DEFAULT
式を含む列で次の戦略を使用します。
- UUID バージョン 4 の値を生成する UUID 関数。
bit_reversed_positive
オプションを持つスキーマ オブジェクトSEQUENCE
。SEQUENCE
は、GoogleSQL と PostgreSQL の両方で使用できます。
主キーを自動生成する方法
このセクションでは、主キー値として使用する UUID とビット反転シーケンスを自動的に生成する方法について説明します。
Universally Unique Identifier(UUID)
Spanner は、主キーとして使用する UUID バージョン 4 文字列を自動的に生成できます。UUID は、新しいアプリケーションや行数の多いテーブルに適しています。これらはキースペース全体にほぼ均一に分散されるため、大規模なホットスポット化を防止できます。UUID の生成では非常に多くの値(2122)が生成され、各値は実質的に一意です。たとえば、50% の衝突確率では 2.71×1018、86 年間では 1 秒あたり 10 億が必要です。これにより、大規模なテーブルで使用する場合に一意の値が確実に生成されます。UUID は、データベースで生成するかクライアントで生成するかにかかわらず一意です。可能であれば UUID を使用することをおすすめします。クライアントが生成した UUID が RFC 4122 に従って小文字でシリアル化されている場合、クライアントと 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 のリファレンス ページをご覧ください。
IDENTITY
列
IDENTITY
列を使用すると、キー列と非キー列の整数値を自動的に生成できます。IDENTITY
列では、ユーザーが基盤となるシーケンスを手動で維持したり、列と基盤となるシーケンスの関係を管理する必要はありません。自動生成された ID 列が削除されると、基盤となるシーケンスも自動的に削除されます。
IDENTITY
列を使用するには、シーケンスの生成時に開始の整数値を指定する方法と、Spanner に整数シーケンスを生成させる方法があります。開始の整数値を指定するには、START COUNTER WITH
オプションを使用して、正の INT64
開始値を使用する必要があります。Spanner は、この値を使用して自動生成された内部シーケンス カウンタの次の値を設定し、この列に挿入する前に値をビット反転します。
Spanner では、IDENTITY
列は GoogleSQL と PostgreSQL の両方でサポートされています。
GoogleSQL
次の例は、CREATE TABLE
コマンドを使用して新しいテーブルを作成するときに、IDENTITY
列を使用して SingerId
の自動生成整数の主キー列を作成する方法を示しています。
CREATE TABLE Singers (
SingerId INT64 GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
Name STRING(MAX),
Rank INT64
) PRIMARY KEY (SingerId);
START_WITH_COUNTER
オプションを使用して、列のカウンタの開始を指定することもできます。次の例では、ビット反転された正の値と 1,000 から始まる内部カウンタを持つ SingerId
に、自動生成された整数列が作成されます。
CREATE TABLE Singers (
SingerId INT64 GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE START COUNTER WITH 1000),
Name STRING(MAX),
Rank INT64
) PRIMARY KEY (SingerId);
PostgreSQL
次の例は、CREATE
TABLE
コマンドを使用して新しいテーブルを作成するときに、IDENTITY
列を使用して SingerId
の自動生成整数列を作成する方法を示しています。
CREATE TABLE Singers (
SingerId bigint GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
Name text,
PRIMARY KEY (SingerId)
);
START COUNTER WITH
オプションを使用して、列のカウンタの開始を指定することもできます。次の例では、ビット反転された正の値を生成する SingerId
に自動生成された整数列が作成されます。ビット反転前の内部カウンタは 1,000 から開始されます。
CREATE TABLE Singers (
SingerId bigint GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE START COUNTER WITH 1000),
Name text,
PRIMARY KEY (SingerId)
);
SERIAL と AUTO_INCREMENT
Spanner は、PostgreSQL の SERIAL
と GoogleSQL の AUTO_INCREMENT
をサポートしています。これらは IDENTITY 列の DDL エイリアスであり、一意の整数列の作成に使用されます。SERIAL
または AUTO_INCREMENT
を使用する前に、まずデータベースの default_sequence_kind
オプションを設定する必要があります。次の SQL ステートメントを使用して、データベースの default_squence_kind
オプションを設定できます。
GoogleSQL
ALTER DATABASE db SET OPTIONS (default_sequence_kind = 'bit_reversed_positive');
CREATE TABLE Singers (
id INT64 AUTO_INCREMENT PRIMARY KEY,
name STRING(MAX),
)
PostgreSQL
ALTER DATABASE db SET spanner.default_sequence_kind = 'bit_reversed_positive';
CREATE TABLE Singers (
id serial PRIMARY KEY,
name text
);
SERIAL
と AUTO_INCREMENT
は IDENTITY 列にマッピングされるため、スキーマをシリアル化するときには表示されません。このスキーマの場合、GetDatabaseDDL
の出力は次のようになります。
GoogleSQL
ALTER DATABASE db SET OPTIONS (default_sequence_kind = 'bit_reversed_positive');
CREATE TABLE Singers (
id INT64 GENERATED BY DEFAULT AS IDENTITY,
name STRING(MAX),
) PRIMARY KEY (id);
PostgreSQL
ALTER DATABASE db SET spanner.default_sequence_kind = 'bit_reversed_positive';
CREATE TABLE Singers (
id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
name character varying,
PRIMARY KEY(id)
);
ビット反転シーケンス
ビット反転シーケンスは、整数のシーケンスを生成してビット反転するスキーマ オブジェクトです。このオブジェクトは、一意であることを保証するために、非公開の内部 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 のシーケンス オプションについて確認する。