# 数据库

FluxiQ PIX 的 PostgreSQL 配置、模式管理、迁移和性能调优。

## 前提条件

- PostgreSQL 16 已安装并可访问
- 扩展 `uuid-ossp` 和 `pg_trgm` 可用
- 具有 CREATE/ALTER/DROP 权限的数据库用户

## 模式概览

FluxiQ PIX 使用 8 个 PostgreSQL 模式来分离关注点：

| 模式 | 表数量 | 用途 |
|------|--------|------|
| `monetarie_auth` | ~10 | 用户、会话、MFA、机构、群组、权限 |
| `monetarie_dict` | ~8 | PIX 密钥、认领、违规报告、CID 同步 |
| `monetarie_spi` | ~12 | 消息（交易）、支付、账户、余额 |
| `monetarie_spi_ref` | ~6 | 参考数据：银行、状态码、消息类型 |
| `monetarie_spi_msg` | ~4 | 加密密钥、XML 消息 |
| `monetarie_audit` | ~4 | XML 归档、BACEN API 验证 |
| `monetarie_settlement` | ~10 | 净额计算、对账、QR 码、总账会计 |
| `bacen_simulator` | ~24 | 模拟器配置、场景、测试运行 |

## 连接配置

```elixir
# config/runtime.exs
config :shared, Shared.Repo,
  hostname: System.get_env("DB_HOST", "localhost"),
  port: String.to_integer(System.get_env("DB_PORT", "5432")),
  username: System.get_env("DB_USER", "postgres"),
  password: System.get_env("DB_PASS", "postgres"),
  database: System.get_env("DB_NAME", "monetarie"),
  pool_size: String.to_integer(System.get_env("POOL_SIZE", "250"))
```

### 连接池大小

| 环境 | POOL_SIZE | Repos | Pods | 总连接数 |
|------|-----------|-------|------|----------|
| 开发 | 10 | 4 | 1 | 40 |
| 预发布 | 50 | 4 | 2 | 400 |
| 生产 | 200 | 4 | 2 | 1,600 |
| 高 TPS | 250 | 4 | 4 | 4,000 |

确保 PostgreSQL 的 `max_connections` 至少超过总连接数 10%。

## 迁移

FluxiQ PIX 共有 25 个迁移。运行方式：

```bash
# 开发环境
cd backend && mix ecto.migrate

# 生产环境 (Kubernetes)
kubectl exec -n pix deployment/pix-backend -- bin/monetarie_pix eval "Shared.Release.migrate()"
```

### 迁移摘要

| # | 时间戳 | 用途 |
|---|--------|------|
| 1 | 20260201000001 | 初始模式和表 |
| 2 | 20260203000001 | 13 个差距解决表 |
| 3 | 20260203000002 | 参考数据种子 |
| 4 | 20260203100001 | PostgreSQL 扩展和 ENUM |
| 5-9 | 20260203100002-06 | 各模式中缺失的表 |
| 10 | 20260203100007 | 数据库函数、触发器、视图 |
| 11 | 20260203100008 | BACEN 模拟器表 |
| 12 | 20260203100009 | 种子 SQL 加载 |
| 13 | 20260206000001 | 认证机构和群组 |
| 14-16 | 20260206200001-03 | BACEN 合规、域值、审批层 |
| 17 | 20260207300001 | MFA 字段 |
| 18 | 20260207400001 | 总账会计 (44 COSIF + 6 成本中心) |
| 19 | 20260207500001 | 系统配置 (13 个参数) |
| 20 | 20260208000001 | 性能索引 (E2E ID、状态、日期) |
| 21 | 20260208100001 | 账户 ISPB、user_groups 关联表 |
| 22 | 20260209000001 | 重建 infraction_reports (UUID PK, MED 2.0) |
| 23 | 20260209100001 | TPS 索引 (8 个：分支、CPF、GIN 三元组) |
| 24 | 20260209200001 | 审计修复 (reported_cpf_cnpj, user_groups 字段) |
| 25 | 20260210000001 | 分区表 (activity_log, login_history) |

## ENUM 类型

| 模式 | Enum | 值 |
|------|------|----|
| `monetarie_dict` | `key_type` | CPF, CNPJ, PHONE, EMAIL, EVP |
| `monetarie_spi` | `debit_credit` | DEBIT, CREDIT |
| `monetarie_spi` | `message_direction` | OUTBOUND, INBOUND |

## 性能调优

### 关键索引（迁移 20、23）

| 表 | 索引 | 类型 | 用途 |
|----|------|------|------|
| `monetarie_spi.messages` | `end_to_end_id::text` | GIN 三元组 | E2E ID 模糊搜索 |
| `monetarie_spi.messages` | `status_id` | B-tree | 状态过滤 |
| `monetarie_spi.messages` | `branch_id, status_id` | 复合 | 分支仪表板 |
| `monetarie_spi.messages` | `inserted_at` | B-tree | 日期范围查询 |
| `monetarie_spi.payments` | `debtor_cpf_cnpj` | B-tree | CPF/CNPJ 查询 |
| `monetarie_dict.dict_keys` | `key_type, key_value` | 复合 | 密钥查询 |

::: warning GIN 三元组与 CHAR 列
`gin_trgm_ops` 不接受 CHAR 类型列。必须转换为 text：`(end_to_end_id::text) gin_trgm_ops`。
:::

### PostgreSQL 配置（生产环境）

```sql
ALTER SYSTEM SET max_connections = 6000;
ALTER SYSTEM SET shared_buffers = '8GB';
ALTER SYSTEM SET effective_cache_size = '24GB';
ALTER SYSTEM SET work_mem = '64MB';
ALTER SYSTEM SET maintenance_work_mem = '2GB';
ALTER SYSTEM SET random_page_cost = 1.1;  -- SSD 存储
ALTER SYSTEM SET checkpoint_completion_target = 0.9;
ALTER SYSTEM SET wal_buffers = '64MB';
ALTER SYSTEM SET max_wal_size = '4GB';
```

## 表分区

迁移 25 为高容量审计表创建月度分区：

| 表 | 分区键 | 策略 |
|----|--------|------|
| `monetarie_audit.activity_log` | `created_at` | 月度 RANGE |
| `monetarie_auth.login_history` | `login_at` | 月度 RANGE |

`PartitionManager` GenServer 自动提前 60 天创建分区并清除过期记录。

## 种子数据

```bash
mix run apps/shared/priv/repo/seeds.exs
```

| 数据 | 数量 |
|------|------|
| 参与者 | 10 |
| 用户 | 7 |
| 参考银行 | 369 (+98 额外) |
| PIX 密钥 | 277 |
| DICT 操作 | 15,442 |
| 交易 (30天) | 1,000+ |
| COSIF 账户 | 44 |
| XSD 模式 | 27 |
| 错误代码 | 161 |

## 预期结果

配置数据库后：

- 所有 25 个迁移无错误完成
- 8 个模式已创建，包含所有表和索引
- 种子数据已加载（如需要）
- 连接池大小适合您的部署模式
- 审计表的分区已激活
