目標
このチュートリアルでは、Spanner PGAdapter ローカル プロキシを使用して PostgreSQL ドライバを実行する手順について説明します。
- Spanner のインスタンスとデータベースを作成します。
- データベースのデータに対し、書き込み、読み取り、SQL クエリの実行を行います。
- データベース スキーマを更新します。
- 読み取り / 書き込みトランザクションを使用してデータを更新します。
- セカンダリ インデックスをデータベースに追加します。
- インデックスを使用して、データの読み込みと SQL クエリの実行を行います。
- 読み取り専用トランザクションを使用してデータを取得します。
費用
このチュートリアルで使用する Spanner は、Google Cloud の有料コンポーネントです。Spanner を使用する際の料金については、料金をご覧ください。
始める前に
設定に示されている手順を完了します。この手順では、デフォルトの Google Cloud プロジェクトの作成と設定、課金の有効化、Cloud Spanner API の有効化、Cloud Spanner API の使用に必要な認証情報を取得するための OAuth 2.0 の設定について説明しています。
特に、ローカルの開発環境に認証情報を設定するために、必ず gcloud auth
application-default login
を実行してください。
ローカルの PGAdapter 環境を準備する
PostgreSQL ドライバを PGAdapter と組み合わせて使用して Spanner に接続することができます。PGAdapter は、PostgreSQL ネットワーク プロトコルを Spanner gRPC プロトコルに変換するローカル プロキシです。
PGAdapter を実行するには Java または Docker が必要です。
開発マシンに次のものがまだインストールされていない場合は、いずれか 1 つをインストールします。
ローカルマシンにサンプルアプリのリポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/pgadapter.git
Spanner のサンプルコードが含まれるディレクトリに移動します。
psql
cd pgadapter/samples/snippets/psql-snippets
Java
cd pgadapter/samples/snippets/java-snippets mvn package -DskipTests
Go
cd pgadapter/samples/snippets/golang-snippets
Node.js
cd pgadapter/samples/snippets/nodejs-snippets npm install
Python
cd pgadapter/samples/snippets/python-snippets python -m venv ./venv pip install -r requirements.txt cd samples
C#
cd pgadapter/samples/snippets/dotnet-snippets
インスタンスを作成する
Spanner を最初に使用する場合は、インスタンスを作成する必要があります。インスタンスとは、Spanner データベースによって使用されるリソースの割り当てのことです。インスタンスを作成するときは、インスタンス構成を選択してデータの格納場所を指定し、さらに使用するノード数も選択して、インスタンスの配信リソースおよびストレージ リソースの量を決定します。
次のコマンドを実行して、1 ノードの us-central1
リージョンに Spanner インスタンスを作成します。
gcloud spanner instances create test-instance --config=regional-us-central1 \
--description="Test Instance" --nodes=1
これにより、次の特性を持つインスタンスが作成されます。
- インスタンス ID
test-instance
- 表示名
Test Instance
- インスタンス構成
regional-us-central1
(リージョン構成ではデータが単一のリージョンに保存され、マルチリージョン構成ではデータが複数のリージョンに分散されます。詳しくは、インスタンスについてをご覧ください)。 - ノード数 1(
node_count
はインスタンスのデータベースで使用可能な配信リソースとストレージ リソースの量に対応します。詳しくは、ノードと処理ユニットをご覧ください)。
以下のように表示されます。
Creating instance...done.
サンプル ファイルの確認
サンプルのリポジトリには、Spanner を Java で使用する方法を示すサンプルが含まれています。
samples/snippets
ファイルを見ると、Spanner の使用方法を確認できます。このファイルのコードでは、新しいデータベースを作成して使用する方法が示されています。データで使用されているスキーマ例の詳細は、スキーマとデータモデルのページをご覧ください。
PGAdapter を起動する
ローカル開発マシンで PGAdapter を起動し、作成したインスタンスに PGAdapter を向けます。
次のコマンドは、gcloud auth application-default login
を実行していることを前提としています。
Java アプリケーション
wget https://storage.googleapis.com/pgadapter-jar-releases/pgadapter.tar.gz \
&& tar -xzvf pgadapter.tar.gz
java -jar pgadapter.jar -i test-instance
Docker
docker pull gcr.io/cloud-spanner-pg-adapter/pgadapter
docker run \
--name pgadapter \
--rm -d -p 5432:5432 \
-v "$HOME/.config/gcloud":/gcloud:ro \
--env CLOUDSDK_CONFIG=/gcloud \
gcr.io/cloud-spanner-pg-adapter/pgadapter \
-i test-instance -x
エミュレータ
docker pull gcr.io/cloud-spanner-pg-adapter/pgadapter-emulator
docker run \
--name pgadapter-emulator \
--rm -d \
-p 5432:5432 \
-p 9010:9010 \
-p 9020:9020 \
gcr.io/cloud-spanner-pg-adapter/pgadapter-emulator
これにより、組み込みの Spanner エミュレータで PGAdapter が開始されます。この埋め込みエミュレータでは、任意の Spanner インスタンスや接続するデータベースが自動的に作成されます。事前に手動で作成する必要はありません。
PGAdapter は、サイドカー コンテナまたはインプロセス依存関係として本番環境で実行することをおすすめします。PGAdapter を本番環境にデプロイする方法については、PGAdapter を実行する方法を選択するをご覧ください。
データベースの作成
コマンドラインで次のコマンドを実行して、test-instance
というインスタンスに example-db
というデータベースを作成します。
gcloud spanner databases create example-db --instance=test-instance \
--database-dialect=POSTGRESQL
次のように表示されます。
Creating database...done.
テーブルを作成する
次のコードは、データベースに 2 つのテーブルを作成します。
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./create_tables.sh example-db
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar createtables example-db
Go
go run sample_runner.go createtables example-db
Node.js
npm start createtables example-db
Python
python create_tables.py example-db
C#
dotnet run createtables example-db
次のステップでは、データベースにデータを書き込みます。
接続を作成する
読み取りまたは書き込みを行うには、PGAdapter への接続を作成する必要があります。Spanner とのすべてのやり取りはConnection
を介して渡されます。データベース名は接続文字列で指定します。
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./create_connection.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar createconnection example-db
Go
go run sample_runner.go createconnection example-db
Node.js
npm start createconnection example-db
Python
python create_connection.py example-db
C#
dotnet run createconnection example-db
DML でのデータの書き込み
読み取り / 書き込みトランザクションでデータ操作言語(DML)を使用してデータを挿入できます。
次のサンプルは、PostgreSQL ドライバを使用して Spanner で DML ステートメントを実行する方法を示しています。
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./write_data_with_dml.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar writeusingdml example-db
Go
go run sample_runner.go writeusingdml example-db
Node.js
npm start writeusingdml example-db
Python
python write_data_with_dml.py example-db
C#
dotnet run writeusingdml example-db
次のようなレスポンスが表示されます。
4 records inserted.
DML バッチでのデータの書き込み
PGAdapter は DML バッチの実行をサポートしています。1 つのバッチで複数の DML ステートメントを送信すると、Spanner へのラウンドトリップの回数が少なくなり、アプリケーションのパフォーマンスが向上します。
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./write_data_with_dml_batch.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar writeusingdmlbatch example-db
Go
go run sample_runner.go writeusingdmlbatch example-db
Node.js
npm start writeusingdmlbatch example-db
Python
python write_data_with_dml_batch.py example-db
C#
dotnet run writeusingdmlbatch example-db
次のように表示されます。
3 records inserted.
ミューテーションを使用してデータを書き込む
ミューテーションを使ってデータを挿入することもできます。
PGAdapter は、PostgreSQL の COPY
コマンドをミューテーションに変換します。Spanner データベースの COPY
を使用すると、すばやくデータを挿入できます。
COPY
オペレーションは、デフォルトではアトミックです。Spanner でのアトミック操作は commit サイズの上限に従います。
詳しくは、CRUD の制限をご覧ください。
次の例は、非アトミックな COPY
オペレーションを実行する方法を示しています。これにより、
COPY
オペレーションが commit サイズの上限を超えないようにする必要があります。
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./write_data_with_copy.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar write example-db
Go
go run sample_runner.go write example-db
Node.js
npm start write example-db
Python
python write_data_with_copy.py example-db
C#
dotnet run write example-db
次のように表示されます。
Copied 5 singers
Copied 5 albums
SQL を使用したデータのクエリ
Spanner では、データの読み取り用に SQL インターフェースがサポートされています。このインターフェースにアクセスするには、コマンドラインで Google Cloud CLI を使用するか、プログラムで PostgreSQL ドライバを使用します。
コマンドラインから
Albums
テーブルのすべての列から値を読み取るには、次の SQL ステートメントを実行します。
gcloud spanner databases execute-sql example-db --instance=test-instance \
--sql='SELECT singer_id, album_id, album_title FROM albums'
結果は次のようになります。
SingerId AlbumId AlbumTitle
1 1 Total Junk
1 2 Go, Go, Go
2 1 Green
2 2 Forever Hold Your Peace
2 3 Terrified
PostgreSQL ドライバを使用する
コマンドラインで SQL ステートメントを実行するだけでなく、プログラムから PostgreSQL ドライバを使用して同じ SQL ステートメントを発行することもできます。
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./query_data.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar query example-db
Go
go run sample_runner.go query example-db
Node.js
npm start query example-db
Python
python query_data.py example-db
C#
dotnet run query example-db
次のような結果が表示されます。
1 1 Total Junk
1 2 Go, Go, Go
2 1 Green
2 2 Forever Hold Your Peace
2 3 Terrified
SQL パラメータを使用したクエリ
アプリケーションに頻繁に実行されるクエリがある場合は、対象のクエリをパラメータ化してパフォーマンスを改善できます。パラメータ クエリをキャッシュに保存して再利用できます。これにより、コンパイルのコストを削減できます。詳細については、クエリ パラメータを使用して、頻繁に実行するクエリを高速化するをご覧ください。
ここでは、WHERE
句のパラメータを使用して、LastName
の特定の値を含むレコードをクエリします。
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./query_data_with_parameter.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar querywithparameter example-db
Go
go run sample_runner.go querywithparameter example-db
Node.js
npm start querywithparameter example-db
Python
python query_data_with_parameter.py example-db
C#
dotnet run querywithparameter example-db
次のような結果が表示されます。
12 Melissa Garcia
データベース スキーマの更新
MarketingBudget
という列を新たに Albums
テーブルに追加する必要があるとします。既存のテーブルに新しい列を追加するには、データベース スキーマの更新が必要です。Spanner は、データベースがトラフィックの処理を継続している間にデータベースのスキーマを更新することをサポートしています。スキーマの更新では、データベースをオフラインにする必要がなく、テーブル全体または列全体をロックすることもありません。スキーマの更新中もデータベースへのデータの書き込みを続けることができます。サポートされるスキーマの更新とスキーマ変更のパフォーマンスの詳細については、スキーマの更新をご覧ください。
列の追加
コマンドラインで列を追加するには、コマンドラインで Google Cloud CLI を使用するか、プログラムから PostgreSQL ドライブを利用します。
コマンドラインから
テーブルに新しい列を追加するには、次の ALTER TABLE
コマンドを使用します。
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='ALTER TABLE albums ADD COLUMN marketing_budget BIGINT'
次のように表示されます。
Schema updating...done.
PostgreSQL ドライバを使用する
PostgreSQL ドライバを使用して DDL ステートメントを実行し、スキーマを変更します。
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./add_column.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar addmarketingbudget example-db
Go
go run sample_runner.go addmarketingbudget example-db
Node.js
npm start addmarketingbudget example-db
Python
python add_column.py example-db
C#
dotnet run addmarketingbudget example-db
次のように表示されます。
Added marketing_budget column
DDL バッチを実行する
複数のスキーマ変更を 1 つのバッチで実行することをおすすめします。
セミコロン、もしくは START BATCH DDL
ステートメントと RUN BATCH
ステートメントで区切られた 1つの SQL 文字列としてすべての DDL ステートメントを送信することで、PostfreSQL ドライバの組み込みバッチ処理機能を使用して1つのバッチで複数の DDL ステートメントを実行することができます。
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./ddl_batch.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar ddlbatch example-db
Go
go run sample_runner.go ddlbatch example-db
Node.js
npm start ddlbatch example-db
Python
python ddl_batch.py example-db
C#
dotnet run ddlbatch example-db
次のように表示されます。
Added venues and concerts tables
新しい列へのデータの書き込み
次のコードは、新しい列にデータを書き込みます。MarketingBudget
の値を、キーが Albums(1, 1)
の行は 100000
に、キーが Albums(2, 2)
の行は 500000
に設定します。
COPY
コマンドをミューテーションに変換します。COPY
コマンドは、デフォルトで Insert
ミューテーションに変換されます。set spanner.copy_upsert=true
を実行して、COPY
コマンドを InsertOrUpdate
ミューテーションに変換します。これを使用して、Spanner 内の既存のデータを更新できます。
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./update_data_with_copy.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar update example-db
Go
go run sample_runner.go update example-db
Node.js
npm start update example-db
Python
python update_data_with_copy.py example-db
C#
dotnet run update example-db
次のように表示されます。
Updated 2 albums
さらに、SQL クエリを実行して、書き込んだばかりの値を取得することもできます。
クエリを実行するコードを次に示します。
psql
Java
Go
Node.js
Python
C#
次のコマンドでクエリを実行します。
psql
PGDATABASE=example-db ./query_data_with_new_column.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar querymarketingbudget example-db
Go
go run sample_runner.go querymarketingbudget example-db
Node.js
npm start querymarketingbudget example-db
Python
python query_data_with_new_column.py example-db
C#
dotnet run querymarketingbudget example-db
次のように表示されます。
1 1 100000
1 2 null
2 1 null
2 2 500000
2 3 null
データの更新
読み取り / 書き込みトランザクションで DML を使用してデータを更新できます。
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./update_data_with_transaction.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar writewithtransactionusingdml example-db
Go
go run sample_runner.go writewithtransactionusingdml example-db
Node.js
npm start writewithtransactionusingdml example-db
Python
python update_data_with_transaction.py example-db
C#
dotnet run writewithtransactionusingdml example-db
次のように表示されます。
Transferred marketing budget from Album 2 to Album 1
トランザクション タグとリクエスト タグ
トランザクション タグとリクエストタグを使用して、Spanner でのトランザクションとクエリのトラブルシューティングを行います。SPANNER.TRANSACTION_TAG
および SPANNER.STATEMENT_TAG
セッション変数を使用すると、トランザクション タグとリクエストタグを設定できます。
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./tags.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar tags example-db
Go
go run sample_runner.go tags example-db
Node.js
npm start tags example-db
Python
python tags.py example-db
C#
dotnet run tags example-db
読み取り専用トランザクションを使用したデータの取得
同じタイムスタンプで複数の読み取りを実行する場合について考えます。読み取り専用トランザクションはトランザクションの commit 履歴の整合性のあるプレフィックスを監視しているので、アプリケーションは常に整合性のあるデータを取得できます。接続を読み取り専用に設定するか、SET TRANSACTION READ ONLY
SQL ステートメントを使用して読み取り専用トランザクションを実行します。
同じ読み取り専用トランザクションでクエリと読み取りを実行する方法を次に示します。
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./read_only_transaction.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar readonlytransaction example-db
Go
go run sample_runner.go readonlytransaction example-db
Node.js
npm start readonlytransaction example-db
Python
python read_only_transaction.py example-db
C#
dotnet run readonlytransaction example-db
次のような出力が表示されます。
1 1 Total Junk
1 2 Go, Go, Go
2 1 Green
2 2 Forever Hold Your Peace
2 3 Terrified
2 2 Forever Hold Your Peace
1 2 Go, Go, Go
2 1 Green
2 3 Terrified
1 1 Total Junk
パーティション分割クエリと Data Boost
partitionQuery
API は、クエリをより小さな部品またはパーティションに分割し、複数のマシンを使用してパーティションを同時にフェッチします。各パーティションはパーティション トークンによって識別されます。PartitionQuery API は、データベース全体のエクスポートやスキャンなどの一括オペレーションのみを目的としているため、標準クエリ API よりもレイテンシが高くなります。
Data Boost を使用すると、プロビジョニングされた Spanner インスタンス上の既存のワークロードへの影響がほぼゼロの状態で、分析クエリとデータ エクスポートを実行できます。 Data Boost はパーティション分割クエリのみをサポートしています。
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./data_boost.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar databoost example-db
Go
go run sample_runner.go databoost example-db
Node.js
npm start databoost example-db
Python
python data_boost.py example-db
C#
dotnet run databoost example-db
PGAdapter を使用したパーティション分割クエリの実行と Data Boost の使用について、詳しくはData Boost とパーティション分割クエリ ステートメントをご覧ください。
パーティション化された DML
パーティション分割されたデータ操作言語(DML)は、次のタイプの一括更新と一括削除用に設計されています。
- 定期的なクリーンアップとガベージ コレクション
- デフォルト値での新しい列のバックフィリング
psql
Java
Go
Node.js
Python
C#
次のコマンドを使用してサンプルを実行します。
psql
PGDATABASE=example-db ./partitioned_dml.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar partitioneddml example-db
Go
go run sample_runner.go partitioneddml example-db
Node.js
npm start partitioneddml example-db
Python
python partitioned_dml.py example-db
C#
dotnet run datpartitioneddmlboost example-db
クリーンアップ
このチュートリアルで使用したリソースについて Cloud 請求先アカウントに課金されないようにするため、作成したデータベースとインスタンスを削除します。
データベースの削除
インスタンスを削除すると、それに含まれるすべてのデータベースが自動的に削除されます。このステップでは、インスタンスを削除しないでデータベースを削除する方法を示します(インスタンスの料金は引き続き発生します)。
コマンドラインから
gcloud spanner databases delete example-db --instance=test-instance
Google Cloud コンソールの使用
Google Cloud コンソールで、[Spanner インスタンス] ページに移動します。
インスタンスをクリックします。
削除するデータベースをクリックします。
[データベースの詳細] ページで [削除] をクリックします。
データベースを削除することを確認し、[削除] をクリックします。
インスタンスを削除する
インスタンスを削除すると、そのインスタンスで作成されたすべてのデータベースが自動的に削除されます。
コマンドラインから
gcloud spanner instances delete test-instance
Google Cloud コンソールの使用
Google Cloud コンソールで、[Spanner インスタンス] ページに移動します。
インスタンスをクリックします。
[削除] をクリックします。
インスタンスを削除することを確認し、[削除] をクリックします。
次のステップ
仮想マシン インスタンスで Spanner にアクセスする方法を確認する。
クライアント ライブラリを使用して Cloud サービスに対する認証を行うで、承認と認証情報について学習する。
Spanner のスキーマ設計のベスト プラクティスを確認する。