🐈

SpannerのIDENTITYカラムを試す

2024/12/15に公開

はじめに

SpannerにはUUIDv4をデフォルト値としてセットする機能が以前からありました。

CREATE TABLE Users (
    UserID STRING(36) DEFAULT (GENERATE_UUID()),
    Name STRING(MAX),
) PRIMARY KEY (UserID);
$ spanner-cli -e "INSERT INTO Users (Name) VALUES ('meow1');"
$ spanner-cli -e "INSERT INTO Users (Name) VALUES ('meow2');"
$ spanner-cli -e "INSERT INTO Users (Name) VALUES ('meow3');"
$ spanner-cli -e "SELECT * FROM Users;"
UserID  Name
603b703b-803d-4702-93ab-8c29f6aac597    meow1
d1c41809-58da-4541-b471-316efd33b2c8    meow2
7f39d6a5-62af-4a34-829e-f4d31dff30e7    meow3

2024/12/12のリリースでIDENTITYカラムが追加され整数値もセットできるようになったので試します。
https://cloud.google.com/spanner/docs/release-notes#December_12_2024

スキーマ

以前はイチイチ別に CREATE SEQUENCE DDLでシーケンスカウンターを用意する必要がありましたが、Spanner側で全部やってくれるようになったのでスッキリしています。

CREATE TABLE Items (
    ItemID INT64 GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
    Name STRING(MAX),
) PRIMARY KEY (ItemID);

動作確認

適当に3行INSERTしてみましょう。

$ spanner-cli -e "INSERT INTO Items (Name) VALUES ('meow1');"
$ spanner-cli -e "INSERT INTO Items (Name) VALUES ('meow2');"
$ spanner-cli -e "INSERT INTO Items (Name) VALUES ('meow3');"
$ spanner-cli -e "SELECT * FROM Items;"
ItemID  Name
2305843009213693952     meow1
5764607523034234880     meow2
576460752303423488      meow3

ItemIDを指定していないのでデフォルト値としてSpanner側で採番した値が入りました。なおPrimaryKey以外のカラムでも使用できます。

開始番の指定

以下のようにするとシーケンスカウンターの先頭番号を指定できます。但し連番でインクリメントされるとは限らないので、実際に生成していくと大小関係は保ちつつも歯抜けになります。

CREATE TABLE Items (
    ItemID INT64 GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE START COUNTER WITH 100),
    Name STRING(MAX),
) PRIMARY KEY (ItemID);
$ spanner-cli -e "SELECT * FROM Items;"
ItemID  Name
3674937295934324736     meow1
5404319552844595200     meow2
1945555039024054272     meow3
$ spanner-cli -e "SELECT BIT_REVERSE(3674937295934324736, true);"
102
$ spanner-cli -e "SELECT BIT_REVERSE(5404319552844595200, true);"
105
$ spanner-cli -e "SELECT BIT_REVERSE(1945555039024054272, true);"
108

おわりに

既存で自前生成している部分があるとID生成方法が混ざってしまうのが難点。新規の時は是非使いたいですね。

Discussion