目标
本教程将介绍如何使用适用于 PHP 的 Cloud Spanner 客户端库完成以下步骤:
- 创建 Cloud Spanner 实例和数据库。
- 写入、读取数据库中的数据和对数据执行 SQL 查询。
- 更新数据库架构。
- 使用读写事务更新数据。
- 向数据库添加二级索引。
- 使用索引来读取数据和对数据执行 SQL 查询。
- 使用只读事务检索数据。
费用
本教程使用 Cloud Spanner,它是 Google Cloud 的收费组件。如需了解使用 Cloud Spanner 的费用,请参阅价格。
准备工作
完成设置中介绍的步骤,包括创建和设置默认 Google Cloud 项目、启用结算功能、启用 Cloud Spanner API 以及设置 OAuth 2.0 来获取身份验证凭据以使用 Cloud Spanner API。
尤其要确保运行 gcloud auth
application-default login
,以便使用身份验证凭据设置本地开发环境。
准备本地 PHP 环境
按照服务帐号中的步骤将一个服务帐号设置为您的应用默认凭据。完成这些步骤后,您应该能够同时获得一个服务帐号密钥文件(采用 JSON 格式)和一个
GOOGLE_APPLICATION_CREDENTIALS
环境变量,您可以通过它们向 Cloud Spanner API 进行身份验证。在开发机器上安装以下内容(如果尚未安装):
将示例应用代码库克隆到本地机器上:
git clone https://github.com/GoogleCloudPlatform/php-docs-samples
或者,您也可以以 zip 文件的形式下载该示例并将其解压缩。
切换到包含 Cloud Spanner 示例代码的目录:
cd php-docs-samples/spanner
安装依赖项:
composer install
此命令将安装 PHP 版 Cloud Spanner 客户端库,您可以通过运行
composer require google/cloud-spanner
将其添加到任何项目。
创建实例
在首次使用 Cloud Spanner 时,必须创建一个实例,实例是 Cloud Spanner 数据库使用的资源分配单位。创建实例时,请选择一个实例配置(决定数据的存储位置),同时选择要使用的节点数(决定实例中服务资源和存储资源的数量)。
执行以下命令,在区域 us-central1
中创建具有 1 个节点的 Cloud 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.
浏览示例文件
示例代码库包含一个示例,展示了如何通过 PHP 使用 Cloud Spanner。
请查看 src/create_database.php
和 src/add_column.php
中的函数,它们展示了如何创建数据库和修改数据库架构。数据使用架构和数据模型页面中显示的示例架构。
创建数据库
通过在命令行运行以下命令,在名为 test-instance
的实例中创建名为 example-db
的数据库。
php spanner.php create-database test-instance example-db
您应该会看到:
Created database example-db on instance test-instance
您刚刚创建了一个 Cloud Spanner 数据库。以下是创建数据库的代码。
该代码还为一个基本的音乐应用定义了两个表:Singers
和 Albums
。本页面会一直用到这两个表。请查看示例架构(如果您还没有查看)。
下一步是将数据写入数据库。
创建数据库客户端
如需进行读写操作,您需要获取Google\Cloud\Spanner\Database
的实例。
您可以将 Database
视为数据库连接:您与 Cloud Spanner 的所有交互都必须通过 Database
进行。通常,您可以在应用启动时创建 Database
,然后重复使用该 Database
来读取、写入和执行事务。每个客户端均使用 Cloud Spanner 中的资源。
如果您在同一应用中创建多个客户端,则应调用 Database::close
来清理客户端的资源,包括网络连接(一旦不再需要这些资源就立即清理)。
如需了解详情,请参阅 Database
参考文档。
使用 DML 写入数据
您可以在读写事务中使用数据操纵语言 (DML) 插入数据。
使用 executeUpdate()
方法来执行 DML 语句。
使用 write-data-with-dml
命令运行示例。
php spanner.php write-data-with-dml test-instance example-db
您应该会看到:
Inserted 4 row(s).
使用变更写入数据
您还可以使用变更插入数据。
您可以使用 Database::insertBatch
方法来写入数据。insertBatch
会向表中添加新行。单个批处理中的所有插入均以原子方式应用。
此代码演示了如何使用变更写入数据:
使用 insert-data
命令运行示例。
php spanner.php insert-data test-instance example-db
您应该会看到:
Inserted data.
使用 SQL 查询数据
Cloud Spanner 支持使用原生 SQL 接口读取数据,您可以使用 Google Cloud CLI 在命令行中使用该接口,也可以通过 PHP 版 Cloud 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
使用 PHP 版 Cloud Spanner 客户端库
除了在命令行中执行 SQL 语句外,还可以使用适用于 PHP 的 Cloud Spanner 客户端库以编程方式发出相同的 SQL 语句。
使用Database::execute()
运行 SQL 查询。
下面演示了如何发出查询并访问数据:
使用 query-data
命令运行示例。
php spanner.php query-data test-instance example-db
您应该会看到以下结果:
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
您的结果不一定按此顺序排列。如果需要指定结果的顺序,请使用 ORDER BY
子句,如 SQL 最佳做法中所述。
使用 SQL 参数进行查询
您可以使用支持的 SQL 类型在 SQL 语句中添加自定义值。
以下示例演示了如何在 WHERE
子句中使用 @lastName
作为参数来查询包含特定 LastName
值的记录。
使用 query-data-with-parameter 命令运行该示例。
php spanner.php query-data-with-parameter test-instance example-db
您应该会看到以下结果:
SingerId: 12, FirstName: Melissa, LastName: Garcia
使用读取 API 读取数据
除 Cloud Spanner 的 SQL 接口外,Cloud Spanner 还支持读取接口。
使用 Database::read()
从数据库中读取行。使用 KeySet
对象定义要读取的键和键范围的集合。
下面演示了如何读取数据:
使用 read-data
命令运行示例。
php spanner.php read-data test-instance example-db
您看到的输出结果应该类似于以下内容:
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
更新数据库架构
假设您需要将名为 MarketingBudget
的新列添加到 Albums
表。向现有表添加新列需要更新数据库架构。Cloud Spanner 支持在数据库继续处理流量的同时,对数据库进行架构更新。架构更新不需要使数据库离线,并且不会锁定整个表或列;在架构更新期间,您可以继续将数据写入数据库。如需详细了解支持的架构更新和架构更改性能,请参阅架构更新。
添加列
您可以使用 Google Cloud CLI 在命令行中添加列,也可以使用 PHP 版 Cloud Spanner 客户端库以编程方式添加列。
在命令行中
使用以下 ALTER TABLE
命令向表添加新列:
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='ALTER TABLE Albums ADD COLUMN MarketingBudget INT64'
您应该会看到:
Schema updating...done.
使用 PHP 版 Cloud Spanner 客户端库
使用 Database::updateDdl
修改架构:
使用 add-column
命令运行示例。
php spanner.php add-column test-instance example-db
您应该会看到:
Added the MarketingBudget column.
将数据写入新列
以下代码可将数据写入新列。对于键分别为 Albums(1, 1)
和 Albums(2, 2)
的行,该代码会将 MarketingBudget
分别设置为 100000
和 500000
。
使用 update-data
命令运行示例。
php spanner.php update-data test-instance example-db
您应该会看到:
Updated data.
您还可以执行 SQL 查询或读取调用来获取刚才写入的值。
以下是执行查询的代码:
如需执行此查询,请使用 query-data-with-new-column
参数运行示例。
php spanner.php query-data-with-new-column test-instance example-db
您应该会看到:
SingerId: 1, AlbumId: 1, MarketingBudget: 100000
SingerId: 1, AlbumId: 2, MarketingBudget: 0
SingerId: 2, AlbumId: 1, MarketingBudget: 0
SingerId: 2, AlbumId: 2, MarketingBudget: 500000
SingerId: 2, AlbumId: 3, MarketingBudget: 0
更新数据
您可以在读写事务中使用 DML 来更新数据。
使用 executeUpdate()
方法来执行 DML 语句。
使用 write-data-with-dml-transaction
命令运行示例。
php spanner.php write-data-with-dml-transaction test-instance example-db
您应该会看到:
Transaction complete.
使用二级索引
假设您想要提取 Albums
表中 AlbumTitle
值在特定范围内的所有行。您可以使用 SQL 语句或读取调用读取 AlbumTitle
列中的所有值,然后舍弃不符合条件的行。不过,执行全表扫描费用高昂,特别是对内含大量行的表来说更是如此。相反,如果对表创建二级索引,按非主键列进行搜索,则可以提高行检索速度。
向现有表添加二级索引需要更新架构。与其他架构更新一样,Cloud Spanner 支持在数据库继续处理流量的同时添加索引。Cloud Spanner 会使用您的现有数据自动回填索引。回填可能需要几分钟时间才能完成,但在此过程中,您无需使数据库离线,也无需避免写入已编入索引的表。如需了解详情,请参阅索引回填。
添加二级索引后,Cloud Spanner 会自动使用该索引进行 SQL 查询,使用该索引后,查询运行速度可能会提高。如果使用读取接口,则必须指定要使用的索引。
添加二级索引
您可以使用 gcloud
CLI 在命令行中添加列,也可以使用 PHP 版 Cloud Spanner 客户端库以编程方式添加列。
在命令行中
使用以下 CREATE INDEX
命令向数据库添加索引:
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)'
您应该会看到:
Schema updating...done.
使用 PHP 版 Cloud Spanner 客户端库
使用 Database::updateDdl
添加索引:
使用 create-index
命令运行示例。
php spanner.php create-index test-instance example-db
添加索引可能需要几分钟时间。添加索引后,您应该会看到:
Added the AlbumsByAlbumTitle index.
使用索引进行读取
对于 SQL 查询,Cloud Spanner 会自动使用适当的索引。在读取接口中,您必须在请求中指定索引。
要在读取接口中使用索引,请使用 Database::read
方法。
使用 read-data-with-index
命令运行示例。
php spanner.php read-data-with-index test-instance example-db
您应该会看到:
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
添加带 STORING 子句的索引
您可能已经注意到,上面的读取示例不包括读取 MarketingBudget
列。这是因为,Cloud Spanner 的读取接口不支持将索引与数据表联接起来查找未存储在索引中的值。
请创建 AlbumsByAlbumTitle
的备用定义,用于将 MarketingBudget
的副本存储到索引中。
在命令行中
gcloud spanner databases ddl update example-db --instance=test-instance \
--ddl='CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget)'
添加索引可能需要几分钟时间。添加索引后,您应该会看到:
Schema updating...done.
使用 PHP 版 Cloud Spanner 客户端库
使用Database::updateDdl
添加带 STORING
子句的索引:
使用 create-storing-index
命令运行示例。
php spanner.php create-storing-index test-instance example-db
您应该会看到:
Added the AlbumsByAlbumTitle2 index.
现在,当您执行读取操作时便可从 AlbumsByAlbumTitle2
索引中提取所有 AlbumId
、AlbumTitle
和 MarketingBudget
列:
使用 read-data-with-storing-index
命令运行示例。
php spanner.php read-data-with-storing-index test-instance example-db
您看到的输出结果应该类似于以下内容:
AlbumId: 2, AlbumTitle: Forever Hold your Peace, MarketingBudget: 300000
AlbumId: 2, AlbumTitle: Go, Go, Go, MarketingBudget: 0
AlbumId: 1, AlbumTitle: Green, MarketingBudget: 0
AlbumId: 3, AlbumTitle: Terrified, MarketingBudget: 0
AlbumId: 1, AlbumTitle: Total Junk, MarketingBudget: 300000
使用只读事务检索数据
假设您要在同一时间戳执行多个读取操作。只读事务会遵从一致的事务提交历史记录前缀,因此您的应用始终可获得一致的数据。
使用 Snapshot
对象执行只读事务。使用 Database::snapshot
方法来获取 Snapshot
对象。
下面演示了如何运行查询并在同一只读事务中执行读取操作:
使用 read-only-transaction
命令运行示例。
php spanner.php read-only-transaction test-instance example-db
您看到的输出结果应该类似于以下内容:
Results from first read:
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
Results from second read:
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
清理
为避免因本教程中使用的资源导致您的 Google Cloud 帐号产生额外费用,请删除数据库和您创建的实例。
删除数据库
如果您删除一个实例,则该实例中的所有数据库都会自动删除。 本步骤演示了如何在不删除实例的情况下删除数据库(您仍需为该实例付费)。
在命令行中
gcloud spanner databases delete example-db --instance=test-instance
使用 Cloud Console
转到 Google Cloud Console 中的 Cloud Spanner 实例页面。
点击实例。
点击您想删除的数据库。
在数据库详细信息页面中,点击删除。
确认您要删除数据库并点击删除。
删除实例
删除实例会自动删除在该实例中创建的所有数据库。
在命令行中
gcloud spanner instances delete test-instance
使用 Cloud Console
转到 Google Cloud Console 中的 Cloud Spanner 实例页面。
点击您的实例。
点击删除。
确认您要删除实例并点击删除。
后续步骤
在虚拟机实例中访问 Cloud Spanner:创建一个可访问 Cloud Spanner 数据库的虚拟机实例。
在身份验证入门中了解授权和身份验证凭据。
了解更多 Cloud Spanner 概念。