docs: 添加生产环境数据库迁移步骤

- 新增二、生产环境数据库迁移章节
- 记录测试/生产环境数据量对比
- 添加备份和迁移操作步骤
- 添加 memberships/invitation_codes 建表语句
- 添加回滚方案
This commit is contained in:
2026-04-17 23:03:27 +08:00
parent b6c022d472
commit 2aeef3e9bf

View File

@@ -57,6 +57,114 @@ interface WeatherData {
--- ---
## 二、生产环境数据库迁移
### 环境信息
| 环境 | 数据库名 | 数据量 |
|------|---------|--------|
| 测试 | `milkydata_dev` | users: 1, weather_data: 4, payment_orders: 6 |
| 生产 | `milkydata` | users: 2358, weather_data: 6563, payment_orders: 0 |
### 连接方式
```bash
ssh root@1panel-server
docker exec -it 1Panel-postgresql-FtMo psql -U milky -d milkydata_dev # 测试环境
docker exec -it 1Panel-postgresql-FtMo psql -U milky -d milkydata # 生产环境
```
### 当前 schema 差异
| 表 | 测试环境 | 生产环境 | 差异 |
|---|---------|---------|------|
| users | ✅ | ✅ | 无 |
| payment_orders | ✅ | ✅ | 无 |
| weather_data | ✅ | ✅ | **生产缺少 `is_favorite` 列** |
### 迁移步骤
#### ⚠️ 重要:执行前必须备份
```bash
ssh root@1panel-server
# 备份生产数据库
docker exec 1Panel-postgresql-FtMo pg_dump -U milky milkydata > /tmp/milkydata_backup_$(date +%Y%m%d_%H%M%S).sql
# 验证备份成功
ls -la /tmp/milkydata_backup_*.sql
```
#### 步骤 1添加缺失列
生产环境执行PostgreSQL 11+ 几乎无影响):
```sql
-- 添加 is_favorite 列到 weather_data 表
ALTER TABLE weather_data ADD COLUMN is_favorite BOOLEAN NOT NULL DEFAULT false;
```
#### 步骤 2验证
```sql
-- 检查列是否添加成功
SELECT column_name, data_type, is_nullable, column_default
FROM information_schema.columns
WHERE table_name = 'weather_data' AND column_name = 'is_favorite';
```
#### 步骤 3未来新增 memberships 表
当需要会员系统时,在生产环境执行:
```sql
-- 1. 创建 memberships 表
CREATE TABLE memberships (
id SERIAL PRIMARY KEY,
user_id INTEGER UNIQUE REFERENCES users(id),
is_paid BOOLEAN DEFAULT false,
paid_expires_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_memberships_user_id ON memberships(user_id);
-- 2. 从 users 表同步现有数据
INSERT INTO memberships (user_id, is_paid, paid_expires_at)
SELECT id, is_paid, paid_expires_at FROM users
ON CONFLICT (user_id) DO NOTHING;
-- 3. 创建 invitation_codes 表
CREATE TABLE invitation_codes (
id SERIAL PRIMARY KEY,
code VARCHAR(32) UNIQUE NOT NULL,
package_type VARCHAR(20) NOT NULL,
paid_days INTEGER NOT NULL,
source VARCHAR(20) DEFAULT 'invitation',
used_by INTEGER REFERENCES users(id),
used_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
expires_at TIMESTAMPTZ,
is_used BOOLEAN DEFAULT FALSE
);
CREATE INDEX idx_invitation_codes_code ON invitation_codes(code);
```
### 回滚方案
如果需要回滚:
```sql
-- 删除新增的列/表
ALTER TABLE weather_data DROP COLUMN is_favorite;
DROP TABLE IF EXISTS memberships;
DROP TABLE IF EXISTS invitation_codes;
```
---
## 一、代码质量与架构改进 ## 一、代码质量与架构改进
### 1.1 代码组织问题 ### 1.1 代码组织问题