目标
本教程将介绍如何使用 Spanner 完成以下步骤: 适用于 PostgreSQL 驱动程序的 PGAdapter 本地代理:
- 创建 Spanner 实例和数据库。
- 写入、读取数据库中的数据和对数据执行 SQL 查询。
- 更新数据库架构。
- 使用读写事务更新数据。
- 向数据库添加二级索引。
- 使用索引来读取数据和对数据执行 SQL 查询。
- 使用只读事务检索数据。
费用
本教程使用 Spanner,它是 Google Cloud如需了解 Spanner 的使用费用,请参阅 定价。
准备工作
完成设置中介绍的步骤,包括创建和设置默认 Google Cloud 项目、启用结算功能、启用 Cloud Spanner API 以及设置 OAuth 2.0 来获取身份验证凭据以使用 Cloud Spanner API。
尤其要确保运行 gcloud auth
application-default login
,以便使用身份验证凭据设置本地开发环境。
准备本地 PGAdapter 环境
您可以将 PostgreSQL 驱动程序与 PGAdapter 结合使用 才能连接到 Spanner。PGAdapter 是一个 会将 PostgreSQL 网络协议转换为 Spanner gRPC 协议。
PGAdapter 需要 Java 或 Docker 才能运行。
如果尚未安装以下任何一项,请在开发机器上安装其中之一:
将示例应用代码库克隆到本地机器:
git clone https://github.com/GoogleCloudPlatform/pgadapter.git
切换到包含 Spanner 示例代码的目录:
psql
cd pgadapter/samples/snippets/psql-snippets
Java
cd pgadapter/samples/snippets/java-snippets mvn package -DskipTests
Go
cd pgadapter/samples/snippets/golang-snippets
Node.js
cd pgadapter/samples/snippets/nodejs-snippets npm install
Python
cd pgadapter/samples/snippets/python-snippets python -m venv ./venv pip install -r requirements.txt cd samples
C#
cd pgadapter/samples/snippets/dotnet-snippets
创建实例
首次使用 Spanner 时,您必须创建一个实例, 分配 Spanner 数据库使用的资源。创建实例时,请选择一个实例配置(决定数据的存储位置),同时选择要使用的节点数(决定实例中服务资源和存储资源的数量)。
执行以下命令,在该区域中创建 Spanner 实例
us-central1
,具有 1 个节点:
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 与 PGAdapter 结合使用。
请浏览samples/snippets
文件夹,其中说明了如何使用
Spanner。代码展示了如何创建和使用新数据库。数据
使用
架构和数据模型页面。
启动 PGAdapter
在本地开发机器上启动 PGAdapter,并将其指向 实例
以下命令假定您已执行
gcloud auth application-default login
。
Java 应用
wget https://storage.googleapis.com/pgadapter-jar-releases/pgadapter.tar.gz \
&& tar -xzvf pgadapter.tar.gz
java -jar pgadapter.jar -i test-instance
Docker
docker pull gcr.io/cloud-spanner-pg-adapter/pgadapter
docker run \
--name pgadapter \
--rm -d -p 5432:5432 \
-v "$HOME/.config/gcloud":/gcloud:ro \
--env CLOUDSDK_CONFIG=/gcloud \
gcr.io/cloud-spanner-pg-adapter/pgadapter \
-i test-instance -x
模拟器
docker pull gcr.io/cloud-spanner-pg-adapter/pgadapter-emulator
docker run \
--name pgadapter-emulator \
--rm -d \
-p 5432:5432 \
-p 9010:9010 \
-p 9020:9020 \
gcr.io/cloud-spanner-pg-adapter/pgadapter-emulator
这将使用嵌入式 Spanner 启动 PGAdapter 模拟器。此嵌入式模拟器会自动创建任何 Spanner 而无需手动创建 。
我们建议您在生产环境中运行 PGAdapter,并将其作为 Sidecar 或作为进程内依赖项使用如需详细了解如何部署 PGAdapter 在生产环境中的情况,请参阅 选择运行 PGAdapter 的方法。
创建数据库
通过以下方法在名为 test-instance
的实例中创建名为 example-db
的数据库:
请在命令行中运行以下命令。
gcloud spanner databases create example-db --instance=test-instance \
--database-dialect=POSTGRESQL
您应该会看到:
Creating database...done.
创建表
以下代码会在数据库中创建两个表。
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./create_tables.sh example-db
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar createtables example-db
Go
go run sample_runner.go createtables example-db
Node.js
npm start createtables example-db
Python
python create_tables.py example-db
C#
dotnet run createtables example-db
下一步是将数据写入数据库。
创建连接
您必须先创建与以下服务的连接,然后才能执行读写操作 PGAdapter 结合使用。您与 Spanner 的所有交互都必须 通过Connection
实现。数据库名称在连接字符串中指定。
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./create_connection.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar createconnection example-db
Go
go run sample_runner.go createconnection example-db
Node.js
npm start createconnection example-db
Python
python create_connection.py example-db
C#
dotnet run createconnection example-db
使用 DML 写入数据
您可以在读写事务中使用数据操纵语言 (DML) 插入数据。
这些示例展示了如何在 Spanner 上执行 DML 语句 使用 PostgreSQL 驱动程序。
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./write_data_with_dml.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar writeusingdml example-db
Go
go run sample_runner.go writeusingdml example-db
Node.js
npm start writeusingdml example-db
Python
python write_data_with_dml.py example-db
C#
dotnet run writeusingdml example-db
您应该会看到以下响应:
4 records inserted.
使用 DML 批次写入数据
PGAdapter 支持执行 DML 批次。发送多个 DML 语句减少 并提升应用的性能。
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./write_data_with_dml_batch.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar writeusingdmlbatch example-db
Go
go run sample_runner.go writeusingdmlbatch example-db
Node.js
npm start writeusingdmlbatch example-db
Python
python write_data_with_dml_batch.py example-db
C#
dotnet run writeusingdmlbatch example-db
您应该会看到:
3 records inserted.
使用变更写入数据
您还可以使用变更插入数据。
PGAdapter 会将 PostgreSQL COPY
命令转换为
变更。使用 COPY
是在
Spanner 数据库的数据。
COPY
操作默认为原子操作。原子操作
Spanner 受到提交大小限制。
如需了解详情,请参阅 CRUD 限制。
以下示例展示了如何执行非原子 COPY
操作。这样,
COPY
操作以超出提交大小限制。
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./write_data_with_copy.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar write example-db
Go
go run sample_runner.go write example-db
Node.js
npm start write example-db
Python
python write_data_with_copy.py example-db
C#
dotnet run write example-db
您应该会看到:
Copied 5 singers
Copied 5 albums
使用 SQL 查询数据
Spanner 支持使用 SQL 接口读取数据, 使用 Google Cloud CLI 或 以编程方式使用 PostgreSQL 驱动程序。
在命令行中
执行以下 SQL 语句,读取 Albums
表中所有列的值:
gcloud spanner databases execute-sql example-db --instance=test-instance \
--sql='SELECT singer_id, album_id, album_title 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
使用 PostgreSQL 驱动程序
除了在命令行上执行 SQL 语句外,还可以发出 使用 PostgreSQL 驱动程序以编程方式创建相同的 SQL 语句。
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./query_data.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar query example-db
Go
go run sample_runner.go query example-db
Node.js
npm start query example-db
Python
python query_data.py example-db
C#
dotnet run query 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
值的查询记录。
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./query_data_with_parameter.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar querywithparameter example-db
Go
go run sample_runner.go querywithparameter example-db
Node.js
npm start querywithparameter example-db
Python
python query_data_with_parameter.py example-db
C#
dotnet run querywithparameter example-db
您应该会看到以下结果:
12 Melissa Garcia
更新数据库架构
假设您需要将名为 MarketingBudget
的新列添加到 Albums
表。向现有表添加新列需要更新数据库架构。Spanner 支持对数据库进行架构更新,同时
以便继续处理流量架构更新不需要
数据库离线,且不会锁定整个表或列;您可以继续
在架构更新期间将数据写入数据库。详细了解“支持”
架构更新和架构更改性能,
进行架构更新。
添加列
您可以使用 Google Cloud CLI 或 以编程方式使用 PostgreSQL 驱动程序。
在命令行中
使用以下 ALTER TABLE
命令向表添加新列:
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='ALTER TABLE albums ADD COLUMN marketing_budget BIGINT'
您应该会看到:
Schema updating...done.
使用 PostgreSQL 驱动程序
使用 PostgreSQL 驱动程序执行 DDL 语句,以修改 架构:
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./add_column.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar addmarketingbudget example-db
Go
go run sample_runner.go addmarketingbudget example-db
Node.js
npm start addmarketingbudget example-db
Python
python add_column.py example-db
C#
dotnet run addmarketingbudget example-db
您应该会看到:
Added marketing_budget column
执行 DDL 批次
建议一次性执行多个架构修改。
您可以使用内置的
批量处理功能,具体方法是提交所有 DDL,
语句表示为一个以英文分号分隔的 SQL 字符串,或者使用
START BATCH DDL
和 RUN BATCH
语句。
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./ddl_batch.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar ddlbatch example-db
Go
go run sample_runner.go ddlbatch example-db
Node.js
npm start ddlbatch example-db
Python
python ddl_batch.py example-db
C#
dotnet run ddlbatch example-db
您应该会看到:
Added venues and concerts tables
将数据写入新列
以下代码可将数据写入新列。对于 Albums(1, 1)
键控的行,该代码会将 MarketingBudget
设置为 100000
;而对于 Albums(2, 2)
键控的行,该代码会将其设置为 500000
。
COPY
命令转换为
变更。COPY
命令默认转换为 Insert
变更。
执行 set spanner.copy_upsert=true
以将 COPY
命令转换为
InsertOrUpdate
项变更。这可用于更新现有数据
Spanner。
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./update_data_with_copy.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar update example-db
Go
go run sample_runner.go update example-db
Node.js
npm start update example-db
Python
python update_data_with_copy.py example-db
C#
dotnet run update example-db
您应该会看到:
Updated 2 albums
您也可以执行 SQL 查询来获取刚刚写入的值。
以下是执行查询的代码:
psql
Java
Go
Node.js
Python
C#
使用以下命令运行查询:
psql
PGDATABASE=example-db ./query_data_with_new_column.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar querymarketingbudget example-db
Go
go run sample_runner.go querymarketingbudget example-db
Node.js
npm start querymarketingbudget example-db
Python
python query_data_with_new_column.py example-db
C#
dotnet run querymarketingbudget example-db
您应该会看到:
1 1 100000
1 2 null
2 1 null
2 2 500000
2 3 null
更新数据
您可以在读写事务中使用 DML 来更新数据。
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./update_data_with_transaction.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar writewithtransactionusingdml example-db
Go
go run sample_runner.go writewithtransactionusingdml example-db
Node.js
npm start writewithtransactionusingdml example-db
Python
python update_data_with_transaction.py example-db
C#
dotnet run writewithtransactionusingdml example-db
您应该会看到:
Transferred marketing budget from Album 2 to Album 1
交易代码和请求代码
使用事务代码和请求代码
来排查 Spanner 中的事务和查询问题。您可以设置
交易代码以及请求代码与 SPANNER.TRANSACTION_TAG
和
SPANNER.STATEMENT_TAG
会话变量。
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./tags.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar tags example-db
Go
go run sample_runner.go tags example-db
Node.js
npm start tags example-db
Python
python tags.py example-db
C#
dotnet run tags example-db
使用只读事务检索数据
假设您要在同一时间戳执行多个读取操作。只读事务会遵从一致的事务提交历史记录前缀,因此您的应用始终可获得一致的数据。
将连接设置为只读或使用 SET TRANSACTION READ ONLY
SQL
语句来执行只读事务。
下面演示了如何运行查询并在同一只读事务中执行读取操作:
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./read_only_transaction.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar readonlytransaction example-db
Go
go run sample_runner.go readonlytransaction example-db
Node.js
npm start readonlytransaction example-db
Python
python read_only_transaction.py example-db
C#
dotnet run readonlytransaction example-db
您看到的输出结果应该类似于以下内容:
1 1 Total Junk
1 2 Go, Go, Go
2 1 Green
2 2 Forever Hold Your Peace
2 3 Terrified
2 2 Forever Hold Your Peace
1 2 Go, Go, Go
2 1 Green
2 3 Terrified
1 1 Total Junk
分区查询和 Data Boost
partitionQuery
API 将查询划分为较小的部分或分区,并使用多个
并行提取分区。每个分区都由
分区标记。PartitionQuery API 的延迟时间比标准
Query API,因为它仅适用于批量操作,例如导出或
扫描整个数据库。
数据提升 执行分析查询和数据导出,费用接近于零 对已预配 Spanner 实例上现有工作负载的影响。 Data Boost 仅支持分区查询。
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./data_boost.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar databoost example-db
Go
go run sample_runner.go databoost example-db
Node.js
npm start databoost example-db
Python
python data_boost.py example-db
C#
dotnet run databoost example-db
如需详细了解如何运行分区查询以及如何搭配使用 Data Boost 和 PGAdapter,请参阅: Data Boost 和分区查询语句
分区 DML
分区数据操纵语言 (DML) 是 适用于以下类型的批量更新和删除操作:
- 定期清理和垃圾回收。
- 使用默认值回填新列。
psql
Java
Go
Node.js
Python
C#
使用以下命令运行该示例:
psql
PGDATABASE=example-db ./partitioned_dml.sh
Java
java -jar target/pgadapter-snippets/pgadapter-samples.jar partitioneddml example-db
Go
go run sample_runner.go partitioneddml example-db
Node.js
npm start partitioneddml example-db
Python
python partitioned_dml.py example-db
C#
dotnet run datpartitioneddmlboost example-db
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生额外费用,请删除数据库和您创建的实例。
删除数据库
如果您删除一个实例,则该实例中的所有数据库都会自动删除。 本步骤演示了如何在不删除实例的情况下删除数据库(您仍需为该实例付费)。
在命令行中
gcloud spanner databases delete example-db --instance=test-instance
使用 Google Cloud 控制台
前往 Google Cloud 控制台中的 Spanner 实例页面。
点击实例。
点击您想删除的数据库。
在数据库详细信息页面中,点击删除。
确认您要删除数据库并点击删除。
删除实例
删除实例会自动删除在该实例中创建的所有数据库。
在命令行中
gcloud spanner instances delete test-instance
使用 Google Cloud 控制台
前往 Google Cloud 控制台中的 Spanner 实例页面。
点击您的实例。
点击删除。
确认您要删除实例并点击删除。
后续步骤
了解如何通过虚拟机实例访问 Spanner。
要了解授权和身份验证凭据,请参阅进行身份验证 使用客户端库的 Cloud 服务。
详细了解 Spanner 架构设计最佳实践。