目標
このチュートリアルでは、PHP 用の Cloud Spanner クライアント ライブラリを使用するステップを詳しく説明します。
- Cloud Spanner のインスタンスとデータベースを作成します。
- データベースのデータに対し、書き込み、読み取り、SQL クエリの実行を行います。
- データベース スキーマを更新します。
- 読み取り / 書き込みトランザクションを使用してデータを更新します。
- セカンダリ インデックスをデータベースに追加します。
- インデックスを使用して、データの読み込みと SQL クエリの実行を行います。
- 読み取り専用トランザクションを使用してデータを取得します。
料金
このチュートリアルで使用する Cloud Spanner は、Google Cloud の有料コンポーネントです。Cloud Spanner を使用する料金については、料金をご覧ください。
始める前に
設定に示されている手順を完了します。この手順では、デフォルトの Google Cloud プロジェクトの作成と設定、課金の有効化、Cloud Spanner API の有効化、Cloud Spanner API の使用に必要な認証情報を取得するための OAuth 2.0 の設定について説明しています。
特に、ローカルの開発環境に認証情報を設定するために、必ず gcloud auth
application-default login
を実行してください。
ローカルの PHP 環境を準備する
サービス アカウントの手順に沿って、アプリケーションのデフォルト認証情報としてサービス アカウントを設定します。この手順に沿って、サービス アカウント キー ファイル(JSON 形式)と
GOOGLE_APPLICATION_CREDENTIALS
環境変数の両方を取得する必要があります。これにより、Cloud Spanner API の認証を受けられるようになります。開発マシンに次のものがまだインストールされていない場合はインストールします。
ローカルマシンにサンプルアプリのリポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/php-docs-samples
あるいは、zip 形式のサンプルをダウンロードして、ファイルを抽出することもできます。
Cloud Spanner のサンプルコードが含まれるディレクトリに移動します。
cd php-docs-samples/spanner
依存関係をインストールします。
composer install
これにより、PHP 用の Cloud Spanner クライアント ライブラリがインストールされます。このライブラリをプロジェクトに追加するには、
composer require google/cloud-spanner
を実行します。
インスタンスの作成
Cloud Spanner を最初に使用するときは、インスタンスを作成する必要があります。インスタンスとは、Cloud Spanner データベースによって使用されるリソースの割り当てのことです。インスタンスを作成するときは、インスタンス構成を選択してデータの格納場所を指定し、さらに使用するノード数も選択して、インスタンスの配信リソースおよびストレージ リソースの量を決定します。
次のコマンドを実行して、1 ノードの us-central1
リージョンに Cloud 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.
サンプル ファイルの確認
サンプル リポジトリには、PHP での Cloud Spanner の使用方法を示すサンプルがあります。
src/create_database.php
および src/add_column.php
の関数を見ると、データベースの作成方法とデータベース スキーマの変更方法を確認できます。データで使用されているスキーマ例の詳細は、スキーマとデータモデルのページをご覧ください。
データベースの作成
コマンドラインで次のコマンドを実行して、test-instance
というインスタンスに example-db
というデータベースを作成します。
php spanner.php create-database test-instance example-db
以下のように表示されます。
Created database example-db on instance test-instance
これで Cloud Spanner データベースが作成されました。データベースを作成したコードは次のとおりです。
コードでは、基本的な音楽アプリケーション用の 2 つのテーブル Singers
と Albums
も定義されています。これらのテーブルはこのページ全体で使用されています。まだスキーマ例を見ていない場合は確認してください。
次のステップでは、データベースにデータを書き込みます。
データベース クライアントの作成
読み取りと書き込みを行うには、Google\Cloud\Spanner\Database
のインスタンスを取得する必要があります。
Database
はデータベース接続と考えることができます。Cloud Spanner とのすべてのやり取りは Database
を経由する必要があります。通常はアプリケーション開始時に Database
を作成し、読み取り、書き込み、トランザクションの実行に Database
を再利用します。
各クライアントは Cloud Spanner のリソースを使用するため、Database::close
を呼び出してクライアントのリソース(ネットワーク接続を含む)をクリーンアップする必要があります。
詳細については、Database
のリファレンスをご覧ください。
DML でのデータの書き込み
読み取り / 書き込みトランザクションでデータ操作言語(DML)を使用してデータを挿入できます。
executeUpdate()
メソッドを使用して DML ステートメントを実行します。
write-data-with-dml
コマンドを使用してサンプルを実行します。
php spanner.php write-data-with-dml test-instance example-db
以下のように表示されます。
Inserted 4 row(s).
ミューテーションを使用してデータを書き込む
ミューテーションを使ってデータを挿入することもできます。
データの書き込みには Database::insertBatch
メソッドを使用します。insertBatch
はテーブルに新しい行を追加します。1 つのバッチ内の挿入はすべてアトミックに適用されます。
次のコードは、ミューテーションを使用してデータを書き込む方法を示しています。
insert-data
コマンドを使用してサンプルを実行します。
php spanner.php insert-data test-instance example-db
以下のように表示されます。
Inserted data.
SQL を使用したデータのクエリ
Cloud Spanner では、データの読み取り用にネイティブ SQL インターフェースがサポートされています。このインターフェースにアクセスするには、コマンドラインで gcloud
コマンドライン ツールを使用するか、プログラムで PHP 用の Cloud Spanner クライアント ライブラリを使用します。
コマンドラインから
Albums
テーブルのすべての列から値を読み取るには、次の SQL ステートメントを実行します。
gcloud spanner databases execute-sql example-db --instance=test-instance \
--sql='SELECT SingerId, AlbumId, AlbumTitle 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
PHP 用の Cloud Spanner クライアント ライブラリの使用
コマンドラインで SQL ステートメントを実行するだけでなく、PHP 用の Cloud Spanner クライアント ライブラリを使用して同じ SQL ステートメントをプログラマティックに発行できます。
SQL クエリを実行するには、Database::execute()
を使用します。
クエリを発行してデータにアクセスする方法を次に示します。
query-data
コマンドを使用してサンプルを実行します。
php spanner.php query-data test-instance example-db
次のような結果が表示されます。
SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold Your Peace
SingerId: 1, AlbumId: 2, AlbumTitle: Go, Go, Go
SingerId: 2, AlbumId: 1, AlbumTitle: Green
SingerId: 2, AlbumId: 3, AlbumTitle: Terrified
SingerId: 1, AlbumId: 1, AlbumTitle: Total Junk
結果の順序はこのとおりとは限りません。結果の順序を確実にする必要がある場合は、SQL ベスト プラクティスに記載のとおり ORDER BY
句を使用します。
SQL パラメータを使用したクエリ
サポートされている SQL 型を使用して、SQL ステートメントにカスタム値を追加できます。
ここでは、WHERE
句でパラメータとして @lastName
を使用し、LastName
に特定の値を含むレコードを取得します。
query-data-with-parameter コマンドを使用してサンプルを実行します。
php spanner.php query-data-with-parameter test-instance example-db
次のような結果が表示されます。
SingerId: 12, FirstName: Melissa, LastName: Garcia
読み取り API を使用したデータの読み込み
Cloud Spanner の SQL インターフェースに加えて、Cloud Spanner は読み取りインターフェースもサポートしています。
Database::read()
を使用して、データベースから行を読み取ります。読み取るキーおよびキー範囲のコレクションを定義するには、KeySet
オブジェクトを使用します。
データを読み取る方法を次に示します。
read-data
コマンドを使用してサンプルを実行します。
php spanner.php read-data test-instance example-db
次のような出力が表示されます。
SingerId: 1, AlbumId: 1, AlbumTitle: Total Junk
SingerId: 1, AlbumId: 2, AlbumTitle: Go, Go, Go
SingerId: 2, AlbumId: 1, AlbumTitle: Green
SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold your Peace
SingerId: 2, AlbumId: 3, AlbumTitle: Terrified
データベース スキーマの更新
MarketingBudget
という列を新たに Albums
テーブルに追加する必要があるとします。既存のテーブルに新しい列を追加するには、データベース スキーマの更新が必要です。Cloud Spanner は、トラフィック提供中のデータベースへのスキーマの更新をサポートしています。スキーマの更新では、データベースをオフラインにする必要がなく、テーブル全体や列がロックされないため、スキーマの更新中もデータベースへのデータの書き込みを続けることができます。サポートされるスキーマの更新とスキーマ変更のパフォーマンスの詳細については、スキーマの更新をご覧ください。
列の追加
列を追加するには、コマンドラインで gcloud
コマンドライン ツールを使用するか、プログラムで PHP 用の Cloud Spanner クライアント ライブラリを使用します。
コマンドラインから
テーブルに新しい列を追加するには、次の ALTER TABLE
コマンドを使用します。
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='ALTER TABLE Albums ADD COLUMN MarketingBudget INT64'
以下のように表示されます。
Schema updating...done.
PHP 用の Cloud Spanner クライアント ライブラリの使用
スキーマを変更するには、Database::updateDdl
を使用します。
add-column
コマンドを使用してサンプルを実行します。
php spanner.php add-column test-instance example-db
以下のように表示されます。
Added the MarketingBudget column.
新しい列へのデータの書き込み
次のコードは、新しい列にデータを書き込みます。MarketingBudget
の値を、キーが Albums(1, 1)
の行は 100000
に、キーが Albums(2, 2)
の行は 500000
に設定します。
update-data
コマンドを使用してサンプルを実行します。
php spanner.php update-data test-instance example-db
以下のように表示されます。
Updated data.
SQL クエリまたは読み取り呼び出しを実行して、書き込んだばかりの値を取得することもできます。
クエリを実行するコードを次に示します。
このクエリを実行するには、query-data-with-new-column
引数を使用してサンプルを実行します。
php spanner.php query-data-with-new-column test-instance example-db
以下のように表示されます。
SingerId: 1, AlbumId: 1, MarketingBudget: 100000
SingerId: 1, AlbumId: 2, MarketingBudget: 0
SingerId: 2, AlbumId: 1, MarketingBudget: 0
SingerId: 2, AlbumId: 2, MarketingBudget: 500000
SingerId: 2, AlbumId: 3, MarketingBudget: 0
データの更新
読み取り / 書き込みトランザクションで DML を使用してデータを更新できます。
executeUpdate()
メソッドを使用して DML ステートメントを実行します。
write-data-with-dml-transaction
コマンドを使用してサンプルを実行します。
php spanner.php write-data-with-dml-transaction test-instance example-db
以下のように表示されます。
Transaction complete.
セカンダリ インデックスの使用
Albums
から AlbumTitle
の値が特定の範囲内にある行すべてを取得すると仮定します。SQL ステートメントまたは読み取り呼び出しを使用して AlbumTitle
列からすべての値を読み取り、基準を満たしていない行を破棄することもできますが、このようなテーブル全体のスキャンは割高です(特に、行数が多いテーブルの場合)。代わりに、テーブルにセカンダリ インデックスを作成することにより、主キー以外の列を検索するときの行の取得速度を上げることができます。
既存のテーブルにセカンダリ インデックスを追加するには、スキーマの更新が必要です。他のスキーマの更新と同様に、Cloud Spanner ではデータベースがトラフィックを提供している間にインデックスを追加できます。Cloud Spanner では、インデックスに既存のデータが自動的にバックフィルされます。バックフィルには数分かかることがありますが、このプロセスの間に、データベースをオフラインにしたり、インデックス化対象のテーブルへの書き込みを控えたりする必要はありません。詳細については、インデックスのバックフィリングをご覧ください。
セカンダリ インデックスを追加すると、インデックス効果で実行速度が上がりそうな SQL クエリに対してそのセカンダリ インデックスが自動的に使用されるようになります。読み取りインターフェースを使用する場合は、使用するインデックスを指定する必要があります。
セカンダリ インデックスの追加
インデックスを追加するには、コマンドラインで gcloud
コマンドライン ツールを使用するか、プログラムで PHP 用の Cloud Spanner クライアント ライブラリを使用します。
コマンドラインから
データベースにインデックスを追加するには、次の CREATE INDEX
コマンドを使用します。
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)'
以下のように表示されます。
Schema updating...done.
PHP 用の Cloud Spanner クライアント ライブラリの使用
インデックスを追加するには、Database::updateDdl
を使用します。
create-index
コマンドを使用してサンプルを実行します。
php spanner.php create-index test-instance example-db
インデックスの追加には数分かかる場合があります。インデックスが追加されると、次のように表示されます。
Added the AlbumsByAlbumTitle index.
インデックスを使用して読み取りを行う
SQL クエリの場合、Cloud Spanner により適切なインデックスが自動的に使用されます。読み取りインターフェースでは、リクエストでインデックスを指定する必要があります。
読み取りインターフェースでインデックスを使用するには、Database::read
メソッドを使用します。
read-data-with-index
コマンドを使用してサンプルを実行します。
php spanner.php read-data-with-index test-instance example-db
以下のように表示されます。
AlbumId: 2, AlbumTitle: Forever Hold your Peace
AlbumId: 2, AlbumTitle: Go, Go, Go
AlbumId: 1, AlbumTitle: Green
AlbumId: 3, AlbumTitle: Terrified
AlbumId: 1, AlbumTitle: Total Junk
STORING 句を使用してインデックスを追加する
上記の読み取り例では、MarketingBudget
列の読み取りが含まれていませんでした。これは、Cloud Spanner の読み取りインターフェースが、インデックスとデータテーブルを結合してインデックスに格納されていない値を検索する機能をサポートしていないためです。
MarketingBudget
のコピーをインデックスに格納する AlbumsByAlbumTitle
の代替定義を作成します。
コマンドラインから
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget)'
インデックスの追加には数分かかる場合があります。インデックスが追加されると、次のように表示されます。
Schema updating...done.
PHP 用の Cloud Spanner クライアント ライブラリの使用
Database::updateDdl
を使用し、STORING
句を指定してインデックスを追加します。
create-storing-index
コマンドを使用してサンプルを実行します。
php spanner.php create-storing-index test-instance example-db
以下のように表示されます。
Added the AlbumsByAlbumTitle2 index.
これで、インデックス AlbumsByAlbumTitle2
から AlbumId
、AlbumTitle
、MarketingBudget
列をすべて取得する読み取りを実行できるようになりました。
read-data-with-storing-index
コマンドを使用してサンプルを実行します。
php spanner.php read-data-with-storing-index test-instance example-db
次のような出力が表示されます。
AlbumId: 2, AlbumTitle: Forever Hold your Peace, MarketingBudget: 300000
AlbumId: 2, AlbumTitle: Go, Go, Go, MarketingBudget: 0
AlbumId: 1, AlbumTitle: Green, MarketingBudget: 0
AlbumId: 3, AlbumTitle: Terrified, MarketingBudget: 0
AlbumId: 1, AlbumTitle: Total Junk, MarketingBudget: 300000
読み取り専用トランザクションを使用したデータの取得
同じタイムスタンプで複数の読み取りを実行する場合について考えます。読み取り専用トランザクションは、トランザクションの commit 履歴で整合性のあるプレフィックスを監視しているため、アプリケーションは常に整合性のあるデータを取得できます。読み取り専用トランザクションを実行するには、Snapshot
オブジェクトを使用します。Database::snapshot
メソッドを使用して Snapshot
オブジェクトを取得します。
同じ読み取り専用トランザクションでクエリと読み取りを実行する方法を次に示します。
read-only-transaction
コマンドを使用してサンプルを実行します。
php spanner.php read-only-transaction test-instance example-db
次のような出力が表示されます。
Results from first read:
SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold Your Peace
SingerId: 1, AlbumId: 2, AlbumTitle: Go, Go, Go
SingerId: 2, AlbumId: 1, AlbumTitle: Green
SingerId: 2, AlbumId: 3, AlbumTitle: Terrified
SingerId: 1, AlbumId: 1, AlbumTitle: Total Junk
Results from second read:
SingerId: 1, AlbumId: 1, AlbumTitle: Total Junk
SingerId: 1, AlbumId: 2, AlbumTitle: Go, Go, Go
SingerId: 2, AlbumId: 1, AlbumTitle: Green
SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold Your Peace
SingerId: 2, AlbumId: 3, AlbumTitle: Terrified
クリーンアップ
このチュートリアルで使用したリソースについて Google Cloud アカウントに課金されないようにするため、作成したデータベースとインスタンスを削除します。
データベースの削除
インスタンスを削除すると、それに含まれるすべてのデータベースが自動的に削除されます。このステップでは、インスタンスを削除しないでデータベースを削除する方法を示します(インスタンスの料金は引き続き発生します)。
コマンドラインから
gcloud spanner databases delete example-db --instance=test-instance
Cloud Console を使用する
Google Cloud Console で、Cloud Spanner の [インスタンス] ページに移動します。
インスタンスをクリックします。
削除するデータベースをクリックします。
[データベースの詳細] ページで [削除] をクリックします。
データベースを削除することを確認し、[削除] をクリックします。
インスタンスの削除
インスタンスを削除すると、そのインスタンスで作成されたすべてのデータベースが自動的に削除されます。
コマンドラインから
gcloud spanner instances delete test-instance
Cloud Console を使用する
Google Cloud Console で、Cloud Spanner の [インスタンス] ページに移動します。
インスタンスをクリックします。
[削除] をクリックします。
インスタンスを削除することを確認し、[削除] をクリックします。