目標
本教學課程會使用 Java 專用的 Spanner 用戶端程式庫,逐步引導您完成下列步驟:
- 建立 Spanner 執行個體和資料庫。
- 對資料庫中的資料進行寫入和讀取,以及執行 SQL 查詢。
- 更新資料庫結構定義。
- 使用讀取/寫入交易來更新資料。
- 將次要索引新增至資料庫。
- 使用索引對資料執行讀取作業和 SQL 查詢。
- 使用唯讀交易擷取資料。
費用
本教學課程使用 Spanner,這是Google Cloud的計費元件。如要瞭解 Spanner 的使用費用,請參閱「定價」一文。
事前準備
完成「設定」一文中說明的步驟,包含建立與設定預設的 Google Cloud 專案、啟用計費功能、啟用 Cloud Spanner API 和設定 OAuth 2.0 以取得使用 Cloud Spanner API 的驗證憑證。
特別提醒您,請務必執行 gcloud auth
application-default login
來設定本機開發環境的驗證憑證。
準備本機 Java 環境
請在您的開發機器上安裝下列項目:
將應用程式存放區範例複製到本機電腦中:
git clone https://github.com/googleapis/java-spanner.git
變更為包含 Spanner 範例程式碼的目錄:
cd java-spanner/samples/snippets
產生範例 JAR 檔案:
mvn clean package
建立執行個體
首次使用 Spanner 時,您必須建立執行個體,這是 Spanner 資料庫會使用的資源分配單位。建立執行個體時,請選擇「執行個體設定」以決定資料儲存的位置,再選擇要使用的節點數量以決定執行個體的服務和儲存空間資源量。
執行下列指令,在 us-central1
地區使用 1 個節點建立 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。
建立資料庫
GoogleSQL
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
createdatabase test-instance example-db
PostgreSQL
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
createpgdatabase test-instance example-db
畫面上會顯示下列訊息:
Created database [example-db]
GoogleSQL
PostgreSQL
下一個步驟是將資料寫入資料庫。
建立資料庫用戶端
您必須先建立DatabaseClient
,才能執行讀取或寫入作業。您可以將 DatabaseClient
視為一種資料庫連線:您與 Spanner 的所有互動都必須透過 DatabaseClient
。一般而言,您會在應用程式啟動時建立 DatabaseClient
,接著就能重複使用該 DatabaseClient
來讀取、寫入及執行交易。
每個用戶端都會使用 Spanner 中的資源,因此呼叫 close()
來關閉不需要的用戶端是不錯的做法。
詳情請參閱 DatabaseClient
Javadoc 參考資料。
使用 DML 寫入資料
您可以使用資料操縱語言 (DML) 在讀寫交易中插入資料。
請使用 executeUpdate()
方法執行 DML 陳述式。
使用 writeusingdml
引數執行範例。
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
writeusingdml test-instance example-db
畫面上會顯示下列訊息:
4 records inserted.
使用變異寫入資料
您也可以使用變異來插入資料。
您可以使用 Mutation
物件寫入資料。Mutation
物件是變異作業的容器。Mutation
代表一系列的插入、更新和刪除作業,Spanner 會以不可分割的形式,將這些作業套用至 Spanner 資料庫中不同的資料列和資料表。
Mutation
類別中的 newInsertBuilder()
方法會建構 INSERT
變異,在資料表中插入新的資料列。如果該資料列已存在,寫入就會失敗。或者,您也可以使用 newInsertOrUpdateBuilder
方法建構 INSERT_OR_UPDATE
變異,在資料列已存在的情況下更新資料欄值。
DatabaseClient
類別中的 write()
方法會寫入異動事件。而系統會以不可分割的形式套用單一批次中的所有異動事件。
此程式碼顯示如何使用變異寫入資料:
使用 write
引數執行範例。
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
write test-instance example-db
畫面上應該會顯示指令執行成功的訊息。
使用 SQL 查詢資料
Spanner 支援可用於讀取資料的 SQL 介面。您可以透過 Google Cloud CLI 在指令列上存取這個介面,也可以透過程式輔助方式使用 Java 專用的 Spanner 用戶端程式庫存取這個介面。
使用指令列
執行下列 SQL 陳述式,從 Albums
資料表讀取所有資料欄的值:
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
使用適用於 Java 的 Spanner 用戶端程式庫
除了在指令列上執行 SQL 陳述式外,您也可以使用 Java 專用的 Spanner 用戶端程式庫,透過程式輔助方式發出相同的 SQL 陳述式。
您可以使用下列方法和類別來執行 SQL 查詢:DatabaseClient
類別中的singleUse()
方法:使用此方法,即可在 Spanner 資料表的一或多個資料列中,讀取一或多個資料欄的值。singleUse()
會傳回ReadContext
物件,可用來執行讀取作業或 SQL 陳述式。ReadContext
類別的executeQuery()
方法:使用這個方法執行資料庫查詢。Statement
類別:使用這個類別,即可建構 SQL 字串。ResultSet
類別:使用這個類別,即可存取 SQL 陳述式或讀取呼叫傳回的資料。
下面說明如何發出查詢和存取資料:
使用 query
引數執行範例。
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
query 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
使用 SQL 參數執行查詢
如果應用程式有經常執行的查詢,您可以透過參數化來提升效能。系統可快取並重新使用產生的參數查詢,減少編譯的成本。詳情請參閱「使用查詢參數,針對經常執行的查詢加快速度」。
以下範例說明如何在 WHERE
子句中使用參數,查詢包含 LastName
特定值的記錄。
GoogleSQL
PostgreSQL
使用 queryWithParameter 引數執行範例。
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
querywithparameter test-instance example-db
畫面上應會顯示下列結果:
12 Melissa Garcia
使用讀取 API 讀取資料
除了 Spanner 的 SQL 介面外,Spanner 也支援讀取介面。
使用ReadContext
類別的 read()
方法,讀取資料庫中的資料列。使用 KeySet
物件定義要讀取的索引鍵集合和索引鍵範圍。
下列內容將示範如何讀取資料:
使用 read
引數執行範例。
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
read 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
資料表,必須先更新資料庫結構定義,才能新增新資料欄到現有的資料表。Spanner 可在資料庫持續處理流量時,支援資料庫的結構定義更新作業。結構定義更新作業不需要讓資料庫離線,也不會鎖定整個資料表或資料欄;您可以在結構定義更新期間持續將資料寫入資料庫。詳情請參閱進行結構定義更新一文中支援的結構定義更新和結構定義變更效能。
新增資料欄
您可以使用 Google Cloud CLI 在指令列上新增資料欄,或使用 Java 專用的 Spanner 用戶端程式庫透過程式輔助方式新增資料欄。
使用指令列
使用下列 ALTER TABLE
指令,在資料表中新增資料欄:
GoogleSQL
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='ALTER TABLE Albums ADD COLUMN MarketingBudget INT64'
PostgreSQL
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='ALTER TABLE Albums ADD COLUMN MarketingBudget BIGINT'
畫面上會顯示下列訊息:
Schema updating...done.
使用適用於 Java 的 Spanner 用戶端程式庫
請使用DatabaseAdminClient
類別的 updateDatabaseDdl()
方法修改結構定義:
GoogleSQL
PostgreSQL
使用 addmarketingbudget
引數執行範例。
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
addmarketingbudget test-instance example-db
畫面上會顯示下列訊息:
Added MarketingBudget column.
寫入資料到新資料欄
以下程式碼會將資料寫入新資料欄,並在 Albums(1, 1)
和 Albums(2, 2)
這兩個索引鍵表示的資料列中將 MarketingBudget
分別設為 100000
和 500000
。
使用 update
引數執行範例。
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
update test-instance example-db
您也可以執行 SQL 查詢或讀取呼叫,以擷取剛寫入的值。
以下是執行查詢的程式碼:
GoogleSQL
PostgreSQL
如要執行這項查詢,請使用 querymarketingbudget
引數執行範例檔案。
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
querymarketingbudget test-instance example-db
畫面上會顯示下列訊息:
1 1 100000
1 2 NULL
2 1 NULL
2 2 500000
2 3 NULL
更新資料
您可以在讀寫交易中使用 DML 來更新資料。
請使用 executeUpdate()
方法執行 DML 陳述式。
GoogleSQL
PostgreSQL
使用 writewithtransactionusingdml
引數執行範例。
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
writewithtransactionusingdml test-instance example-db
使用次要索引
假設您要針對 Albums
擷取 AlbumTitle
值在特定範圍內的所有資料列,可以先利用 SQL 陳述式或讀取呼叫,從 AlbumTitle
資料欄讀取所有值,然後再捨棄條件不符的資料列。不過,執行完整資料表掃描的費用高昂,對於內含大量資料列的資料表而言更是如此。因此您可以改為在資料表建立次要索引,以在將非主鍵資料欄做為搜尋條件時,能加快資料列的擷取速度。
您必須先更新結構定義,才能將次要索引新增至現有資料表。如同其他結構定義更新,Spanner 支援在資料庫持續處理流量時新增索引。Spanner 會自動使用現有資料填入索引。補充作業可能需要幾分鐘才能完成,但您不必將資料庫設為離線,也不必避免在這個程序中寫入已編入索引的資料表。詳情請參閱「新增次要索引」。
新增次要索引後,Spanner 會自動將其用於 SQL 查詢,這些查詢可能會在使用索引後執行得更快。如果您使用讀取介面,則必須指定要使用的索引。
新增次要索引
您可以使用 gcloud CLI 在指令列上新增索引,或使用 Java 專用的 Spanner 用戶端程式庫透過程式輔助方式新增索引。
使用指令列
使用下列 CREATE INDEX
指令,在資料庫中新增索引:
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)'
畫面上會顯示下列訊息:
Schema updating...done.
使用 Java 專用的 Spanner 用戶端程式庫
使用DatabaseAdminClient
類別的 updateDatabaseDdl()
方法新增索引:
使用 addindex
引數執行範例。
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
addindex test-instance example-db
索引可能需要幾分鐘才能新增完成。之後畫面上會顯示以下訊息:
Added the AlbumsByAlbumTitle index.
使用索引進行讀取
對於 SQL 查詢,Spanner 會自動使用適當的索引。在讀取介面中,您必須在要求中指定索引。
如要在讀取介面中使用索引,請使用 ReadContext
類別的 readUsingIndex()
方法。
下列程式碼會從 AlbumsByAlbumTitle
索引中擷取所有 AlbumId
和 AlbumTitle
資料欄。
使用 readindex
引數執行範例。
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
readindex test-instance example-db
畫面上會顯示下列訊息:
2 Forever Hold Your Peace
2 Go, Go, Go
1 Green
3 Terrified
1 Total Junk
新增索引以便僅讀取索引
您可能已經注意到,前述的讀取範例並未包含讀取 MarketingBudget
資料欄。這是因為 Spanner 的讀取介面不支援將索引與資料表彙整,再查詢未保存於索引中的值。
請為 AlbumsByAlbumTitle
建立替代定義,將 MarketingBudget
的副本保存在索引中。
使用指令列
GoogleSQL
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget)
PostgreSQL
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) INCLUDE (MarketingBudget)
索引可能需要幾分鐘才能新增完成。之後畫面上會顯示以下訊息:
Schema updating...done.
使用 Java 專用的 Spanner 用戶端程式庫
使用 DatabaseAdminClient
類別的 updateDatabaseDdl()
方法,透過 STORING
子句 (針對 GoogleSQL) 和 INCLUDE
子句 (針對 PostgreSQL) 新增索引:
GoogleSQL
PostgreSQL
使用 addstoringindex
引數執行範例。
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
addstoringindex test-instance example-db
索引可能需要幾分鐘才能新增完成。之後畫面上會顯示以下訊息:
Added AlbumsByAlbumTitle2 index
現在您可以執行讀取作業,從 AlbumsByAlbumTitle2
索引中擷取所有 AlbumId
、AlbumTitle
和 MarketingBudget
欄:
使用 readstoringindex
引數執行範例。
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
readstoringindex test-instance example-db
畫面會顯示類似以下的輸出:
2 Forever Hold Your Peace 300000
2 Go, Go, Go NULL
1 Green NULL
3 Terrified NULL
1 Total Junk 300000
使用唯讀交易擷取資料
假設您想要在相同時間戳記執行一次以上的讀取作業。唯讀交易會觀察出交易修訂記錄中一致的前置字串,讓應用程式取得的資料始終保持一致。如要執行唯讀交易,請使用 ReadOnlyTransaction
物件。請使用 DatabaseClient
類別的 readOnlyTransaction()
方法取得 ReadOnlyTransaction
物件。
以下顯示如何執行查詢,並在同一個唯讀交易中執行讀取作業:
使用 readonlytransaction
引數執行範例。
java -jar target/spanner-snippets/spanner-google-cloud-samples.jar \
readonlytransaction test-instance example-db
畫面會顯示類似以下的輸出:
2 2 Forever Hold Your Peace
1 2 Go, Go, Go
2 1 Green
2 3 Terrified
1 1 Total Junk
1 1 Total Junk
1 2 Go, Go, Go
2 1 Green
2 2 Forever Hold Your Peace
2 3 Terrified
清除所用資源
如要避免系統向您的 Cloud Billing 帳戶收取您在本教學課程中所用資源的額外費用,請捨棄資料庫並刪除您建立的執行個體。
刪除資料庫
您刪除執行個體時,也會自動刪除其中所有資料庫。這個步驟將示範如何在保留執行個體的情況下刪除資料庫 (您仍須支付執行個體費用)。
使用指令列
gcloud spanner databases delete example-db --instance=test-instance
使用 Google Cloud 主控台
前往 Google Cloud 控制台的「Spanner 執行個體」頁面。
點選執行個體。
點選您要刪除的資料庫。
在「Database details」(資料庫詳細資料) 頁面,按一下 [Delete] (刪除)。
確認您要刪除資料庫,然後按一下 [Delete] (刪除)。
刪除執行個體
您刪除執行個體時,也會自動捨棄您在其中建立的所有資料庫。
使用指令列
gcloud spanner instances delete test-instance
使用 Google Cloud 主控台
前往 Google Cloud 控制台的「Spanner 執行個體」頁面。
點選執行個體。
按一下 [Delete] (刪除)。
確認您要刪除執行個體,然後按一下 [Delete] (刪除)。
後續步驟
瞭解如何透過虛擬機器執行個體存取 Spanner。
請參閱「使用用戶端程式庫驗證 Cloud 服務」一文,進一步瞭解授權和驗證憑證。
進一步瞭解 Spanner 的結構定義設計最佳做法。