数据库层架构
四层架构设计
HiDNS 实现了严格的四层数据库架构:
DSM层 → 业务适配器层 → 数据库抽象层 → 驱动层 → 数据库
第一层:业务适配器层
文件位置: server/src/db/bal/business-adapter.ts
职责: 提供函数式 API,所有数据库操作必须通过此层
核心函数
// 查询多行
export async function query<T = QueryResult>(sql: string, params?: unknown[]): Promise<T[]>
// 查询单行
export async function get<T = QueryResult>(sql: string, params?: unknown[]): Promise<T | undefined>
// 执行无返回
export async function execute(sql: string, params?: unknown[]): Promise<void>
// 插入返回ID
export async function insert(sql: string, params?: unknown[]): Promise<number>
// 执行返回影响行数
export async function run(sql: string, params?: unknown[]): Promise<{ changes: number }>
// 获取当前时间函数
export function now(): string
// 获取数据库类型
export function getDbType(): DatabaseType
// 检查是否已连接
export function isDbConnected(): boolean
// 事务支持
export async function withTransaction<T>(fn: (trx: TransactionOperations) => Promise<T>): Promise<T>
业务操作模块
// 用户操作
export const UserOperations = {
async getById(id: number): Promise<User | undefined>,
async getByUsername(username: string): Promise<User | undefined>,
async getByEmail(email: string): Promise<User | undefined>,
async create(user: Omit<User, 'id' | 'createdAt'>): Promise<number>,
async update(id: number, updates: Partial<User>): Promise<void>,
async delete(id: number): Promise<void>,
async list(options?: ListOptions): Promise<PaginatedResult<User>>,
}
// DNS 账号操作
export const DnsAccountOperations = { ... }
// 域名操作
export const DomainOperations = { ... }
// 团队操作
export const TeamOperations = { ... }
// 设置操作
export const SettingsOperations = { ... }
// 审计操作
export const AuditOperations = { ... }
// Token 操作
export const TokenOperations = { ... }
// 密钥操作
export const SecretOperations = { ... }
// 安全策略操作
export const SecurityPolicyOperations = { ... }
// 设备信任操作
export const TrustedDeviceOperations = { ... }
// 用户偏好操作
export const UserPreferencesOperations = { ... }
// 会话操作
export const SessionOperations = { ... }
// 登录限制操作
export const LoginLimitOperations = { ... }
// 故障转移操作
export const FailoverOperations = { ... }
// 审计导出操作
export const AuditExportOperations = { ... }
// TOTP 操作
export const TOTPOperations = { ... }
// WebAuthn 操作
export const WebAuthnOperations = { ... }
// SMTP 操作
export const SmtpOperations = { ... }
// WHOIS 操作
export const WhoisOperations = { ... }
// 审计规则操作
export const AuditRulesOperations = { ... }
// 审计日志操作
export const AuditLogOperations = { ... }
// OAuth 操作
export const OAuthOperations = { ... }
// 双因素认证操作
export const TwoFAOperations = { ... }
// 事务操作
export class TransactionOperations { ... }
使用示例
import { query, get, execute, insert, run, now, UserOperations } from '../db';
// 查询单行
const user = await get<User>('SELECT * FROM users WHERE id = ?', [userId]);
// 查询多行
const users = await query<User>('SELECT * FROM users WHERE status = ?', ['active']);
// 插入数据
const id = await insert('INSERT INTO users (name, email) VALUES (?, ?)', [name, email]);
// 执行更新
await execute('UPDATE users SET last_login = ? WHERE id = ?', [now(), userId]);
// 使用业务操作模块
const user = await UserOperations.getById(1);
第二层:数据库抽象层
文件位置: server/src/db/core/
职责: 提供统一的数据库连接和类型系统
文件结构
db/core/
├── types.ts # 统一类型定义
├── connection.ts # 连接管理器(单例模式)
└── config.ts # 配置管理
核心类型
// 数据库类型
type DatabaseType = 'sqlite' | 'mysql' | 'postgresql'
// 数据库连接接口
interface DatabaseConnection {
readonly type: DatabaseType
readonly isConnected: boolean
query<T>(sql: string, params?: unknown[]): Promise<T[]>
get<T>(sql: string, params?: unknown[]): Promise<T | undefined>
execute(sql: string, params?: unknown[]): Promise<void>
insert(sql: string, params?: unknown[]): Promise<number>
run(sql: string, params?: unknown[]): Promise<{ changes: number }>
beginTransaction(): Promise<Transaction>
close(): Promise<void>
}
第三层:驱动层
文件位置: server/src/db/dl/
职责: 实现具体数据库的操作逻辑
文件结构
db/dl/
├── base.ts # 基础驱动类(模板方法模式)
├── mysql.ts # MySQL 驱动(连接池)
├── postgresql.ts # PostgreSQL 驱动(连接池)
└── sqlite.ts # SQLite 驱动(better-sqlite3)
驱动特性
- MySQL: 连接池管理、慢查询日志、连接池事件监控
- PostgreSQL: 连接池管理、SSL 支持
- SQLite: WAL 模式、外键约束、同步执行包装
第四层:声明式模式管理层 (DSM)
文件位置: server/src/db/dsm/
职责: 管理数据库表结构的声明式定义、自动调谐(reconciliation)、数据迁移及版本管理
文件结构
db/dsm/
├── index.ts # 统一入口
├── init-dsm.ts # DSM 初始化
├── schema-reconciler.ts # Schema 调谐器(自动同步表结构)
├── migration-manager.ts # 迁移管理器
├── data-migration-runner.ts # 数据迁移运行器
├── backup-manager.ts # 备份管理器
├── sql-compat.ts # SQL 兼容性层
├── column-validator.ts # 列验证器
├── schema/
│ ├── registry.ts # Schema 注册表
│ └── migration.ts # 迁移定义
└── schemas/
├── index.ts # Schema 入口
├── complete-schema.ts # 完整 Schema 定义
├── types/
│ └── schema.ts # Schema 类型定义
└── dialects/
├── sqlite.ts # SQLite 方言
├── mysql.ts # MySQL 方言
└── postgresql.ts # PostgreSQL 方言
核心能力
- 声明式 Schema 定义: 用 TypeScript 定义表结构,自动生成对应数据库的 DDL
- 自动调谐: 启动时自动比对声明式 Schema 与实际数据库结构,自动增补缺失的表和字段
- 版本管理: 支持增量迁移和回滚操作
- 多数据库方言: 根据数据库类型自动适配 SQLite/MySQL/PostgreSQL 语法
- 幂等性保证: 重复执行不会产生副作用
数据库主入口
文件位置: server/src/db/index.ts
职责: 统一导出业务适配器函数和类型
// ==================== 业务适配器层(推荐)====================
export {
// 核心函数
query, get, execute, insert, run, now,
getDbType, isDbConnected, withTransaction,
// 业务操作模块
UserOperations, DnsAccountOperations, DomainOperations,
TeamOperations, SettingsOperations, AuditOperations,
TokenOperations, SecretOperations,
SecurityPolicyOperations, TrustedDeviceOperations,
UserPreferencesOperations, SessionOperations,
LoginLimitOperations, FailoverOperations,
AuditExportOperations, TOTPOperations,
WebAuthnOperations, SmtpOperations, WhoisOperations,
AuditRulesOperations, AuditLogOperations,
OAuthOperations, TwoFAOperations,
// 类型
type QueryResult, TransactionOperations,
} from './bal/business-adapter';
// ==================== 初始化函数 ====================
export { initSchema, initSchemaAsync } from './schema';
Schema 管理
职责: 定义和管理数据库表结构
多数据库 Schema
- SQLite Schema:
schemas/sqlite.ts - MySQL Schema:
schemas/mysql.ts - PostgreSQL Schema:
schemas/postgresql.ts
核心表
users: 用户表teams: 团队表team_members: 团队成员表dns_accounts: DNS 账号表domains: 域名表domain_records: 解析记录表audit_logs: 审计日志表runtime_secrets: 运行时密钥表api_tokens: API Token 表notification_channels: 通知渠道表failover_configs: 故障转移配置表oauth_user_links: OAuth 用户绑定表user_2fa: 双因素认证表login_attempts: 登录尝试表system_settings: 系统设置表whois_cache: WHOIS 缓存表renewable_domains: 可续期域名表user_preferences: 用户偏好设置(置顶域名)email_templates: 邮件模板表security_policies: 安全策略表device_trust: 设备信任表ns_monitor_configs: NS 监测配置表tunnels: Cloudflare Tunnel 表
数据库初始化流程
app.ts:252 → createConnection() → 创建数据库连接(传统层)
app.ts:255 → connect() → 初始化业务适配器
app.ts:258 → initSchemaAsync(conn) → 初始化数据库表结构
initSchemaAsync 函数
export async function initSchemaAsync(conn, reset = false): Promise<void> {
if (conn.type === 'sqlite') {
initSQLiteSchema(conn, reset);
} else if (conn.type === 'mysql') {
await initMySQLSchema(conn, reset);
} else if (conn.type === 'postgresql') {
await initPostgreSQLSchema(conn, reset);
}
}
数据库调用规范
✅ 正确用法
// 使用业务适配器函数
import { query, get, execute, insert, UserOperations } from '../db';
const user = await get<User>('SELECT * FROM users WHERE id = ?', [userId]);
const users = await query<User>('SELECT * FROM users WHERE status = ?', ['active']);
const id = await insert('INSERT INTO users (name, email) VALUES (?, ?)', [name, email]);
❌ 错误用法
// 禁止直接使用兼容层
import { getAdapter } from '../db/adapter'; // 已废除
const db = getAdapter();
日志记录
业务适配器层自动记录所有数据库操作:
[BusinessAdapter] [DEBUG] Executing get {"sql":"SELECT * FROM users WHERE id = ?","params":[1]}
[BusinessAdapter] [ERROR] Get failed {"sql":"...","error":"...","duration":"44ms"}
数据库迁移
迁移脚本位置
server/scripts/
├── db-migrate.ts # 数据库迁移主脚本
├── db-rollback.ts # 回滚脚本
└── migrate-*.js # 特定迁移脚本
迁移流程
- 检测数据库类型(SQLite/MySQL/PostgreSQL)
- 根据类型选择对应的 SQL 语法
- 执行迁移并记录版本
- 支持回滚操作
自动迁移
initSchemaAsync(): 应用启动时自动检测并迁移- 幂等性保证:重复执行不会产生副作用
- 增量迁移:只添加缺失的表和字段