0
0
0
0
博客/.../

TiDB vs MongoDB:结构化与非结构化数据存储方案全面对比

 Billmay表妹  发表于  2026-06-02
原创

摘要

TiDB(关系型分布式数据库)与 MongoDB(文档型数据库)代表了数据存储的两种核心范式。TiDB 继承了关系型数据库的严谨数据模型和强事务保证,MongoDB 则以灵活的文档模型和敏捷开发著称。本文从数据模型、查询能力、事务支持、扩展方式和适用场景五个维度进行系统对比,帮助技术团队根据业务特征选择最合适的存储方案。

本文适合谁:正在评估关系型与文档型数据库选型的技术架构师、后端负责人,以及需要同时处理结构化和非结构化数据的系统设计师。


一、数据模型对比

1.1 核心数据模型差异

维度 TiDB MongoDB
数据模型 关系型(表 + 行 + 列) 文档型(集合 + 文档/BSON)
Schema 策略 固定 Schema(DDL 定义) 动态 Schema(灵活文档结构)
数据格式 关系型表格 JSON/BSON 文档
嵌套结构 需要关联表(JOIN) 原生支持嵌套文档
数据类型 SQL 标准数据类型 丰富的 BSON 类型(含数组、日期、二进制等)
数据约束 强约束(NOT NULL、UNIQUE、CHECK) 弱约束(Schema Validation 可选)
多态数据 需要额外列或关联表 原生支持(同一集合不同结构)

1.2 数据模型示例对比

-- TiDB:关系型建模(用户 + 订单,通过外键关联)
CREATE TABLE users (
    id BIGINT PRIMARY KEY AUTO_RANDOM,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(200) NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY uk_email (email)
);

CREATE TABLE orders (
    id BIGINT PRIMARY KEY AUTO_RANDOM,
    user_id BIGINT NOT NULL,
    amount DECIMAL(10,2) NOT NULL,
    status VARCHAR(20) NOT NULL,
    items JSON,  -- 订单明细(JSON 类型)
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_user_id (user_id)
);
// MongoDB:文档型建模(用户 + 订单可内嵌或独立集合)
// 独立集合方式
db.users.insertOne({
    name: "张三",
    email: "zhangsan@example.com",
    createdAt: new Date(),
    tags: ["VIP", "活跃用户"]  // 灵活字段
});

db.orders.insertOne({
    userId: ObjectId("..."),
    amount: NumberDecimal("150.00"),
    status: "completed",
    items: [
        { productId: "P001", name: "商品A", price: 50, qty: 2 },
        { productId: "P002", name: "商品B", price: 50, qty: 1 }
    ],
    createdAt: new Date()
});

// 内嵌方式(订单直接嵌入用户文档)
db.users.insertOne({
    name: "张三",
    email: "zhangsan@example.com",
    orders: [
        { amount: 150, status: "completed", items: [...] }
    ]
});

1.3 数据模型选型要点

场景 推荐 TiDB 推荐 MongoDB
数据结构固定、关系明确 强关系约束更安全 Schema 过度灵活反而增加风险
数据结构多变、频繁迭代 Schema 变更需要 DDL 迁移 动态 Schema 天然适配
强数据一致性要求 完整约束 + 事务保证 Schema Validation 可选,但不如 SQL 严格
复杂嵌套文档 JSON 类型支持,但查询不如原生文档灵活 原生嵌套查询能力更强
多对多关系 JOIN 高效处理 需要 denormalize 或 $lookup

二、查询能力对比

2.1 查询能力矩阵

查询能力 TiDB MongoDB
点查(主键) 优秀(B+ Tree) 优秀(B+ Tree / Hash)
范围查询 优秀(索引支持) 良好(索引支持)
多条件 AND/OR 优秀(多列索引 + 优化器) 良好(复合索引)
JOIN 原生支持(优化器自动选择路径) $lookup 聚合管道(性能有限)
子查询 完整支持 支持($expr、聚合子查询)
窗口函数 完整支持 5.0+ 支持($setWindowFields)
CTE 支持 支持($lookup with pipeline)
全文检索 内置全文索引(有限) Atlas Search / Text Index
地理空间查询 支持(MySQL 空间函数) GeoJSON 原生支持(2dsphere)
聚合管道 GROUP BY + 窗口函数 aggregation pipeline(丰富但性能波动)
JSON 查询 JSON 函数(->、->>) 原生文档路径查询

2.2 JOIN 查询对比

-- TiDB:原生 JOIN(优化器自动选择最佳执行计划)
SELECT
    u.name,
    u.email,
    o.id AS order_id,
    o.amount,
    o.status,
    o.created_at
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE u.id = 1001
ORDER BY o.created_at DESC;
-- 单次查询,执行时间 < 1ms
// MongoDB:$lookup 实现 JOIN
db.users.aggregate([
    { $match: { _id: ObjectId("...") } },
    {
        $lookup: {
            from: "orders",
            localField: "_id",
            foreignField: "userId",
            as: "user_orders"
        }
    },
    { $unwind: "$user_orders" },
    { $sort: { "user_orders.createdAt": -1 } },
    {
        $project: {
            name: 1,
            email: 1,
            orderId: "$user_orders._id",
            amount: "$user_orders.amount",
            status: "$user_orders.status"
        }
    }
]);
// 聚合管道方式,性能不如 TiDB 原生 JOIN

2.3 JSON/文档查询对比

-- TiDB:JSON 函数查询
SELECT
    id,
    JSON_EXTRACT(items, '$[0].name') AS first_item,
    JSON_LENGTH(items) AS item_count
FROM orders
WHERE JSON_CONTAINS(items, '"P001"', '$[*].productId');

-- TiDB 5.x+:JSON Table Value Function
SELECT jt.product_id, jt.name, jt.qty
FROM orders,
    JSON_TABLE(items, '$[*]' COLUMNS (
        product_id VARCHAR(20) PATH '$.productId',
        name VARCHAR(100) PATH '$.name',
        qty INT PATH '$.qty'
    )) AS jt
WHERE id = 1001;
// MongoDB:原生文档路径查询
db.orders.find(
    { "items.productId": "P001" },
    { "items.$": 1 }
);
// 原生路径表达式,语法简洁

三、事务支持对比

事务指标 TiDB MongoDB
事务模型 分布式事务(Percolator + 2PC) 多文档事务(4.0+,基于两阶段提交)
隔离级别 RC、RR、Serializable Snapshot Isolation(快照隔离)
一致性保证 线性一致性(Raft) 因部署模式而异(因果一致性/线性一致性)
跨集合事务 天然支持(跨表事务) 4.0+ 支持跨集合事务(性能有开销)
事务大小限制 建议 < 100MB 16MB 文档大小限制影响事务范围
分布式事务延迟 跨 Region 有网络开销 分片事务有额外开销
事务性能 OLTP 场景优秀 多文档事务性能比单文档操作低 30-50%

事务使用对比

-- TiDB:分布式事务(应用无感知)
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1001;
UPDATE accounts SET balance = balance + 100 WHERE id = 2002;
INSERT INTO transactions (from_id, to_id, amount) VALUES (1001, 2002, 100);
COMMIT;
// MongoDB:多文档事务(需要显式 session)
const session = client.startSession();
try {
    session.startTransaction();
    await db.accounts.updateOne(
        { _id: 1001 },
        { $inc: { balance: -100 } },
        { session }
    );
    await db.accounts.updateOne(
        { _id: 2002 },
        { $inc: { balance: 100 } },
        { session }
    );
    await db.transactions.insertOne(
        { fromId: 1001, toId: 2002, amount: 100 },
        { session }
    );
    await session.commitTransaction();
} finally {
    session.endSession();
}

四、扩展方式对比

扩展维度 TiDB MongoDB
水平扩展方式 增加节点,PD 自动调度数据 增加分片(Shard),Balancer 自动均衡
分片策略 自动(Range 分裂) Hash / Range / 自定义分片键
扩展透明度 对应用完全透明 大部分透明(分片键选择影响性能)
弹性扩缩容 在线扩缩容,秒级生效 在线扩缩容,分钟级生效
数据均衡 PD 调度,Region 自动迁移 Config Server + Balancer
多数据中心 原生跨 Region 部署 Zone/Shard 策略 + Cross-DC 复制
存储计算分离 是(计算/存储独立扩展) 部分支持(Shared 策略可配置)

五、适用场景分析

5.1 推荐使用 TiDB 的场景

场景 原因
金融交易、账务系统 强事务、强一致性、数据约束
ERP/CRM/OA 系统 关系模型天然匹配、复杂 JOIN 需求
电商订单与库存管理 事务一致性 + 实时查询 + 分析
SaaS 多租户系统 强隔离 + 灵活权限 + HTAP
实时报表与 BI HTAP 一体化,无需额外分析系统

5.2 推荐使用 MongoDB 的场景

场景 原因
内容管理系统(CMS) 灵活 Schema,内容结构多变
物联网数据采集 多态设备数据,字段不固定
用户画像/行为日志 嵌套文档,灵活标签
实时分析中间层 高写入吞吐 + 灵活查询
移动应用后端 Schema 灵活 + 开发敏捷

5.3 混合使用场景

在实际系统中,TiDB 与 MongoDB 可以各司其职:

混合架构:
┌──────────┐     ┌──────────┐     ┌──────────┐
│ 业务系统  │────▶│ TiDB     │     │ MongoDB  │
└──────────┘     │核心业务数据│     │灵活文档数据│
                │(订单/账务)│     │(日志/画像)│
                └──────────┘     └──────────┘
                                   │
                                   ▼
                                搜索引擎
                                缓存层

FAQ

Q1:TiDB 的 JSON 类型能否替代 MongoDB 的文档存储能力?

TiDB 支持原生 JSON 数据类型和 JSON 函数,可以存储和查询半结构化数据。但在以下方面不如 MongoDB:嵌套文档的灵活查询语法、原生文档更新操作符($push/$pull/$set)、多态文档的存储效率。如果你的数据以非结构化文档为主,MongoDB 仍然是更合适的选择。

Q2:MongoDB 的事务性能能否满足核心交易场景?

MongoDB 从 4.0 开始支持多文档事务,在单分片场景下事务性能表现良好。但在跨分片分布式事务场景下,性能开销显著增大(约 30-50%),且快照隔离级别不如 TiDB 的 RR 级别严格。对于金融核心交易等对事务性能和一致性要求极高的场景,TiDB 是更稳健的选择。

Q3:TiDB 能否存储非结构化数据?

TiDB 通过 JSON 数据类型可以存储非结构化数据,单个 JSON 列最大支持 1GB(由 max_allowed_packet 控制)。同时 TiDB 提供 JSON Table Value Function,可以将 JSON 数据展开为关系型表进行查询。但 TiDB 的 JSON 能力是关系型数据库的扩展,不是核心设计,大规模 JSON 数据的查询性能和灵活性不如 MongoDB。

Q4:从 MongoDB 迁移到 TiDB 需要注意什么?

迁移需要注意以下关键问题:Schema 设计转换(从文档模型转为关系模型)、嵌套文档的展平、$lookup 查询转为 SQL JOIN、灵活字段的处理(可使用 JSON 列保留灵活性)、MongoDB 特有操作符的替代(如 $push/$pull 改为 SQL UPDATE)。建议使用 TiDB 提供的迁移工具进行数据导入,并充分测试查询兼容性。


总结

TiDB 与 MongoDB 分属关系型与文档型数据库的代表性产品,各自在擅长的领域具有不可替代的优势。TiDB 在强事务、复杂关系查询、数据一致性约束方面表现卓越,适合核心业务系统;MongoDB 在 Schema 灵活性、嵌套文档处理、快速迭代开发方面优势突出,适合内容管理、物联网、日志分析等场景。

选择的关键不在于"哪个更好",而在于业务数据的特征和需求。如果数据以固定结构的关系型数据为主,需要强事务保证和复杂查询能力,TiDB 是更合适的选择。如果数据以多变的非结构化文档为主,需要灵活的 Schema 和快速的迭代能力,MongoDB 更有优势。在复杂业务系统中,两者可以配合使用。


下一步行动

  1. 试用 TiDB:体验 TiDB 的关系型分布式能力,验证 SQL 兼容性和 JSON 数据类型支持。

TiDB 免费试用

  1. 获取结构化数据解决方案:了解 TiDB 在金融、电商、SaaS 等结构化数据密集型行业的最佳实践。

TiDB 行业解决方案

  1. 申请 POC 测试:提供您的数据模型,获取专属的 TiDB POC 测试环境和迁移评估报告。

申请 POC 测试


相关资源

0
0
0
0

版权声明:本文为 TiDB 社区用户原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接和本声明。

评论
暂无评论