目標
本教學課程將引導您使用 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 環境
如要在自己的應用程式中開始使用 Spanner,請將用戶端程式庫新增至專案依附元件:
如果您使用 Maven,請將下列指令新增至 pom.xml 檔案。如要進一步瞭解 BOM,請參閱「Google Cloud Platform 程式庫 BOM」。
如果您使用 Gradle,請在依附元件中加入以下指令:
如果您使用 sbt,請在依附元件中加入以下指令:
如果您使用的是 Visual Studio Code 或 IntelliJ,可以使用下列 IDE 外掛程式,將用戶端程式庫新增至專案:
這些外掛程式會提供其他功能,例如服務帳戶的金鑰管理功能。詳情請參閱各外掛程式的說明文件。
或者,如要執行本教學課程中使用的範例應用程式,請按照下列步驟準備本機環境:
請在您的開發機器上安裝下列項目:
將應用程式存放區範例複製到本機電腦中:
git clone https://github.com/googleapis/google-cloud-java.git變更為包含 Spanner 程式碼範例的目錄:
cd google-cloud-java/java-spanner/samples/snippets產生範例 JAR 檔案:
mvn clean package
建立執行個體
首次使用 Spanner 時,必須建立執行個體,也就是 Spanner 資料庫所用的資源分配單位。建立執行個體時,請選擇「執行個體設定」以決定資料儲存的位置,再選擇要使用的節點數量以決定執行個體的服務和儲存空間資源量。
請參閱「建立執行個體」,瞭解如何使用下列任一方法建立 Spanner 執行個體。您可以將執行個體命名為 test-instance,以便與本文件中參照名為 test-instance 的執行個體的其他主題搭配使用。
- Google Cloud CLI
- Google Cloud 控制台
- 用戶端程式庫 (C++、C#、Go、Java、Node.js、PHP、Python 或 Ruby)
瀏覽範例檔案
範例存放區包含一個範例,說明如何搭配使用 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 寫入資料
您可以在讀寫交易中使用 data manipulation language (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 資料表中所有資料欄的值:
GoogleSQL
gcloud spanner databases execute-sql example-db --instance=test-instance \
--sql='SELECT SingerId, AlbumId, AlbumTitle FROM Albums'
GoogleSQL 管道語法
gcloud spanner databases execute-sql example-db --instance=test-instance \
--sql='FROM Albums |> SELECT SingerId, AlbumId, AlbumTitle'
結果顯示:
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
更新資料庫結構定義
假設您需要在 Albums 資料表中新增名為 MarketingBudget 的資料欄。必須先更新資料庫結構定義,才能新增新資料欄到現有的資料表。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) 的資料列 MarketingBudget 設為 100000,並將索引鍵為 Albums(2, 2) 的資料列設為 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
使用次要索引
假設您要擷取 AlbumTitle 值在特定範圍內的所有 Albums 資料列,您可以先使用 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.
使用索引進行讀取
Spanner 會自動為 SQL 查詢使用適當的索引。在讀取介面中,您必須在要求中指定索引。
如要在讀取介面中使用索引,請使用 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 的讀取介面不支援透過 join 索引與資料表,再查詢未儲存於索引中的值。
建立 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 Instances」(Spanner 執行個體) 頁面。
點選執行個體。
點選您要刪除的資料庫。
在「Database details」(資料庫詳細資料) 頁面,按一下 [Delete] (刪除)。
確認您要刪除資料庫,然後按一下 [Delete] (刪除)。
刪除執行個體
您刪除執行個體時,也會自動捨棄您在其中建立的所有資料庫。
使用指令列
gcloud spanner instances delete test-instance
使用 Google Cloud 控制台
前往 Google Cloud 控制台的「Spanner Instances」(Spanner 執行個體) 頁面。
點選執行個體。
按一下 [Delete] (刪除)。
確認您要刪除執行個體,然後按一下 [Delete] (刪除)。
後續步驟
瞭解如何透過虛擬機器執行個體存取 Spanner。
如要瞭解授權和驗證憑證,請參閱「使用用戶端程式庫向 Cloud 服務進行驗證」。
進一步瞭解 Spanner 結構定義設計最佳做法。