目标
本教程将介绍如何使用 Spanner ADO.NET 驱动程序完成以下步骤:
- 创建 Spanner 实例和数据库。
- 写入、读取数据库中的数据和对数据执行 SQL 查询。
- 更新数据库架构。
- 使用读写事务更新数据。
- 向数据库添加二级索引。
- 使用索引来读取数据和对数据执行 SQL 查询。
- 使用只读事务检索数据。
费用
本教程使用 Spanner,它是Google Cloud的收费组件。如需了解使用 Spanner 的费用,请参阅价格。
准备工作
完成设置中介绍的步骤,包括创建和设置默认 Google Cloud 项目、启用结算功能、启用 Cloud Spanner API 以及设置 OAuth 2.0 来获取身份验证凭据以使用 Cloud Spanner API。
尤其要确保运行 gcloud auth
application-default login,以便使用身份验证凭据设置本地开发环境。
准备本地 ADO.NET 环境
在开发机器上下载并安装 .NET(如果尚未安装)。
将示例代码库克隆到您的本地机器:
git clone https://github.com/googleapis/dotnet-spanner-entity-framework.git切换到包含 Spanner ADO.NET 驱动程序示例代码的目录:
cd dotnet-spanner-entity-framework/spanner-ado-net/spanner-ado-net-getting-started-guide
创建实例
在首次使用 Spanner 时,必须创建一个实例,实例是 Spanner 数据库使用的资源分配单位。创建实例时,请选择一个实例配置(决定数据的存储位置),同时选择要使用的节点数(决定实例中服务资源和存储资源的数量)。
如需了解如何使用以下任一方法创建 Spanner 实例,请参阅创建实例。您可以将实例命名为 test-instance,以便将其用于本文档中引用名为 test-instance 的实例的其他主题。
- Google Cloud CLI
- Google Cloud 控制台
- 客户端库(C++、C#、Go、Java、Node.js、PHP、Python 或 Ruby)
浏览示例文件
示例代码库包含一个示例,展示了如何将 Spanner 与 ADO.NET 搭配使用。
请浏览SampleRunner.cs 文件,其中说明了如何使用 Spanner。代码展示了如何创建和使用新数据库。数据使用架构和数据模型页面中显示的示例架构。
创建数据库
GoogleSQL
gcloud spanner databases create example-db --instance=test-instance
PostgreSQL
gcloud spanner databases create example-db --instance=test-instance \
--database-dialect=POSTGRESQL
您应该会看到:
Creating database...done.
创建表
以下代码会在数据库中创建两个表。
GoogleSQL
PostgreSQL
使用以下命令运行示例:
GoogleSQL
dotnet run createtables projects/PROJECT_ID/instances/test-instance/databases/example-db
PostgreSQL
dotnet run createtablespg projects/PROJECT_ID/instances/test-instance/databases/example-db
下一步是将数据写入数据库。
创建连接
您必须先创建一个连接,然后才能与 Spanner 进行交互。数据库名称和其他连接属性在 ADO.NET 连接字符串中指定。GoogleSQL
PostgreSQL
使用 DML 写入数据
您可以在读写事务中使用数据操纵语言 (DML) 插入数据。
使用 DbCommand#ExecuteNonQuery 方法来执行 DML 语句。
GoogleSQL
PostgreSQL
使用以下命令运行示例:
GoogleSQL
dotnet run dmlwrite projects/PROJECT_ID/instances/test-instance/databases/example-db
PostgreSQL
dotnet run dmlwritepg projects/PROJECT_ID/instances/test-instance/databases/example-db
结果应显示:
4 records inserted.
使用变更写入数据
您还可以使用变更插入数据。
您可以使用 batch.CreateInsertCommand() 方法插入数据,此方法会创建一个新的 SpannerBatchCommand 以将行插入表中。SpannerBatchCommand.ExecuteNonQueryAsync() 方法将向表中添加新行。
以下代码展示了如何使用变更写入数据:
GoogleSQL
PostgreSQL
使用 write 参数运行以下示例:
GoogleSQL
dotnet run write projects/PROJECT_ID/instances/test-instance/databases/example-db
PostgreSQL
dotnet run writepg projects/PROJECT_ID/instances/test-instance/databases/example-db
使用 SQL 查询数据
Spanner 支持使用 SQL 接口读取数据,您可以使用 Google Cloud CLI 在命令行中访问该接口,也可以使用 Spanner ADO.NET 驱动程序以编程方式访问该接口。
在命令行中
执行以下 SQL 语句,读取 Albums 表中所有列的值:
GoogleSQL
gcloud spanner databases execute-sql example-db --instance=test-instance \
--sql='SELECT SingerId, AlbumId, AlbumTitle FROM Albums'
PostgreSQL
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
使用 Spanner ADO.NET 驱动程序
除了在命令行中执行 SQL 语句外,还可以使用 Spanner ADO.NET 驱动程序以编程方式发出相同的 SQL 语句。
以下方法用于执行 SQL 查询:DbCommand类中的ExecuteReader方法:使用此方法可执行会返回行的 SQL 语句,例如包含THEN RETURN子句的查询或 DML 语句。DbDataReader类:使用此类访问由 SQL 语句返回的数据。
以下示例使用了 ExecuteReaderAsync 方法:
GoogleSQL
PostgreSQL
使用以下命令运行示例:
GoogleSQL
dotnet run query projects/PROJECT_ID/instances/test-instance/databases/example-db
PostgreSQL
dotnet run querypg projects/PROJECT_ID/instances/test-instance/databases/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 值的记录。
Spanner ADO.NET 驱动程序支持位置查询参数和命名查询参数。SQL 语句中的 ? 表示位置查询参数。向 DbCommand 的 Parameters 添加查询参数值。例如:
GoogleSQL
PostgreSQL
使用以下命令运行示例:
GoogleSQL
dotnet run querywithparameter projects/PROJECT_ID/instances/test-instance/databases/example-db
PostgreSQL
dotnet run querywithparameterpg projects/PROJECT_ID/instances/test-instance/databases/example-db
结果会显示以下内容:
12 Melissa Garcia
更新数据库架构
假设您需要将名为 MarketingBudget 的新列添加到 Albums 表。向现有表添加新列需要更新数据库架构。Spanner 支持在数据库继续处理流量的同时,对数据库进行架构更新。架构更新不需要使数据库离线,并且不会锁定整个表或列;在架构更新期间,您可以继续将数据写入数据库。如需详细了解支持的架构更新和架构更改性能,请参阅更新架构。
添加列
您可以使用 Google Cloud CLI 在命令行中添加列,也可以使用 Spanner ADO.NET 驱动程序以编程方式添加列。
在命令行中
使用以下 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 marketing_budget bigint'
您应该会看到:
Schema updating...done.
使用 Spanner ADO.NET 驱动程序
使用ExecuteNonQueryAsync 方法修改架构:
GoogleSQL
PostgreSQL
使用以下命令运行示例:
GoogleSQL
dotnet run addcolumn projects/PROJECT_ID/instances/test-instance/databases/example-db
PostgreSQL
dotnet run addcolumnpg projects/PROJECT_ID/instances/test-instance/databases/example-db
结果会显示以下内容:
Added MarketingBudget column.
执行 DDL 批处理
我们建议您在一个批处理操作中执行多个架构修改。使用 ADO.NET CreateBatch 方法创建批处理。以下示例会在一个批处理操作中创建两个表:
GoogleSQL
PostgreSQL
使用以下命令运行示例:
GoogleSQL
dotnet run ddlbatch projects/PROJECT_ID/instances/test-instance/databases/example-db
PostgreSQL
dotnet run ddlbatchpg projects/PROJECT_ID/instances/test-instance/databases/example-db
结果会显示以下内容:
Added Venues and Concerts tables.
将数据写入新列
以下代码可将数据写入新列。对于 Albums(1, 1) 键控的行,该代码会将 MarketingBudget 设置为 100000;而对于 Albums(2, 2) 键控的行,该代码会将其设置为 500000。
GoogleSQL
PostgreSQL
使用以下命令运行示例:
GoogleSQL
dotnet run update projects/PROJECT_ID/instances/test-instance/databases/example-db
PostgreSQL
dotnet run updatepg projects/PROJECT_ID/instances/test-instance/databases/example-db
结果会显示以下内容:
Updated 2 albums
您也可以执行 SQL 查询来获取刚刚写入的值。
以下示例使用 ExecuteReaderAsync 方法执行查询:
GoogleSQL
PostgreSQL
如需执行此查询,请运行以下命令:
GoogleSQL
dotnet run querymarketingbudget projects/PROJECT_ID/instances/test-instance/databases/example-db
PostgreSQL
dotnet run querymarketingbudgetpg projects/PROJECT_ID/instances/test-instance/databases/example-db
您应该会看到:
1 1 100000
1 2 null
2 1 null
2 2 500000
2 3 null
更新数据
您可以在读写事务中使用 DML 来更新数据。
调用 connection.BeginTransactionAsync() 可在 ADO.NET 中执行读写事务。
GoogleSQL
PostgreSQL
使用以下命令运行示例:
GoogleSQL
dotnet run writewithtransactionusingdml projects/PROJECT_ID/instances/test-instance/databases/example-db
PostgreSQL
dotnet run writewithtransactionusingdmlpg projects/PROJECT_ID/instances/test-instance/databases/example-db
事务标记和请求标记
使用事务标记和请求标记可排查 Spanner 中的事务和查询问题。您可以在 Transaction 对象上设置标记以向 Spanner 发送事务标记,也可以在 DbCommand 对象上设置标记以向 Spanner 发送请求标记。例如:
GoogleSQL
PostgreSQL
使用以下命令运行示例:
GoogleSQL
dotnet run tags projects/PROJECT_ID/instances/test-instance/databases/example-db
PostgreSQL
dotnet run tagspg projects/PROJECT_ID/instances/test-instance/databases/example-db
使用只读事务检索数据
假设您要在同一时间戳执行多个读取操作。只读事务会观察事务提交记录的一致前缀,以便应用始终获得一致的数据。
调用 connection.BeginReadOnlyTransactionAsync() 可执行只读事务。
下面演示了如何运行查询并在同一只读事务中执行读取操作:
GoogleSQL
PostgreSQL
使用以下命令运行示例:
GoogleSQL
dotnet run readonlytransaction projects/PROJECT_ID/instances/test-instance/databases/example-db
PostgreSQL
dotnet run readonlytransactionpg projects/PROJECT_ID/instances/test-instance/databases/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
分区 DML
分区数据操纵语言 (DML) 旨在用于以下类型的批量更新和删除:
- 定期清理和垃圾回收。
- 使用默认值回填新列。
GoogleSQL
PostgreSQL
使用以下命令运行示例:
GoogleSQL
dotnet run pdml projects/PROJECT_ID/instances/test-instance/databases/example-db
PostgreSQL
dotnet run pdmlpg projects/PROJECT_ID/instances/test-instance/databases/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 架构设计最佳实践。