目標
本教學課程將引導您使用 Node.js 適用的 Spanner 用戶端程式庫,完成下列步驟:
- 建立 Spanner 執行個體和資料庫。
- 對資料庫中的資料進行寫入和讀取,以及執行 SQL 查詢。
- 更新資料庫結構定義。
- 使用讀取/寫入交易來更新資料。
- 將次要索引新增至資料庫。
- 使用索引對資料執行讀取作業和 SQL 查詢。
- 使用唯讀交易擷取資料。
費用
本教學課程使用 Spanner,這是Google Cloud的計費元件。如要瞭解 Spanner 的使用費用,請參閱「定價」。
事前準備
完成「設定」一節所述的步驟,包括建立及設定預設 Google Cloud 專案、啟用計費功能、啟用 Cloud Spanner API,以及設定 OAuth 2.0,以取得使用 Cloud Spanner API 的驗證憑證。
請務必執行 gcloud auth
application-default login,使用驗證憑證設定本機開發環境。
準備本機 Node.js 環境
按照步驟設定 Node.js 開發環境
將範例應用程式存放區複製到您的本機電腦:
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git您也可以透過 zip 檔案的格式下載範例,然後再解壓縮該檔案。
變更為包含 Spanner 程式碼範例的目錄:
cd nodejs-docs-samples/spanner/使用
npm安裝依附元件:npm install
建立執行個體
首次使用 Spanner 時,必須建立執行個體,也就是 Spanner 資料庫所用的資源分配單位。建立執行個體時,請選擇「執行個體設定」以決定資料儲存的位置,再選擇要使用的節點數量以決定執行個體的服務和儲存空間資源量。
請參閱「建立執行個體」,瞭解如何使用下列任一方法建立 Spanner 執行個體。您可以將執行個體命名為 test-instance,以便與本文件中參照名為 test-instance 的執行個體的其他主題搭配使用。
- Google Cloud CLI
- Google Cloud 控制台
- 用戶端程式庫 (C++、C#、Go、Java、Node.js、PHP、Python、Ruby 或 Rust)
瀏覽範例檔案
範例存放區包含一個範例,說明如何搭配使用 Spanner 和 Node.js。
請查看 samples/schema.js 檔案,瞭解如何建立資料庫及修改資料庫結構定義。資料會使用「結構定義與資料模型」頁面中顯示的範例結構定義。
建立資料庫
GoogleSQL
node schema.js createDatabase test-instance example-db MY_PROJECT_ID
PostgreSQL
node schema.js createPgDatabase test-instance example-db MY_PROJECT_ID
如下所示:
Created database example-db on instance test-instance.
GoogleSQL
PostgreSQL
下一個步驟是將資料寫入資料庫。
建立資料庫用戶端
您必須先建立Database,才能執行讀取或寫入作業:
您可以將 Database 視為資料庫連線:您與 Spanner 的所有互動都必須透過 Database 進行。一般來說,您會在應用程式啟動時建立 Database,然後重複使用該 Database 來讀取、寫入及執行交易。每個用戶端都會使用 Spanner 中的資源。
如果您在同一個應用程式中建立多個用戶端,請在不再需要用戶端時,立即呼叫 Database.close() 清理用戶端的資源,包括網路連線。
詳情請參閱 Database 參考資料。
使用 DML 寫入資料
您可以在讀寫交易中使用 data manipulation language (DML) 插入資料。
您可以使用 runUpdate() 方法執行 DML 陳述式。
使用 writeUsingDml 引數執行範例。
node dml.js writeUsingDml test-instance example-db MY_PROJECT_ID
如下所示:
4 records inserted.
使用變異寫入資料
您也可以使用變異來插入資料。
您可以使用 Table 物件寫入資料。Table.insert() 方法會在資料表中新增資料列。系統會以不可分割的形式套用單一批次中的所有插入資料。
此程式碼顯示如何使用變異寫入資料:
使用 insert 引數執行範例。
node crud.js insert test-instance example-db MY_PROJECT_ID
如下所示:
Inserted data.
使用 SQL 查詢資料
Spanner 支援讀取資料的 SQL 介面,您可以使用 Google Cloud CLI 在指令列存取,或使用 Node.js 適用的 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
使用 Node.js 專用的 Spanner 用戶端程式庫
除了在指令列執行 SQL 陳述式,您也可以使用 Node.js 適用的 Spanner 用戶端程式庫,以程式輔助方式發出相同的 SQL 陳述式。
使用 Database.run() 執行 SQL 查詢。
下面說明如何發出查詢和存取資料:
node crud.js query test-instance example-db MY_PROJECT_ID
畫面上應會顯示下列結果:
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
使用 SQL 參數查詢
如果應用程式經常執行某個查詢,您可以將其參數化,以提升效能。產生的參數化查詢可以快取並重複使用,進而降低編譯成本。詳情請參閱「使用查詢參數加快頻繁執行的查詢」。
以下範例說明如何在 WHERE 子句中使用參數,查詢包含特定 LastName 值的記錄。
GoogleSQL
PostgreSQL
下面說明如何發出查詢和存取資料:
node dml.js queryWithParameter test-instance example-db MY_PROJECT_ID
畫面會顯示以下結果:
SingerId: 12, FirstName: Melissa, LastName: Garcia
使用讀取 API 讀取資料
除了 Spanner 的 SQL 介面外,Spanner 也支援讀取介面。
使用 Table.read() 讀取資料庫中的資料列。使用 KeySet 物件定義要讀取的索引鍵和索引鍵範圍集合。
下列內容將示範如何讀取資料:
使用 read 引數執行範例。
node crud.js read test-instance example-db MY_PROJECT_ID
畫面會顯示類似以下的輸出:
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
更新資料庫結構定義
假設您需要在 Albums 資料表中新增名為 MarketingBudget 的資料欄。必須先更新資料庫結構定義,才能新增新資料欄到現有的資料表。Spanner 可支援更新資料庫結構定義,同時讓資料庫持續處理流量。結構定義更新作業不需要讓資料庫離線,也不會鎖定整個資料表或資料欄;您可以在結構定義更新期間,持續將資料寫入資料庫。如要進一步瞭解支援的結構定義更新和結構定義變更效能,請參閱「更新結構定義」。
新增資料欄
您可以使用 Google Cloud CLI 在指令列中新增資料欄,或使用 Node.js 適用的 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.
使用 Node.js 專用的 Spanner 用戶端程式庫
使用 Database.updateSchema 修改結構定義:
GoogleSQL
PostgreSQL
使用 addColumn 引數執行範例。
node schema.js addColumn test-instance example-db MY_PROJECT_ID
如下所示:
Added the MarketingBudget column.
寫入資料到新資料欄
以下程式碼會將資料寫入新資料欄,這會將索引鍵為 Albums(1, 1) 的資料列 MarketingBudget 設為 100000,並將索引鍵為 Albums(2, 2) 的資料列設為 500000。
使用 update 引數執行範例。
node crud.js update test-instance example-db MY_PROJECT_ID
如下所示:
Updated data.
您也可以執行 SQL 查詢或讀取呼叫,以擷取剛寫入的值。
以下是執行查詢的程式碼:
如要執行這項查詢,請使用 queryNewColumn 引數執行範例。
node schema.js queryNewColumn test-instance example-db MY_PROJECT_ID
如下所示:
SingerId: 1, AlbumId: 1, MarketingBudget: 100000
SingerId: 1, AlbumId: 2, MarketingBudget: null
SingerId: 2, AlbumId: 1, MarketingBudget: null
SingerId: 2, AlbumId: 2, MarketingBudget: 500000
SingerId: 2, AlbumId: 3, MarketingBudget: null
更新資料
您可以在讀寫交易中使用 DML 來更新資料。
您可以使用 runUpdate() 方法執行 DML 陳述式。
GoogleSQL
PostgreSQL
使用 writeWithTransactionUsingDml 引數執行範例。
node dml.js writeWithTransactionUsingDml test-instance example-db MY_PROJECT_ID
如下所示:
Successfully executed read-write transaction using DML to transfer $200000 from Album 2 to Album 1.
使用次要索引
假設您要擷取 AlbumTitle 值在特定範圍內的所有 Albums 資料列,您可以先使用 SQL 陳述式或讀取呼叫,來讀取 AlbumTitle 資料欄的所有值,然後捨棄條件不符的資料列。不過,掃描完整資料表的費用高昂,資料表內含大量資料列時更是如此。因此您可以改為在資料表建立次要索引,這樣將非主鍵資料欄做為搜尋條件時,就能加快資料列的擷取速度。
您必須先更新結構定義,才能在現有資料表新增次要索引。如同其他結構定義更新作業,Spanner 可支援新增索引,同時讓資料庫持續處理流量。Spanner 會自動使用現有資料補充索引。補充作業可能需要幾分鐘才能完成,在這個過程中,您不需將資料庫設為離線,可照常執行索引資料表的寫入作業。詳情請參閱「新增次要索引」。
新增次要索引後,Spanner 會自動將其用於可能透過索引加快執行速度的 SQL 查詢。如果使用讀取介面,則必須指定要使用的索引。
新增次要索引
您可以使用 gcloud CLI 在指令列中新增索引,或使用 Node.js 適用的 Spanner 用戶端程式庫,以程式輔助方式新增索引。
使用指令列
使用下列 CREATE INDEX 指令,將索引新增至資料庫:
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)'
如下所示:
Schema updating...done.
使用 Node.js 適用的 Spanner 用戶端程式庫
使用 Database.updateSchema() 新增索引:
使用 createIndex 引數執行範例。
node indexing.js createIndex test-instance example-db MY_PROJECT_ID
索引可能需要幾分鐘才能新增完成。之後畫面上會顯示以下訊息:
Added the AlbumsByAlbumTitle index.
使用索引進行讀取
Spanner 會自動為 SQL 查詢使用適當的索引。在讀取介面中,您必須在要求中指定索引。
如要在讀取介面中使用索引,請使用 Table.read() 方法。
使用 readIndex 引數執行範例。
node indexing.js readIndex test-instance example-db MY_PROJECT_ID
如下所示:
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
新增索引,以便執行僅限索引讀取作業
您可能已注意到,先前的讀取範例不包含讀取 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.
使用 Node.js 適用的 Spanner 用戶端程式庫
使用Database.updateSchema() 新增含有 STORING 子句的索引:
使用 createStoringIndex 引數執行範例。
node indexing.js createStoringIndex test-instance example-db MY_PROJECT_ID
如下所示:
Added the AlbumsByAlbumTitle2 index.
現在您可以執行讀取作業,從 AlbumsByAlbumTitle2 索引擷取所有 AlbumId、AlbumTitle 和 MarketingBudget 欄:
使用 readStoringIndex 引數執行範例。
node indexing.js readStoringIndex test-instance example-db MY_PROJECT_ID
畫面會顯示類似以下的輸出:
AlbumId: 2, AlbumTitle: Forever Hold your Peace, MarketingBudget: 300000
AlbumId: 2, AlbumTitle: Go, Go, Go, MarketingBudget: null
AlbumId: 1, AlbumTitle: Green, MarketingBudget: null
AlbumId: 3, AlbumTitle: Terrified, MarketingBudget: null
AlbumId: 1, AlbumTitle: Total Junk, MarketingBudget: 300000
使用唯讀交易擷取資料
假設您想要在相同時間戳記執行一次以上的讀取作業。唯讀交易會觀察交易修訂版本記錄的一致前置字串,因此應用程式一律會取得一致的資料。使用 Database.runTransaction() 執行唯讀交易。
以下顯示如何執行查詢,並在同一個唯讀交易中執行讀取作業:
使用 readOnly 引數執行範例。
node transaction.js readOnly test-instance example-db MY_PROJECT_ID
畫面會顯示類似以下的輸出:
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
SingerId: 1, AlbumId: 2, AlbumTitle: Go, Go, Go
SingerId: 1, AlbumId: 1, AlbumTitle: Total Junk
SingerId: 2, AlbumId: 1, AlbumTitle: Green
SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold your Peace
SingerId: 2, AlbumId: 3, AlbumTitle: Terrified
Successfully executed read-only transaction.
清除所用資源
為避免系統向您的 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 結構定義設計最佳做法。