Spanner数据库操作 #
一、数据库概述 #
1.1 数据库概念 #
text
Spanner数据库层次结构
├── Instance (实例)
│ ├── 计算资源配置
│ ├── 节点数量
│ └── 区域配置
│
├── Database (数据库)
│ ├── Schema定义
│ ├── 表和索引
│ └── 数据存储
│
└── Table (表)
├── 主键定义
├── 列定义
└── 约束条件
1.2 数据库限制 #
| 限制项 | 值 |
|---|---|
| 每个实例最大数据库数 | 100 |
| 数据库名长度 | 2-30字符 |
| 数据库名字符 | 字母、数字、下划线、连字符 |
| 数据库大小 | 无限制 |
二、创建数据库 #
2.1 使用GCP控制台 #
text
步骤:
1. 导航到Spanner页面
2. 选择实例
3. 点击"创建数据库"
4. 输入数据库名称
5. 选择数据库方言
- Google标准SQL
- PostgreSQL
6. (可选)定义Schema
7. 点击"创建"
2.2 使用gcloud CLI #
bash
# 创建数据库(Google标准SQL)
gcloud spanner databases create my-database \
--instance=my-instance
# 创建数据库(PostgreSQL)
gcloud spanner databases create my-pg-database \
--instance=my-instance \
--database-dialect=POSTGRESQL
# 创建数据库并定义Schema
gcloud spanner databases create my-database \
--instance=my-instance \
--ddl="CREATE TABLE users (user_id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (user_id)"
2.3 使用SQL #
sql
-- Google标准SQL
CREATE DATABASE my_database;
-- 创建数据库时设置选项
CREATE DATABASE my_database
OPTIONS (
database_dialect = 'GOOGLE_STANDARD_SQL'
);
2.4 使用客户端库 #
java
// Java
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.Instance;
import com.google.cloud.spanner.Database;
Instance instance = spanner.getInstanceAdminClient().getInstance(instanceId);
Operation<Database, CreateDatabaseMetadata> op = instance.createDatabase(
databaseId,
Arrays.asList(
"CREATE TABLE users (" +
" user_id INT64 NOT NULL," +
" name STRING(100) NOT NULL" +
") PRIMARY KEY (user_id)"
)
);
Database database = op.waitFor().getResult();
python
# Python
from google.cloud import spanner
spanner_client = spanner.Client(project_id)
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)
operation = database.create()
operation.result() # 等待完成
go
// Go
import (
"context"
"cloud.google.com/go/spanner/admin/database/apiv1"
)
func createDatabase(ctx context.Context, instanceID, databaseID string) error {
adminClient, _ := database.NewDatabaseAdminClient(ctx)
defer adminClient.Close()
op, _ := adminClient.CreateDatabase(ctx, &databasepb.CreateDatabaseRequest{
Parent: fmt.Sprintf("projects/%s/instances/%s", projectID, instanceID),
CreateStatement: fmt.Sprintf("CREATE DATABASE `%s`", databaseID),
})
_, err := op.Wait(ctx)
return err
}
三、查看数据库 #
3.1 列出所有数据库 #
bash
# 使用gcloud CLI
gcloud spanner databases list --instance=my-instance
text
输出示例:
DATABASE_ID STATE
my-database READY
my-pg-database READY
3.2 查看数据库详情 #
bash
# 使用gcloud CLI
gcloud spanner databases describe my-database \
--instance=my-instance
text
输出示例:
name: projects/my-project/instances/my-instance/databases/my-database
state: READY
createTime: '2024-03-27T10:00:00.000000000Z'
databaseDialect: GOOGLE_STANDARD_SQL
3.3 查看数据库Schema #
bash
# 使用gcloud CLI
gcloud spanner databases ddl describe my-database \
--instance=my-instance
sql
-- 输出示例
CREATE TABLE users (
user_id INT64 NOT NULL,
name STRING(100) NOT NULL,
) PRIMARY KEY (user_id);
3.4 使用SQL查询 #
sql
-- 查看数据库信息(通过系统表)
SELECT * FROM INFORMATION_SCHEMA.DATABASES;
-- 查看所有表
SELECT table_name
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = '';
-- 查看表结构
SELECT column_name, data_type, is_nullable
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'users';
四、修改数据库 #
4.1 更新Schema #
bash
# 使用gcloud CLI添加表
gcloud spanner databases ddl update my-database \
--instance=my-instance \
--ddl="CREATE TABLE orders (
order_id INT64 NOT NULL,
user_id INT64 NOT NULL,
amount FLOAT64
) PRIMARY KEY (order_id)"
# 添加多个DDL语句
gcloud spanner databases ddl update my-database \
--instance=my-instance \
--ddl="CREATE TABLE products (
product_id INT64 NOT NULL,
name STRING(100)
) PRIMARY KEY (product_id)" \
--ddl="CREATE INDEX idx_products_name ON products(name)"
4.2 使用SQL更新Schema #
sql
-- 添加列
ALTER TABLE users ADD COLUMN email STRING(100);
-- 删除列
ALTER TABLE users DROP COLUMN email;
-- 添加索引
CREATE INDEX idx_users_email ON users(email);
-- 删除索引
DROP INDEX idx_users_email;
-- 创建交错表
CREATE TABLE orders (
user_id INT64 NOT NULL,
order_id INT64 NOT NULL,
amount FLOAT64
) PRIMARY KEY (user_id, order_id),
INTERLEAVE IN PARENT users ON DELETE CASCADE;
4.3 批量Schema更新 #
java
// Java批量更新
import com.google.cloud.spanner.DatabaseAdminClient;
import com.google.spanner.admin.database.v1.UpdateDatabaseDdlRequest;
List<String> statements = Arrays.asList(
"CREATE TABLE products (product_id INT64 NOT NULL, name STRING(100)) PRIMARY KEY (product_id)",
"CREATE TABLE order_items (order_id INT64 NOT NULL, product_id INT64 NOT NULL, quantity INT64) PRIMARY KEY (order_id, product_id)"
);
Operation<Void, UpdateDatabaseDdlMetadata> operation =
adminClient.updateDatabaseDdl(instanceId, databaseId, statements, null);
operation.waitFor();
五、删除数据库 #
5.1 使用GCP控制台 #
text
步骤:
1. 导航到Spanner页面
2. 选择实例
3. 选择要删除的数据库
4. 点击"删除"
5. 输入数据库名称确认
6. 点击"删除"
5.2 使用gcloud CLI #
bash
# 删除数据库
gcloud spanner databases delete my-database \
--instance=my-instance
5.3 使用客户端库 #
java
// Java
DatabaseAdminClient adminClient = spanner.getDatabaseAdminClient();
adminClient.dropDatabase(instanceId, databaseId);
python
# Python
database = instance.database(database_id)
database.drop()
go
// Go
adminClient.DropDatabase(ctx, &databasepb.DropDatabaseRequest{
Database: fmt.Sprintf("projects/%s/instances/%s/databases/%s", projectID, instanceID, databaseID),
})
5.4 注意事项 #
text
删除数据库前注意:
├── 数据无法恢复(除非有备份)
├── 删除操作不可逆
├── 确保没有应用正在使用
└── 考虑先创建备份
六、数据库备份 #
6.1 创建备份 #
bash
# 创建备份
gcloud spanner backups create my-backup \
--instance=my-instance \
--database=my-database \
--retention-period=7d \
--expiration-date=2024-04-03T00:00:00Z
6.2 查看备份 #
bash
# 列出备份
gcloud spanner backups list --instance=my-instance
# 查看备份详情
gcloud spanner backups describe my-backup \
--instance=my-instance
6.3 从备份恢复 #
bash
# 从备份恢复数据库
gcloud spanner databases restore my-restored-db \
--instance=my-instance \
--source-backup=my-backup
6.4 删除备份 #
bash
# 删除备份
gcloud spanner backups delete my-backup \
--instance=my-instance
七、数据库复制 #
7.1 创建副本 #
bash
# 创建数据库副本(在同一实例内)
gcloud spanner databases create my-database-copy \
--instance=my-instance \
--ddl="$(gcloud spanner databases ddl describe my-database --instance=my-instance)"
7.2 跨实例复制 #
text
跨实例复制方式:
├── 导出数据到Cloud Storage
├── 使用Dataflow导入
├── 使用客户端库复制
└── 使用变更流同步
八、数据库版本历史 #
8.1 查看版本历史 #
sql
-- 查看Schema版本历史
SELECT * FROM INFORMATION_SCHEMA.TABLES_OPTIONS;
8.2 时间点查询 #
sql
-- 使用时间戳查询历史数据
SELECT * FROM users
FOR SYSTEM_TIME AS OF TIMESTAMP '2024-03-27T10:00:00Z';
-- 使用时间范围查询
SELECT * FROM users
FOR SYSTEM_TIME BETWEEN
TIMESTAMP '2024-03-27T09:00:00Z' AND
TIMESTAMP '2024-03-27T10:00:00Z';
九、数据库统计信息 #
9.1 查看统计信息 #
sql
-- 查看表大小
SELECT
table_name,
row_count,
size_bytes
FROM INFORMATION_SCHEMA.TABLE_STATS;
-- 查看列统计
SELECT
table_name,
column_name,
total_rows,
distinct_rows
FROM INFORMATION_SCHEMA.COLUMN_STATS;
-- 查看索引统计
SELECT
table_name,
index_name,
row_count,
size_bytes
FROM INFORMATION_SCHEMA.INDEX_STATS;
9.2 查询优化统计 #
sql
-- 查看查询统计
SELECT
text,
execution_count,
avg_latency_seconds,
avg_rows
FROM INFORMATION_SCHEMA.QUERY_STATS_TOP_HOUR
ORDER BY avg_latency_seconds DESC
LIMIT 10;
十、数据库权限管理 #
10.1 IAM权限 #
bash
# 授予数据库用户权限
gcloud spanner databases add-iam-policy-binding my-database \
--instance=my-instance \
--member="user:user@example.com" \
--role="roles/spanner.databaseUser"
# 授予数据库管理员权限
gcloud spanner databases add-iam-policy-binding my-database \
--instance=my-instance \
--member="user:admin@example.com" \
--role="roles/spanner.databaseAdmin"
10.2 细粒度权限 #
sql
-- 创建角色
CREATE ROLE read_only;
-- 授予表权限
GRANT SELECT ON TABLE users TO ROLE read_only;
-- 授予角色给用户
GRANT ROLE read_only TO USER 'reader@example.com';
十一、最佳实践 #
11.1 命名规范 #
text
数据库名称规范:
├── 使用小写字母
├── 使用下划线分隔单词
├── 长度2-30字符
├── 以字母开头
└── 避免保留字
示例:
├── ✅ my_database
├── ✅ ecommerce_prod
├── ❌ MyDatabase
├── ❌ my-database
└── ❌ 1database
11.2 Schema设计建议 #
text
Schema设计原则:
├── 先设计后创建
├── 合理选择主键
├── 使用交错表优化关联
├── 避免热点主键
└── 合理设置索引
11.3 环境管理 #
text
环境隔离建议:
├── 开发环境: 使用模拟器或独立实例
├── 测试环境: 独立实例,小节点配置
├── 预发布环境: 与生产相同配置
└── 生产环境: 多节点,多区域(如需要)
十二、总结 #
数据库操作要点:
| 操作 | 命令/方法 |
|---|---|
| 创建数据库 | gcloud spanner databases create |
| 列出数据库 | gcloud spanner databases list |
| 查看详情 | gcloud spanner databases describe |
| 更新Schema | gcloud spanner databases ddl update |
| 删除数据库 | gcloud spanner databases delete |
| 创建备份 | gcloud spanner backups create |
| 恢复数据库 | gcloud spanner databases restore |
最佳实践:
text
1. 合理命名
└── 遵循命名规范,便于管理
2. 定期备份
└── 设置自动备份策略
3. 权限管理
└── 遵循最小权限原则
4. 监控告警
└── 配置关键指标监控
5. Schema版本控制
└── 使用版本控制管理DDL变更
下一步,让我们学习表操作!
最后更新:2026-03-27