# Trustlog 数据库建表脚本 本目录包含 go-trustlog 数据库持久化模块的建表 SQL 脚本。 --- ## 📁 文件列表 | 文件 | 数据库 | 说明 | |------|--------|------| | `postgresql.sql` | PostgreSQL 12+ | PostgreSQL 数据库建表脚本 | | `mysql.sql` | MySQL 8.0+ / MariaDB 10+ | MySQL 数据库建表脚本 | | `sqlite.sql` | SQLite 3+ | SQLite 数据库建表脚本 | | `test_data.sql` | 通用 | 测试数据插入脚本 | --- ## 📊 表结构说明 ### 1. operation 表 操作记录表,用于存储所有的操作记录。 **关键字段**: - `op_id` - 操作ID(主键) - `client_ip` - **客户端IP(可空,仅落库,不存证)** - `server_ip` - **服务端IP(可空,仅落库,不存证)** - `trustlog_status` - **存证状态(NOT_TRUSTLOGGED / TRUSTLOGGED)** - `timestamp` - 操作时间戳 **索引**: - `idx_operation_timestamp` - 时间戳索引 - `idx_operation_status` - 存证状态索引 - `idx_operation_doid` - DOID 索引 ### 2. trustlog_cursor 表 游标表,用于跟踪处理进度,支持断点续传。 **关键字段**: - `id` - 游标ID(固定为1) - `last_processed_id` - 最后处理的操作ID - `last_processed_at` - 最后处理时间 **特性**: - 自动初始化一条记录(id=1) - 用于实现最终一致性 ### 3. trustlog_retry 表 重试表,用于管理失败的存证操作。 **关键字段**: - `op_id` - 操作ID(主键) - `retry_count` - 重试次数 - `retry_status` - 重试状态(PENDING / RETRYING / DEAD_LETTER) - `next_retry_at` - 下次重试时间(指数退避) - `error_message` - 错误信息 **索引**: - `idx_retry_status` - 重试状态索引 - `idx_retry_next_retry_at` - 下次重试时间索引 --- ## 🚀 使用方法 ### PostgreSQL ```bash # 方式1: 使用 psql 命令 psql -U username -d database_name -f postgresql.sql # 方式2: 使用管道 psql -U username -d database_name < postgresql.sql # 方式3: 在 psql 中执行 psql -U username -d database_name \i postgresql.sql ``` ### MySQL ```bash # 方式1: 使用 mysql 命令 mysql -u username -p database_name < mysql.sql # 方式2: 在 mysql 中执行 mysql -u username -p USE database_name; SOURCE mysql.sql; ``` ### SQLite ```bash # 方式1: 使用 sqlite3 命令 sqlite3 trustlog.db < sqlite.sql # 方式2: 在 sqlite3 中执行 sqlite3 trustlog.db .read sqlite.sql ``` --- ## 🔍 验证安装 每个 SQL 脚本末尾都包含验证查询,执行后可以检查: ### PostgreSQL ```sql -- 查询所有表 SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND tablename IN ('operation', 'trustlog_cursor', 'trustlog_retry'); ``` ### MySQL ```sql -- 查询所有表 SHOW TABLES LIKE 'operation%'; SHOW TABLES LIKE 'trustlog_%'; ``` ### SQLite ```sql -- 查询所有表 SELECT name FROM sqlite_master WHERE type='table' AND name IN ('operation', 'trustlog_cursor', 'trustlog_retry'); ``` --- ## 📝 字段说明 ### operation 表新增字段 #### client_ip 和 server_ip **特性**: - 类型: VARCHAR(32) / TEXT (根据数据库而定) - 可空: YES - 默认值: NULL **用途**: - 记录客户端和服务端的 IP 地址 - **仅用于数据库持久化** - **不参与存证哈希计算** - **不会被序列化到 CBOR 格式** **示例**: ```sql -- 插入 NULL 值(默认) INSERT INTO operation (..., client_ip, server_ip, ...) VALUES (..., NULL, NULL, ...); -- 插入 IP 值 INSERT INTO operation (..., client_ip, server_ip, ...) VALUES (..., '192.168.1.100', '10.0.0.50', ...); ``` #### trustlog_status **特性**: - 类型: VARCHAR(32) / TEXT - 可空: YES - 可选值: - `NOT_TRUSTLOGGED` - 未存证 - `TRUSTLOGGED` - 已存证 **用途**: - 标记操作记录的存证状态 - 用于查询未存证的记录 - 支持最终一致性机制 --- ## 🔄 常用查询 ### 1. 查询未存证的操作 ```sql SELECT * FROM operation WHERE trustlog_status = 'NOT_TRUSTLOGGED' ORDER BY timestamp ASC LIMIT 100; ``` ### 2. 查询待重试的操作 ```sql SELECT * FROM trustlog_retry WHERE retry_status IN ('PENDING', 'RETRYING') AND next_retry_at <= NOW() ORDER BY next_retry_at ASC LIMIT 100; ``` ### 3. 查询死信记录 ```sql SELECT o.op_id, o.doid, r.retry_count, r.error_message, r.created_at FROM operation o JOIN trustlog_retry r ON o.op_id = r.op_id WHERE r.retry_status = 'DEAD_LETTER' ORDER BY r.created_at DESC; ``` ### 4. 按 IP 查询操作 ```sql -- 查询特定客户端IP的操作 SELECT * FROM operation WHERE client_ip = '192.168.1.100' ORDER BY timestamp DESC; -- 查询未设置IP的操作 SELECT * FROM operation WHERE client_ip IS NULL ORDER BY timestamp DESC; ``` ### 5. 统计存证状态 ```sql SELECT trustlog_status, COUNT(*) as count FROM operation GROUP BY trustlog_status; ``` --- ## 🗑️ 清理脚本 ### 删除所有表 ```sql -- PostgreSQL / MySQL DROP TABLE IF EXISTS trustlog_retry; DROP TABLE IF EXISTS trustlog_cursor; DROP TABLE IF EXISTS operation; -- SQLite DROP TABLE IF EXISTS trustlog_retry; DROP TABLE IF EXISTS trustlog_cursor; DROP TABLE IF EXISTS operation; ``` ### 清空数据(保留结构) ```sql -- 清空重试表 DELETE FROM trustlog_retry; -- 清空操作表 DELETE FROM operation; -- 重置游标表 UPDATE trustlog_cursor SET last_processed_id = NULL, last_processed_at = NULL, updated_at = CURRENT_TIMESTAMP WHERE id = 1; ``` --- ## ⚠️ 注意事项 ### 1. 字符集和排序规则(MySQL) - 使用 `utf8mb4` 字符集 - 使用 `utf8mb4_unicode_ci` 排序规则 - 支持完整的 Unicode 字符 ### 2. 索引长度(MySQL) - `doid` 字段使用前缀索引 `doid(255)` - 避免索引长度超过限制 ### 3. 自增主键 - PostgreSQL: `SERIAL` - MySQL: `AUTO_INCREMENT` - SQLite: `AUTOINCREMENT` ### 4. 时间类型 - PostgreSQL: `TIMESTAMP` - MySQL: `DATETIME` - SQLite: `DATETIME` (存储为文本) ### 5. IP 字段长度 - 当前长度: 32 字符 - IPv4: 最长 15 字符 (`255.255.255.255`) - IPv4 with port: 最长 21 字符 (`255.255.255.255:65535`) - **IPv6: 最长 39 字符** - 如需支持完整 IPv6,建议扩展到 64 字符 --- ## 🔧 扩展建议 ### 1. 如果需要支持完整 IPv6 ```sql -- 修改 client_ip 和 server_ip 字段长度 ALTER TABLE operation MODIFY COLUMN client_ip VARCHAR(64); ALTER TABLE operation MODIFY COLUMN server_ip VARCHAR(64); ``` ### 2. 如果需要分区表(PostgreSQL) ```sql -- 按时间分区 CREATE TABLE operation_partitioned ( -- ... 字段定义 ... ) PARTITION BY RANGE (timestamp); CREATE TABLE operation_2024_01 PARTITION OF operation_partitioned FOR VALUES FROM ('2024-01-01') TO ('2024-02-01'); ``` ### 3. 如果需要添加审计字段 ```sql -- 添加创建人和更新人 ALTER TABLE operation ADD COLUMN created_by VARCHAR(64); ALTER TABLE operation ADD COLUMN updated_by VARCHAR(64); ALTER TABLE operation ADD COLUMN updated_at TIMESTAMP; ``` --- ## 📚 相关文档 - [PERSISTENCE_QUICKSTART.md](../../PERSISTENCE_QUICKSTART.md) - 快速入门 - [README.md](../README.md) - 详细技术文档 - [IP_FIELDS_USAGE.md](../IP_FIELDS_USAGE.md) - IP 字段使用说明 --- ## ✅ 检查清单 安装完成后,请检查: - [ ] 所有3个表都已创建 - [ ] 所有索引都已创建 - [ ] trustlog_cursor 表有初始记录(id=1) - [ ] operation 表可以插入 NULL 的 IP 值 - [ ] operation 表可以插入非 NULL 的 IP 值 - [ ] 查询验证脚本能正常执行 --- **最后更新**: 2025-12-23 **版本**: v1.0.0