前言
💡 痛点: OLTP 和 OLAP 怎么选数据库?TiDB 和 ClickHouse 各有什么优势?什么时候用哪个?能不能用一个数据库同时搞定 TP + AP?
🎯 解决方案: 本文系统对比 TiDB 和 ClickHouse:架构差异、性能基准、适用场景、实战部署、SQL 优化、HTAP 架构设计、选型决策树。
#mermaid-svg-zMvCTe6rSVIyCcZS{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-zMvCTe6rSVIyCcZS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-zMvCTe6rSVIyCcZS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-zMvCTe6rSVIyCcZS .error-icon{fill:#552222;}#mermaid-svg-zMvCTe6rSVIyCcZS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zMvCTe6rSVIyCcZS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-zMvCTe6rSVIyCcZS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zMvCTe6rSVIyCcZS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zMvCTe6rSVIyCcZS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-zMvCTe6rSVIyCcZS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zMvCTe6rSVIyCcZS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zMvCTe6rSVIyCcZS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zMvCTe6rSVIyCcZS .marker.cross{stroke:#333333;}#mermaid-svg-zMvCTe6rSVIyCcZS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zMvCTe6rSVIyCcZS p{margin:0;}#mermaid-svg-zMvCTe6rSVIyCcZS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-zMvCTe6rSVIyCcZS .cluster-label text{fill:#333;}#mermaid-svg-zMvCTe6rSVIyCcZS .cluster-label span{color:#333;}#mermaid-svg-zMvCTe6rSVIyCcZS .cluster-label span p{background-color:transparent;}#mermaid-svg-zMvCTe6rSVIyCcZS .label text,#mermaid-svg-zMvCTe6rSVIyCcZS span{fill:#333;color:#333;}#mermaid-svg-zMvCTe6rSVIyCcZS .node rect,#mermaid-svg-zMvCTe6rSVIyCcZS .node circle,#mermaid-svg-zMvCTe6rSVIyCcZS .node ellipse,#mermaid-svg-zMvCTe6rSVIyCcZS .node polygon,#mermaid-svg-zMvCTe6rSVIyCcZS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zMvCTe6rSVIyCcZS .rough-node .label text,#mermaid-svg-zMvCTe6rSVIyCcZS .node .label text,#mermaid-svg-zMvCTe6rSVIyCcZS .image-shape .label,#mermaid-svg-zMvCTe6rSVIyCcZS .icon-shape .label{text-anchor:middle;}#mermaid-svg-zMvCTe6rSVIyCcZS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-zMvCTe6rSVIyCcZS .rough-node .label,#mermaid-svg-zMvCTe6rSVIyCcZS .node .label,#mermaid-svg-zMvCTe6rSVIyCcZS .image-shape .label,#mermaid-svg-zMvCTe6rSVIyCcZS .icon-shape .label{text-align:center;}#mermaid-svg-zMvCTe6rSVIyCcZS .node.clickable{cursor:pointer;}#mermaid-svg-zMvCTe6rSVIyCcZS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-zMvCTe6rSVIyCcZS .arrowheadPath{fill:#333333;}#mermaid-svg-zMvCTe6rSVIyCcZS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-zMvCTe6rSVIyCcZS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-zMvCTe6rSVIyCcZS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zMvCTe6rSVIyCcZS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-zMvCTe6rSVIyCcZS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zMvCTe6rSVIyCcZS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-zMvCTe6rSVIyCcZS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-zMvCTe6rSVIyCcZS .cluster text{fill:#333;}#mermaid-svg-zMvCTe6rSVIyCcZS .cluster span{color:#333;}#mermaid-svg-zMvCTe6rSVIyCcZS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-zMvCTe6rSVIyCcZS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-zMvCTe6rSVIyCcZS rect.text{fill:none;stroke-width:0;}#mermaid-svg-zMvCTe6rSVIyCcZS .icon-shape,#mermaid-svg-zMvCTe6rSVIyCcZS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zMvCTe6rSVIyCcZS .icon-shape p,#mermaid-svg-zMvCTe6rSVIyCcZS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-zMvCTe6rSVIyCcZS .icon-shape .label rect,#mermaid-svg-zMvCTe6rSVIyCcZS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zMvCTe6rSVIyCcZS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-zMvCTe6rSVIyCcZS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-zMvCTe6rSVIyCcZS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 场景
ClickHouse_架构
ClickHouse Server
ZooKeeper/ZK
元数据存储
Replica
副本复制
TiDB_架构
PD
元数据 + 调度
TiKV
行存 + 事务
TiFlash
列存 + 副本
TiDB Server
无状态 SQL 层
OLTP
高并发写入/事务
OLAP
海量数据聚合分析
HTAP
TP + AP 混合
TiDB
ClickHouse
一、架构对比
1.1 核心架构差异
# ======== TiDB 架构(HTAP 分布式数据库)========
#
# 组件:
# - TiDB Server:无状态 SQL 层(兼容 MySQL 协议)
# - PD (Placement Driver):元数据 + 调度中心(ETCD 实现)
# - TiKV:行存存储引擎(LSM-Tree,支持事务)
# - TiFlash:列存引擎(TiKV 的 Raft 副本,强一致性)
#
# 关键特性:
# ✅ 100% MySQL 兼容(迁移零成本)
# ✅ 分布式事务(Percolator 模型,2PC + Percolator)
# ✅ HTAP(TiKV 行存 + TiFlash 列存,自动选择)
# ✅ 弹性伸缩(在线扩缩容,自动 Rebalance)
# ✅ 金融级高可用(Raft 三副本,自动故障转移)
#
# 写入模型:
# Client → TiDB Server → PD(获取 TSO)→ TiKV(Raft 写入)
# ↓
# TiFlash(异步 Raft 副本同步)
#
# ======== ClickHouse 架构(OLAP 列式数据库)========
#
# 组件:
# - ClickHouse Server:独立进程(每个节点对等,无主从)
# - ZooKeeper/ZK:元数据存储(副本 DDL 同步)
# - Storage Engines:MergeTree 系列(核心)
#
# 关键特性:
# ✅ 极致列式存储性能(百亿级数据秒级响应)
# ✅ 向量化执行引擎(SIMD 加速)
# ✅ 多种表引擎(MergeTree / ReplacingMergeTree / Distributed)
# ❌ 不支持完整事务(只支持批量写入,无行级更新/删除)
# ❌ 不兼容 MySQL 协议(自有协议)
#
# 写入模型:
# Client → ClickHouse Server → MergeTree(写入内存 → 定期 Merge 到磁盘)
# ⚠️ 注意:高频小批量写入性能差!必须攒批写入
1.2 功能对比表
| 维度 | TiDB | ClickHouse |
|---|---|---|
| 定位 | HTAP(TP + AP 混合) | OLAP(分析型) |
| MySQL 兼容 | ✅ 100% 兼容 | ❌ 不兼容 |
| 事务支持 | ✅ ACID(分布式事务) | ⚠️ 有限(仅批量写入) |
| 写入性能 | 中(~20K TPS/节点) | 极高(批量写入 ~500K rows/s) |
| 查询性能(AP) | 中(TiFlash 列存加速) | 极快(列式 + 向量化) |
| **查询性能(TP) | 快(TiKV 行存索引) | 慢(不适合点查) |
| 存储引擎 | TiKV(行存)+ TiFlash(列存) | MergeTree(列存) |
| 扩缩容 | 在线扩缩容(自动 Rebalance) | 手动(需 Reshard) |
| 高可用 | Raft 三副本(自动故障转移) | 副本 + ZooKeeper(手动切换) |
| 适用场景 | OLTP + 实时分析 | 海量数据聚合分析 |
二、性能基准
2.1 TPC-C(OLTP 基准)
sql
-- ======== TPC-C 测试结果(参考)========
--
-- 测试环境:3 节点 TiKV(16C/64GB)
-- 测试工具:go-ycsb
--
-- TiDB:
-- TPC-C NewOrder 吞吐量:~120,000 TPM(3 节点)
-- 平均延迟:~15ms
-- 99 分位延迟:~50ms
--
-- ClickHouse:
-- ❌ 不适合 TPC-C(无事务支持)
-- 强行测试:~5,000 TPM(单节点,无事务)
-- 点查延迟:~500ms(无行存索引)
2.2 TPC-H(OLAP 基准)
sql
-- ======== TPC-H Q1(百万级数据聚合)========
-- TiDB(TiFlash 开启)
SELECT
l_returnflag,
l_linestatus,
SUM(l_quantity) AS sum_qty,
SUM(l_extendedprice) AS sum_base_price,
SUM(l_extendedprice * (1 - l_discount)) AS sum_disc_price
FROM lineitem
WHERE l_shipdate <= DATE '1998-12-01' - INTERVAL '90' DAY
GROUP BY l_returnflag, l_linestatus
ORDER BY l_returnflag, l_linestatus;
-- 执行时间(100GB 数据):
-- TiDB + TiFlash:~12 秒
-- ClickHouse:~3 秒 ← 列式存储优势明显
-- ======== TPC-H Q3(三表 JOIN)========
SELECT
l_orderkey,
SUM(l_extendedprice * (1 - l_discount)) AS revenue,
o_orderdate,
o_shippriority
FROM customer, orders, lineitem
WHERE c_mktsegment = 'BUILDING'
AND c_custkey = o_custkey
AND l_orderkey = o_orderkey
AND o_orderdate < DATE '1995-03-15'
AND l_shipdate > DATE '1995-03-15'
GROUP BY l_orderkey, o_orderdate, o_shippriority
ORDER BY revenue DESC, o_orderdate;
-- 执行时间(100GB 数据):
-- TiDB:~45 秒(TiFlash 列存 JOIN)
-- ClickHouse:~8 秒
三、TiDB 实战
3.1 部署(Docker Compose)
yaml
# ======== docker-compose.yml(本地开发)========
version: '3'
services:
pd:
image: pingcap/pd:v7.5.0
ports:
- "2379:2379"
command:
- --name=pd1
- --client-urls=http://0.0.0.0:2379
- --peer-urls=http://0.0.0.0:2380
- --initial-cluster=pd1=http://pd1:2380
volumes:
- pd1:/data/pd
tikv:
image: pingcap/tikv:v7.5.0
ports:
- "20160:20160"
command:
- --addr=0.0.0.0:20160
- --pd=pd1:2379
volumes:
- tikv1:/data/tikv
tidb:
image: pingcap/tidb:v7.5.0
ports:
- "4000:4000" # MySQL 协议端口
- "10080:10080" # 状态端口
command:
- --pd=pd1:2379
- --store=tikv
tiflash:
image: pingcap/tiflash:v7.5.0
ports:
- "9000:9000"
command:
- --pd=pd1:2379
volumes:
pd1:
tikv1:
# 启动
# docker-compose up -d
# 连接(MySQL 协议)
# mysql -h 127.0.0.1 -P 4000 -u root
3.2 TiFlash 列存加速
sql
-- ======== 开启 TiFlash 副本(HTAP 核心)========
-- 1. 为表创建 TiFlash 副本(默认 1 副本)
ALTER TABLE orders SET TIFLASH REPLICA 1;
-- 2. 查看 TiFlash 副本状态
SELECT * FROM information_schema.tiflash_replica;
-- 3. 强制使用 TiFlash(忽略 TiKV 行存)
SELECT /*+ READ_FROM_STORAGE(TIFLASH[orders]) */
user_id,
COUNT(*) AS order_count,
SUM(amount) AS total_amount
FROM orders
WHERE created_at >= '2026-01-01'
GROUP BY user_id;
-- 4. 让优化器自动选择(推荐)
-- TiDB 会根据成本估算自动选择 TiKV 或 TiFlash
-- 点查 → TiKV(行存索引快)
-- 全表扫描/聚合 → TiFlash(列存压缩高)
3.3 分布式事务实战
go
// ======== Go + TiDB(分布式事务)========
package main
import (
"context"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func TransferMoney(ctx context.Context, db *sql.DB, from, to int, amount float64) error {
// TiDB 支持分布式事务(Percolator 模型)
// 自动处理 2PC,对应用透明
tx, err := db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer tx.Rollback()
// 扣款
_, err = tx.ExecContext(ctx,
"UPDATE accounts SET balance = balance - ? WHERE id = ?",
amount, from)
if err != nil {
return err
}
// 加款
_, err = tx.ExecContext(ctx,
"UPDATE accounts SET balance = balance + ? WHERE id = ?",
amount, to)
if err != nil {
return err
}
// 写入转账记录
_, err = tx.ExecContext(ctx,
"INSERT INTO transfers (from_id, to_id, amount) VALUES (?, ?, ?)",
from, to, amount)
if err != nil {
return err
}
return tx.Commit()
}
// TiDB 自动处理分布式事务的 2PC
// 应用无需感知 Percolator 协议细节
四、ClickHouse 实战
4.1 表引擎选择
sql
-- ======== MergeTree(核心引擎)========
CREATE TABLE orders (
order_id UInt64,
user_id UInt32,
amount Decimal(12,2),
created_at DateTime
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(created_at) -- 按月分区
ORDER BY (user_id, created_at) -- 排序键(关键!影响查询性能)
TTL created_at + INTERVAL 90 DAY; -- 90 天自动删除
-- ======== ReplacingMergeTree(去重)========
CREATE TABLE user_profiles (
user_id UInt32,
name String,
email String,
updated_at DateTime
) ENGINE = ReplacingMergeTree(updated_at) -- 按 updated_at 去重
ORDER BY user_id;
-- 写入重复数据,后台 Merge 时自动去重
INSERT INTO user_profiles VALUES (1, 'Alice', 'a@test.com', '2026-01-01');
INSERT INTO user_profiles VALUES (1, 'Alice', 'alice@test.com', '2026-06-01');
-- 查询时只返回最新版本
-- ======== Distributed(分布式表)========
-- 1. 先创建本地表(每个节点)
CREATE TABLE orders_local (
...
) ENGINE = MergeTree() ...;
-- 2. 再创建分布式表(逻辑视图,不存数据)
CREATE TABLE orders_all AS orders_local
ENGINE = Distributed('cluster_1', 'default', 'orders_local', rand());
-- 写入 distributed 表,数据自动散列到各节点
-- 查询 distributed 表,自动聚合各节点结果
4.2 性能优化
sql
-- ======== 1. 索引优化 ========
-- ClickHouse 有 2 种索引:
-- - 主键索引(ORDER BY,稀疏索引)
-- - Skipping Index(数据跳扫索引)
-- 主键索引(最关键!)
-- 查询过滤条件必须命中 ORDER BY 前缀
CREATE TABLE events (
event_date Date,
user_id UInt32,
event_type String,
value Int64
) ENGINE = MergeTree()
PARTITION BY event_date
ORDER BY (event_date, user_id, event_type); -- ← 查询条件要覆盖前缀
-- ✅ 快:命中 ORDER BY 前缀
SELECT * FROM events WHERE event_date = '2026-06-23' AND user_id = 123;
-- ❌ 慢:未命中前缀(全量扫描)
SELECT * FROM events WHERE user_id = 123;
-- ======== 2. 物化视图(预聚合)========
-- 场景:实时统计每日每用户事件数
CREATE TABLE events_daily_mv (
event_date Date,
user_id UInt32,
event_count UInt64,
total_value Int64
) ENGINE = SummingMergeTree() -- 相同 key 自动 SUM 合并
ORDER BY (event_date, user_id);
-- 源表写入时自动更新物化视图
CREATE MATERIALIZED VIEW events_daily_mv_refresh
TO events_daily_mv
AS SELECT
event_date,
user_id,
COUNT(*) AS event_count,
SUM(value) AS total_value
FROM events
GROUP BY event_date, user_id;
-- 查询物化视图(毫秒级)
SELECT * FROM events_daily_mv WHERE event_date = '2026-06-23';
-- ======== 3. 批量写入(必须攒批!)========
-- ❌ 错误:逐条 INSERT(性能极差)
for i in {1..100000}; do
echo "INSERT INTO orders VALUES ($i, 'user$i', 100)" | clickhouse-client
done
-- ✅ 正确:批量 INSERT(至少 1000 行/批)
-- 方式1:CSV 导入
clickhouse-client --query "INSERT INTO orders FORMAT CSV" < data.csv
-- 方式2:JDBC 批量(addBatch + executeBatch)
-- 方式3:HTTP Interface 批量
echo -e "1,'user1',100\n2,'user2',200\n..." | \
curl 'http://localhost:8123/?query=INSERT+INTO+orders+FORMAT+CSV' --data-binary @-
五、HTAP 架构设计
5.1 TiDB HTAP 架构
# ======== TiDB HTAP 数据流向 ========
应用写入(OLTP)
│
▼
┌─────────────┐
│ TiDB Server │ (SQL 解析 + 优化器)
└──────┬──────┘
│
┌───────┴───────┐
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ TiKV │ │ TiFlash │
│ (行存) │◄───│ (列存) │
│ 支持事务 │RaFT│ 分析加速 │
└─────────────┘ └─────────────┘
│ │
└──────────┬──────────┘
│
▼
智能选择执行计划
(优化器自动选择 TiKV 或 TiFlash)
# 实战:订单分析系统
#
# 1. TP 操作(TiKV 行存):
# - 下单:INSERT INTO orders VALUES (...)
# - 支付:UPDATE orders SET status='paid' WHERE id=123
# - 点查:SELECT * FROM orders WHERE id=123
#
# 2. AP 操作(TiFlash 列存):
# - 日报:SELECT DATE(created_at), COUNT(*) FROM orders GROUP BY 1
# - 用户消费排名:SELECT user_id, SUM(amount) FROM orders GROUP BY 1 ORDER BY 2 DESC
# - 优化器自动选择 TiFlash,无需修改 SQL
5.2 双写架构(TiDB + ClickHouse)
# ======== 混合架构(TP + AP 分离)========
#
# 场景:TP 用 TiDB,AP 用 ClickHouse(各取所长)
#
# 数据流向:
# 应用写入 → TiDB(TP 操作)
# │
# │ 变更捕获(TiCDC)
# ▼
# Kafka / Canal
# │
# ▼
# ClickHouse(AP 分析)
#
# ======== 使用 TiCDC 同步到 ClickHouse ========
# 1. 部署 TiCDC
tiup ctl:v7.5.0 cdc cli changefeed create \
--pd=http://pd1:2379 \
--sink-uri="kafka://kafka1:9092/changefeed-1" \
--changefeed-id="to-clickhouse"
# 2. ClickHouse 消费 Kafka 数据
-- 创建 Kafka 引擎表
CREATE TABLE orders_kafka (
order_id UInt64,
user_id UInt32,
amount Decimal(12,2),
created_at DateTime
) ENGINE = Kafka()
SETTINGS
kafka_broker_list = 'kafka1:9092',
kafka_topic_list = 'changefeed-1',
kafka_group_name = 'clickhouse-consumer',
kafka_format = 'JSONEachRow';
-- 创建物化视图,自动从 Kafka 同步到本地表
CREATE MATERIALIZED VIEW orders_sync TO orders_local AS
SELECT * FROM orders_kafka;
六、选型决策树
# ======== TiDB vs ClickHouse 选型 ========
#
# 你的场景是?
#
# ├── 需要完整 ACID 事务(银行/电商/ERP)
# │ └── 选 TiDB ✅
# │
# ├── 主要做海量数据聚合分析(BI/报表/日志分析)
# │ └── 选 ClickHouse ✅
# │
# ├── 需要同时支持 TP + AP(HTAP)
# │ ├── 预算充足 → TiDB(一套系统搞定)
# │ └── 预算有限 → TiDB(TP)+ ClickHouse(AP)混合架构
# │
# ├── MySQL 迁移(零改动)
# │ └── 选 TiDB ✅(100% 兼容)
# │
# └── 实时数仓(Flink + 数仓)
# └── 选 ClickHouse ✅(Flink 官方 Connector 支持)
七、Checklist 总结
□ TiDB 部署
□ TiDB Server(无状态 SQL 层)
□ PD(元数据 + 调度)
□ TiKV(行存 + 事务)
□ TiFlash(列存 + 分析加速)
□ 监控(Grafana + Prometheus)
□ TiDB 优化
□ 开启 TiFlash 副本(ALTER TABLE ... SET TIFLASH REPLICA)
□ 索引优化(覆盖索引 / 前缀索引)
□ 分布式事务(避免热点 Key)
□ 分区表(按时间分区)
□ ClickHouse 部署
□ MergeTree 引擎(核心)
□ ReplacingMergeTree(去重)
□ Distributed 表(分布式查询)
□ ZooKeeper/Keeper(元数据)
□ ClickHouse 优化
□ ORDER BY(排序键设计,必须命中前缀)
□ 批量写入(至少 1000 行/批)
□ 物化视图(预聚合)
□ TTL(自动清理历史数据)
□ HTAP 架构
□ TiDB 单系统(TP + AP 混合)
□ TiDB + ClickHouse(双写架构)
□ TiCDC(变更捕获同步)
□ 查询路由(TP 路由 TiDB,AP 路由 ClickHouse)
总结
TiDB vs ClickHouse 一句话选型:
| 需求 | 选什么 |
|---|---|
| MySQL 兼容迁移 | TiDB |
| 完整 ACID 事务 | TiDB |
| 海量数据聚合分析 | ClickHouse |
| TP + AP 混合负载 | TiDB(HTAP) |
| 实时数仓 | ClickHouse |
| 金融级高可用 | TiDB |
HTAP 两种架构:
- TiDB 单系统:TiKV(TP)+ TiFlash(AP),优化器自动路由
- 混合架构:TiDB(TP)+ ClickHouse(AP),TiCDC 同步