Ruby で Cloud Spanner を使ってみる

目標

このチュートリアルでは、Ruby 用の Cloud Spanner クライアント ライブラリを使用する以下の手順について説明します。

  • Cloud Spanner のインスタンスとデータベースを作成します。
  • データベースのデータに対し、書き込み、読み取り、SQL クエリの実行を行います。
  • データベース スキーマを更新します。
  • 読み取り / 書き込みトランザクションを使用してデータを更新します。
  • セカンダリ インデックスをデータベースに追加します。
  • インデックスを使用して、データの読み込みと SQL クエリの実行を行います。
  • 読み取り専用トランザクションを使用してデータを取得します。

料金

このチュートリアルで使用する Cloud Spanner は、Google Cloud Platform の有料コンポーネントです。Cloud Spanner を使用する料金については、料金をご覧ください。

始める前に

  1. 設定に示されている手順を完了します。その手順では、Google Cloud Platform のデフォルト プロジェクトの作成と設定、課金の有効化、Cloud Spanner API の有効化、Cloud Spanner API を使用するのに必要な認証情報を取得するために OAuth 2.0 を設定する方法について説明しています。
    特に、ローカル開発環境で認証情報を設定するために、必ず gcloud auth application-default login を実行してください。

  2. 開発マシンに次のものがまだインストールされていない場合はインストールします。

  3. ローカルマシンにサンプルアプリのリポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/ruby-docs-samples.git
    

    あるいは、zip 形式のサンプルをダウンロードして、ファイルを抽出することもできます。

  4. Cloud Spanner のサンプルコードが含まれるディレクトリに移動します。

    cd ruby-docs-samples/spanner/
    
  5. 依存関係をインストールします。

    bundle install
    
  6. GOOGLE_CLOUD_PROJECT 環境変数を Google Cloud Platform プロジェクト ID に設定します。

    export GOOGLE_CLOUD_PROJECT=[MY_PROJECT_ID]
    

インスタンスの作成

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.

サンプル ファイルの確認

サンプル リポジトリには、Ruby での Cloud Spanner の使用方法を示すサンプルが含まれています。

Cloud Spanner の使用方法については、spanner_samples.rb ファイルをご覧ください。このファイルのコードでは、新しいデータベースを作成して使用する方法が示されています。データで使用しているサンプル スキーマは、スキーマとデータモデルのページにあります。

データベースの作成

コマンドラインで次のコマンドを実行して、test-instance というインスタンスに example-db というデータベースを作成します。

bundle exec ruby spanner_samples.rb create_database test-instance example-db

以下のように表示されます。

Created database example-db on instance test-instance

これで Cloud Spanner データベースが作成されました。データベースを作成したコードは次のとおりです。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner  = Google::Cloud::Spanner.new project: project_id
instance = spanner.instance instance_id

job = instance.create_database database_id, statements: [
  "CREATE TABLE Singers (
    SingerId     INT64 NOT NULL,
    FirstName    STRING(1024),
    LastName     STRING(1024),
    SingerInfo   BYTES(MAX)
  ) PRIMARY KEY (SingerId)",

  "CREATE TABLE Albums (
    SingerId     INT64 NOT NULL,
    AlbumId      INT64 NOT NULL,
    AlbumTitle   STRING(MAX)
  ) PRIMARY KEY (SingerId, AlbumId),
  INTERLEAVE IN PARENT Singers ON DELETE CASCADE"
]

puts "Waiting for create database operation to complete"

job.wait_until_done!

puts "Created database #{database_id} on instance #{instance_id}"

コードでは、基本的な音楽アプリケーション用の 2 つのテーブル SingersAlbums も定義されています。これらのテーブルはこのページ全体で使用されています。まだスキーマ例を見ていない場合は確認してください。

次のステップでは、データベースにデータを書き込みます。

データベース クライアントの作成

読み取りまたは書き込みを行うには、先に Client を作成する必要があります。Client はデータベース接続と考えることができます。Cloud Spanner とのすべてのやり取りは Client 経由で実行される必要があります。通常はアプリケーション起動時に Client を作成し、読み込み、書き込み、トランザクションの実行に Client を再利用します。次のコードではクライアントの作成方法を示します。

# Imports the Google Cloud client library
require "google/cloud/spanner"

# Your Google Cloud Platform project ID
project_id = "YOUR_PROJECT_ID"

# Instantiates a client
spanner = Google::Cloud::Spanner.new project: project_id

# Your Cloud Spanner instance ID
instance_id = "my-instance"

# Your Cloud Spanner database ID
database_id = "my-database"

# Gets a reference to a Cloud Spanner instance database
database_client = spanner.client instance_id, database_id

# Execute a simple SQL statement
database_client.transaction do |transaction|
  results = transaction.execute "SELECT 1"

  results.rows.each do |row|
    puts row
  end
end

詳細については、Client のリファレンスをご覧ください。

DML を使用してデータを書き込む

読み取り / 書き込みトランザクションでデータ操作言語(DML)を使用してデータを挿入できます。

execute_update() メソッドを使用して DML ステートメントを実行します。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id
row_count = 0

client.transaction do |transaction|
  row_count = transaction.execute_update(
    "INSERT INTO Singers (SingerId, FirstName, LastName) VALUES
     (12, 'Melissa', 'Garcia'),
     (13, 'Russell', 'Morales'),
     (14, 'Jacqueline', 'Long'),
     (15, 'Dylan', 'Shaw')"
  )
end

puts "#{row_count} records inserted."

write_using_dml 引数を使用してサンプルを実行します。

bundle exec ruby spanner_samples.rb write_using_dml test-instance example-db

以下のように表示されます。

 4 records inserted.

ミューテーションを使用してデータを書き込む

ミューテーションを使用してデータを挿入することもできます。

データの書き込みには Client オブジェクトを使用します。Client#commit メソッドは、データベース内の列、行、テーブルにまたがる単一の論理ポイントでアトミックに実行される書き込みトランザクションを作成し、commit します。

次のコードは、ミューテーションを使用してデータを書き込む方法を示しています。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

client.commit do |c|
  c.insert "Singers", [
    { SingerId: 1, FirstName: "Marc",     LastName: "Richards" },
    { SingerId: 2, FirstName: "Catalina", LastName: "Smith"    },
    { SingerId: 3, FirstName: "Alice",    LastName: "Trentor"  },
    { SingerId: 4, FirstName: "Lea",      LastName: "Martin"   },
    { SingerId: 5, FirstName: "David",    LastName: "Lomond"   }
  ]
  c.insert "Albums", [
    { 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"               }
  ]
end

puts "Inserted data"

insert_data 引数を使用してサンプルを実行します。

bundle exec ruby spanner_samples.rb insert_data test-instance example-db

以下のように表示されます。

Inserted data

SQL を使用したデータのクエリ

Cloud Spanner では、データの読み取りにネイティブ SQL インターフェースがサポートされます。このインターフェースへのアクセスは、コマンドラインで gcloud コマンドライン ツールを使用するか、プログラムから Ruby 用の 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

Ruby 用の Cloud Spanner クライアント ライブラリの使用

コマンドラインで SQL ステートメントを実行するだけでなく、プログラムから Ruby 用の Cloud Spanner クライアント ライブラリを使用して同じ SQL ステートメントを発行することもできます。

SQL クエリを実行するには、Client#execute メソッドを使用します。Ruby シンボル :ColumnName を使用すると、行から特定の列のデータにアクセスできます。

クエリを発行してデータにアクセスする方法を次に示します。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

client.execute("SELECT SingerId, AlbumId, AlbumTitle FROM Albums").rows.each do |row|
  puts "#{row[:SingerId]} #{row[:AlbumId]} #{row[:AlbumTitle]}"
end

query_data 引数を使用してサンプルを実行します。

bundle exec ruby spanner_samples.rb query_data test-instance example-db

次のような結果が表示されます。

1 1 Total Junk
1 2 Go, Go, Go
2 1 Green
2 2 Forever Hold Your Peace
2 3 Terrified

読み取り API を使用したデータの読み込み

Cloud Spanner の SQL インターフェースに加えて、Cloud Spanner は読み取りインターフェースもサポートしています。

データベースから行を読み取るには、Client クラスの Client#read メソッドを使用します。

データを読み取る方法を次に示します。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

client.read("Albums", [:SingerId, :AlbumId, :AlbumTitle]).rows.each do |row|
  puts "#{row[:SingerId]} #{row[:AlbumId]} #{row[:AlbumTitle]}"
end

read_data 引数を使用してサンプルを実行します。

bundle exec ruby spanner_samples.rb read_data test-instance example-db

次のような出力が表示されます。

1 1 Total Junk
1 2 Go, Go, Go
2 1 Green
2 2 Forever Hold Your Peace
2 3 Terrified

データベース スキーマの更新

MarketingBudget という列を新たに Albums テーブルに追加する必要があるとします。既存のテーブルに新しい列を追加するには、データベース スキーマの更新が必要です。Cloud Spanner は、トラフィック提供中のデータベースへのスキーマの更新をサポートしています。スキーマの更新では、データベースをオフラインにする必要がなく、テーブル全体や列がロックされないため、スキーマの更新中もデータベースへのデータの書き込みを続けることができます。サポートされるスキーマの更新とスキーマ変更のパフォーマンスの詳細については、スキーマの更新をご覧ください。

列の追加

列の追加は、コマンドラインで gcloud コマンドライン ツールを使用するか、プログラムから Ruby 用の Cloud Spanner クライアント ライブラリを使用して行います。

コマンドラインから

テーブルに新しい列を追加するには、次の ALTER TABLE コマンドを使用します。

gcloud spanner databases ddl update example-db --instance=test-instance \
  --ddl='ALTER TABLE Albums ADD COLUMN MarketingBudget INT64'

以下のように表示されます。

DDL updating...done.

Ruby 用の Cloud Spanner クライアント ライブラリの使用

スキーマを変更するには、Database クラスの Database#update メソッドを使用します。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner  = Google::Cloud::Spanner.new project: project_id
instance = spanner.instance instance_id
database = instance.database database_id

job = database.update statements: [
  "ALTER TABLE Albums ADD COLUMN MarketingBudget INT64"
]

puts "Waiting for database update to complete"

job.wait_until_done!

puts "Added the MarketingBudget column"

add_column 引数を使用してサンプルを実行します。

bundle exec ruby spanner_samples.rb add_column test-instance example-db

以下のように表示されます。

Added the MarketingBudget column

新しい列へのデータの書き込み

次のコードは、新しい列にデータを書き込みます。MarketingBudget の値を、キーが Albums(1, 1) の行では 100000 に、キーが Albums(2, 2) の行では 500000 に設定します。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

client.commit do |c|
  c.update "Albums", [
    { SingerId: 1, AlbumId: 1, MarketingBudget: 100_000 },
    { SingerId: 2, AlbumId: 2, MarketingBudget: 500_000 }
  ]
end

puts "Updated data"

update_data 引数を使用してサンプルを実行します。

bundle exec ruby spanner_samples.rb update_data test-instance example-db

以下のように表示されます。

Updated data

SQL クエリまたは読み取り呼び出しを実行して、書き込んだばかりの値を取得することもできます。

クエリを実行するコードを次に示します。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

client.execute("SELECT SingerId, AlbumId, MarketingBudget FROM Albums").rows.each do |row|
  puts "#{row[:SingerId]} #{row[:AlbumId]} #{row[:MarketingBudget]}"
end

このクエリを実行するには、query_data_with_new_column 引数を使用してサンプルを実行します。

bundle exec ruby spanner_samples.rb query_data_with_new_column test-instance example-db

以下のように表示されます。

1 1 100000
1 2
2 1
2 2 500000
2 3

データの更新

読み取り / 書き込みトランザクションで DML を使用してデータを更新できます。

execute_update() メソッドを使用して DML ステートメントを実行します。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

client.transaction do |transaction|
  first_album = transaction.execute(
    "SELECT MarketingBudget from Albums
     WHERE SingerId = 1 and AlbumId = 1"
  ).rows.first
  second_album = transaction.execute(
    "SELECT MarketingBudget from Albums
    WHERE SingerId = 2 and AlbumId = 2"
  ).rows.first
  raise "The first album does not have enough funds to transfer" if first_album[:MarketingBudget] < 300_000

  new_second_album_budget = second_album[:MarketingBudget] + 200_000
  new_first_album_budget  = first_album[:MarketingBudget] - 200_000

  transaction.execute_update(
    "UPDATE Albums SET MarketingBudget = @albumBudget WHERE SingerId = 1 and AlbumId = 1",
    params: { albumBudget: new_first_album_budget }
  )
  transaction.execute_update(
    "UPDATE Albums SET MarketingBudget = @albumBudget WHERE SingerId = 2 and AlbumId = 2",
    params: { albumBudget: new_second_album_budget }
  )
end

puts "Transaction complete"

write_with_transaction_using_dml 引数を使用してサンプルを実行します。

bundle exec ruby spanner_samples.rb write_with_transaction_using_dml test-instance example-db

以下のように表示されます。

Transaction complete

セカンダリ インデックスの使用

Albums から AlbumTitle の値が特定の範囲内である行すべてをフェッチしたいと仮定します。SQL ステートメントまたは読み取りインターフェースを使用して AlbumTitle 列からすべての値を読み取り、基準を満たしていない行を破棄することもできますが、この方法では処理量が大きくなります(特に、行数が多いテーブルの場合)。代わりに、テーブルにセカンダリ インデックスを作成することにより、主キー以外の列を検索するときの行の取得速度を上げることができます。

既存のテーブルにセカンダリ インデックスを追加するには、スキーマの更新が必要です。他のスキーマの更新と同様に、Cloud Spanner ではデータベースがトラフィックを提供している間にインデックスを追加できます。Cloud Spanner は、内部でインデックスにデータを書き込みます(「バックフィル」)。バックフィルには数分かかることがありますが、このプロセスの間に、データベースをオフラインにしたり、特定のテーブルや列への書き込みを避けたりする必要はありません。詳細については、インデックスのバックフィリングをご覧ください。

セカンダリ インデックスの追加

インデックスの追加は、コマンドラインで gcloud コマンドライン ツールを使用するか、プログラムから Ruby 用の Cloud Spanner クライアント ライブラリを使用して行います。

コマンドラインから

データベースにインデックスを追加するには、次の CREATE INDEX コマンドを使用します。

gcloud spanner databases ddl update example-db --instance=test-instance \
  --ddl='CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)'

以下のように表示されます。

DDL updating...done.

Ruby 用の Cloud Spanner クライアント ライブラリの使用

インデックスを追加するには、Database クラスの Database#update メソッドを使用します。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner  = Google::Cloud::Spanner.new project: project_id
instance = spanner.instance instance_id
database = instance.database database_id

job = database.update statements: [
  "CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)"
]

puts "Waiting for database update to complete"

job.wait_until_done!

puts "Added the AlbumsByAlbumTitle index"

create_index 引数を使用してサンプルを実行します。

bundle exec ruby spanner_samples.rb create_index test-instance example-db

インデックスの追加には数分かかる場合があります。インデックスが追加されると、次のように表示されます。

Added the AlbumsByAlbumTitle index

インデックスを使用したクエリ

新しいインデックスを使用してクエリを実行するには、コマンドラインまたはクライアント ライブラリを使用します。

コマンドラインから

gcloud コマンドライン ツールで SQL ステートメントを実行し、["Aardvark", "Goo")AlbumsTitle の範囲に対して AlbumsByAlbumTitle インデックスを使用して Albums から AlbumIdAlbumTitleMarketingBudget を取得します。

gcloud spanner databases execute-sql example-db --instance=test-instance --sql='SELECT AlbumId, AlbumTitle, MarketingBudget FROM Albums@{FORCE_INDEX=AlbumsByAlbumTitle} WHERE AlbumTitle >= "Aardvark" AND AlbumTitle < "Goo"'

結果は次のようになります。

AlbumId  AlbumTitle               MarketingBudget
2        Go, Go, Go
2        Forever Hold Your Peace  300000

Ruby 用の Cloud Spanner クライアント ライブラリの使用

プログラムでインデックスを使用するコードは、前に使用したクエリのコードと似ています。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"
# start_title = "An album title to start with such as 'Ardvark'"
# end_title   = "An album title to end with such as 'Goo'"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

sql_query = "SELECT AlbumId, AlbumTitle, MarketingBudget
             FROM Albums@{FORCE_INDEX=AlbumsByAlbumTitle}
             WHERE AlbumTitle >= @start_title AND AlbumTitle < @end_title"

params      = { start_title: start_title, end_title: end_title }
param_types = { start_title: :STRING,     end_title: :STRING }

client.execute(sql_query, params: params, types: param_types).rows.each do |row|
  puts "#{row[:AlbumId]} #{row[:AlbumTitle]} #{row[:MarketingBudget]}"
end

query_data_with_index 引数を使用してサンプルを実行します。

bundle exec ruby spanner_samples.rb query_data_with_index test-instance example-db

次のような出力が表示されます。

2 Go, Go, Go
2 Forever Hold Your Peace 300000

詳細については、以下のリファレンスをご覧ください。

インデックスを使用した読み取り

インデックスを使用して読み取るには、Client クラスの read メソッドに index パラメータを指定します。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

result = client.read "Albums", [:AlbumId, :AlbumTitle],
                     index: "AlbumsByAlbumTitle"

result.rows.each do |row|
  puts "#{row[:AlbumId]} #{row[:AlbumTitle]}"
end

read_data_with_index 引数を使用してサンプルを実行します。

bundle exec ruby spanner_samples.rb read_data_with_index test-instance example-db

以下のように表示されます。

2 Forever Hold Your Peace
2 Go, Go, Go
1 Green
3 Terrified
1 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)'

インデックスの追加には数分かかる場合があります。インデックスが追加されると、次のように表示されます。

DDL updating...done.

Ruby 用の Cloud Spanner クライアント ライブラリの使用

STORING 句を指定してインデックスを追加するには、Database クラスの Database#update メソッドを使用します。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner  = Google::Cloud::Spanner.new project: project_id
instance = spanner.instance instance_id
database = instance.database database_id

job = database.update statements: [
  "CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle)
   STORING (MarketingBudget)"
]

puts "Waiting for database update to complete"

job.wait_until_done!

puts "Added the AlbumsByAlbumTitle2 storing index"

create_storing_index 引数を使用してサンプルを実行します。

bundle exec ruby spanner_samples.rb create_storing_index test-instance example-db

以下のように表示されます。

Added the AlbumsByAlbumTitle2 index

これで、インデックス AlbumsByAlbumTitle2 から AlbumIdAlbumTitleMarketingBudget 列をすべて取得する読み取りを実行できるようになります。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

result = client.read "Albums", [:AlbumId, :AlbumTitle, :MarketingBudget],
                     index: "AlbumsByAlbumTitle2"

result.rows.each do |row|
  puts "#{row[:AlbumId]} #{row[:AlbumTitle]} #{row[:MarketingBudget]}"
end

read_data_with_storing_index 引数を使用してサンプルを実行します。

bundle exec ruby spanner_samples.rb read_data_with_storing_index test-instance example-db

次のような出力が表示されます。

2 Forever Hold Your Peace 300000
2 Go, Go, Go
1 Green
3 Terrified
1 Total Junk 300000

読み取り専用トランザクションを使用したデータの取得

同じタイムスタンプで複数の読み取りを実行する場合について考えます。読み取り専用トランザクションはトランザクションの commit 履歴の整合性のあるプレフィックスを監視しているので、アプリケーションは常に整合性のあるデータを取得できます。読み取り専用トランザクションを実行するには、Snapshot オブジェクトを使用します。Snapshot オブジェクトを取得するには、Client クラスの snapshot メソッドを使用します。

同じ読み取り専用トランザクションでクエリと読み取りを実行する方法を次に示します。

# project_id  = "Your Google Cloud project ID"
# instance_id = "Your Spanner instance ID"
# database_id = "Your Spanner database ID"

require "google/cloud/spanner"

spanner = Google::Cloud::Spanner.new project: project_id
client  = spanner.client instance_id, database_id

client.snapshot do |snapshot|
  snapshot.execute("SELECT SingerId, AlbumId, AlbumTitle FROM Albums").rows.each do |row|
    puts "#{row[:AlbumId]} #{row[:AlbumTitle]} #{row[:SingerId]}"
  end

  # Even if changes occur in-between the reads, the transaction ensures that
  # both return the same data.
  snapshot.read("Albums", [:AlbumId, :AlbumTitle, :SingerId]).rows.each do |row|
    puts "#{row[:AlbumId]} #{row[:AlbumTitle]} #{row[:SingerId]}"
  end
end

read_only_transaction 引数を使用してサンプルを実行します。

bundle exec ruby spanner_samples.rb read_only_transaction test-instance example-db

次のような出力が表示されます。

2 Forever Hold Your Peace 2
2 Go, Go, Go 1
1 Green 2
3 Terrified 2
1 Total Junk 1
1 Total Junk 1
2 Go, Go, Go 1
1 Green 2
2 Forever Hold Your Peace 2
3 Terrified 2

クリーンアップ

このチュートリアルで使用したリソースの Google Cloud Platform アカウントが課金されないようにするため、作成したデータベースとインスタンスを削除します。

データベースの削除

インスタンスを削除すると、それに含まれるすべてのデータベースが自動的に削除されます。このステップでは、インスタンスを削除しないでデータベースを削除する方法を示します(インスタンスの料金は引き続き発生します)。

コマンドラインから

gcloud spanner databases delete example-db --instance=test-instance

GCP Console の使用

  1. Google Cloud Platform Console の Cloud Spanner インスタンス ページに移動します。
    Cloud Spanner インスタンス ページに移動
  2. インスタンスをクリックします。
  3. 削除するデータベースをクリックします。
  4. [データベースの詳細] ページで [削除] をクリックします。
  5. データベースを削除することを確認し、[削除] をクリックします。

インスタンスの削除

インスタンスを削除すると、そのインスタンスで作成されたすべてのデータベースが自動的に削除されます。

コマンドラインから

gcloud spanner instances delete test-instance

GCP Console の使用

  1. Google Cloud Platform Console の Cloud Spanner インスタンス ページに移動します。
    Cloud Spanner インスタンス ページに移動
  2. インスタンスをクリックします。
  3. [削除] をクリックします。
  4. インスタンスを削除することを確認し、[削除] をクリックします。

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Cloud Spanner のドキュメント