从 OLAP 引擎到搜索引擎,再到建模工具与日常运维动作。

一、引擎

ClickHouse

ClickHouse 是面向 OLAP 的列式数据库,擅长在海量事件上做过滤、分组和聚合。数据按列存储,同一列类型相近,压缩比高,扫描时只读用到的列。MergeTree 系家是主干:写入先落部分,后台合并去重。分区键常选日期,排序键选高频筛选字段,这两个决定了查询能否跳过大块无用数据。

它不适合高频单行更新和事务。更新实质是写新部分再合并,点查主键不如 MySQL。建表时要把高基数字段控制住,避免把 URL 或用户 ID 当成低基数字符串导致索引膪肿。业务上更常用它做埋点、行为漏斗和运营报表。查询要写成能利用预聚合或折叠的形式,而不是把多表大 Join 搬进来当成通用数仓。

Elasticsearch

Elasticsearch 是分布式搜索引擎,文档进倒排索引后按 term 查。Index 分 shard,副本保证可读。Kibana 做可视化,IK 等分词器处理中文。mapping 一旦定动态字段要谨慎改。

查询有 match、filter、聚合。写入走 refresh 才可搜,近实时不是事务库。堆内存与 disk circuit breaker 是运维重点。版本冲突用乐观并发。

不要当主数据库。 nested/join 成本高。中文检索要选分词并测召回。索引生命周期把热温冷数据分层。安全开 xpack 认证,公网千万别裸奔。

OpenSearch 搜索引擎

OpenSearch 是从 Elasticsearch 7.x 演进的开源搜索与分析引擎,提供倒排索引、聚合和仪表盘。适合日志检索、站内搜索和可观察性,集群由节点角色、分片和副本构成。

映射一旦写入就难大改,字段类型、分词器和动态模板要提前定。写入走 bulk,查询走过滤上下文能走缓存。版本冲突用外部版本或乐观并发控制,避免覆盖更新互相踩。

运维盯堆内存、段合并和磁盘水位。安全插件、快照到对象存储和索引生命周期策略应作为默认项,而不是集群变慢后再补。

supabase

Supabase 把 Postgres、认证、存储和实时订阅打包成后端即服务,API 由数据库表直接生成。适合中小产品快速起步,行级安全策略把权限下沉到 SQL,而不是只写一层应用网关。

实时功能依赖复制槽和订阅,表设计要避免过大行和频繁全表更新。密钥分 anon 与 service role,后者绝不能进前端。迁移用版本化 SQL,生产变更走审核。

当业务出现复杂工作流和多租户计费时,再把部分逻辑抽到边缘函数或独立服务。Postgres 能力用好了,能少引入很多专用组件。

二、建模与设计

数据库设计

数据库设计先从业务实体和关系出发,再谈范式与索引。主键稳定、外键或应用层约束保证引用,枚举用字典表或检查约束。第三范式减少更新异常,报表再靠宽表或视图。命名、时区和软删除策略要在项目开始就定。字段含义写进数据字典,比只靠口头传。

索引服务查询,不是越多越好。高并发写入要避免热点自增和大事务。预估数据量决定要不要分区。变更走迁移脚本,禁止生产手工改表还不记录。评审 ER 图比评审 DAO 代码更能拦住结构性错误。设计的目标是让常见查询简单、异常更新少,而不是一次性画完美模型。业务变了,表结构也要有演进路径。

数据库表设计

数据库表设计流程

表设计注意事项

    1. 逻辑删除
    1. 通用字段
    1. 一张表的字段不宜过多
    1. 定义字段尽量not null
    1. 合理添加索引-联合索引
    1. 不需要严格遵循3NF,可以使用反范式
    1. 避免使用MYSQL保留字
    1. 不搞外键关联,只使用代码维护表关系
    1. 字段需要做注释
    1. 时间类型的选择:date、datetime、time、timestamp、year
    1. SQL优化

表设计工具

DrawIO

PDman

PDman(及后继 PDManer)是国产数据库建模工具,用 JSON 工程描述表、字段、索引与关系,可导出 DDL 到 MySQL/PostgreSQL 等。适合中小团队替代部分 PowerDesigner 场景,版本可进 Git。

建模时先定命名规范与类型映射,再生成 SQL。变更用增量脚本而不是每次全量 drop。字段备注要写业务含义,方便代码生成。

和 MyBatis Generator、JOOQ 衔接时注意类型精度。多人协作避免直接改生成 SQL。导出前检查外键循环。桌面版与 Web 版能力略有差异,团队锁定一个版本。

PowerDesigner

PowerDesigner 是传统企业级数据建模工具,支持概念/逻辑/物理模型,能正向工程出 DDL,反向从库反推模型。CDM 与 PDM 分离,方便同一逻辑模型对多数据库。

团队常用仓库做模型版本。生成脚本要 review 默认约束与命名。和需求变更流程绑定,避免库已改模型未改。许可证与 Windows 环境是推广阻力。

中小项目可用 PDman 或 dbdiagram 替代。迁移时把域、引用完整性规则导出文档。注意字符集与大小写折叠在不同 DBMS 上的差异。不要把生产口令写进模型文件。

ACID原则

ACID 描述事务的四条承诺:原子性要么全成要么全撤,一致性让约束在提交后仍成立,隔离性控制并发可见性,持久性保证提交后掉电不丢。关系数据库用日志、锁和多版本来逼近这些目标。

隔离级别从读未提交到可串行化,越严吞吐越低。幻读、不可重复读要靠间隙锁或快照解决。分布式场景下完整 ACID 成本高,所以会出现最终一致和补偿事务。

业务上先标出必须同生共死的写集合,再决定本地事务还是分布式方案。把无关更新塞进一个大事务,只会拉长锁时间。

三、运维

数据库集成

数据库集成把多个存储与服务组合成可查询的整体。应用不要在业务代码里直接拼接 MySQL、Redis 和 Elasticsearch,而应把写入路径、读取路径和一致性约定明确写出来。常见模式有双写、出站消息驱动同步、CDC 入仓。双写实现快但容易不一致;消息驱动能解耦,但要处理乱序和重复消费。

集成的难点在于事务边界。一笔订单要写库、写缓存、写搜索引擎时,任何一步失败都要有补偿。可以用本地消息表做事务性出站,或者接受最终一致并做对账任务。查询侧要避免跨库 Join,把聚合视图放到专门的读模型。监控要覆盖延迟与滞后里程,否则集成只在流量小的时候看起来正常。

数据库迁移

数据库迁移把表结构、数据和权限从一个环境搬到另一个环境。常见场景包括版本升级、云上云下移交、分库拆分和容灾演练。迁移不是只 dump 再 restore:要对齐字符集、时区、自增列与触发器,还要决定是停机窗口还是在线双写。停机迁移简单但有业务中断;在线迁移要做增量同步和回切开关。

步骤上建议先锁结表结构变更,再跑全量,接着用 binlog 或逻辑复制追平,最后做行数与校验和抽样对比。回切前把读请求切到新库观察一阵,出现差异再切回。迁移脚本要版本化,和应用发布一起走。失败时能清楚说明停在哪张表、已写入多少行,才能收缩回滚范围。

数据库备份

数据库备份要解决两个问题:能不能恢复、能不能在可接受的 RPO 内恢复。物理备份把数据文件拷走,逻辑备份把 SQL 或行记录导出。MySQL 常用 xtrabackup 做热备份,再配 binlog 做点后追增量。备份不要和业务盘放同一个机架,远端要有独立副本和保留策略。

有备份不等于能恢复。要定期做恢复演练:拉到指定时间点、校验表结构和抽样数据。加密库还要备份密钥。分库分表时要记录路由规则,否则恢复后应用连不上。云上快照能改善 RPO,但删库误操作仍要有逻辑备份做点再往前滚。把最近一次成功演练的时间写进运维仪表盘,备份策略才算落地。