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