SQL vs NoSQL:你的应用应该使用哪种数据库?
SQL 数据库(也称关系型数据库)把数据存放在具有固定结构的表中,即行和列,并将相关的表关联起来。你使用 SQL 语言进行查询。Postgres、MySQL 和 SQLite 都是例子。NoSQL 数据库采用其他的数据存储方式,例如文档、键值对、宽列或图,通常结构更灵活。MongoDB、Redis、DynamoDB 和 Firestore 都是例子。对于大多数商业应用,SQL 数据库是明智的默认选择;NoSQL 则在特定任务上表现出色。
使用 AI 构建时,为什么这个选择很重要
数据库是应用中后期最难更改的部分之一。界面可以在一个下午重新设计,但把多年的客户数据迁移到另一种数据库则是一个完整的项目。
当 AI 应用构建器为你添加数据存储时,它实际上是在为你选择其中一种。了解两者的区别能帮助你:
- 理解你的数据是什么样子,以及它能否回答你以后会问的问题(例如“按月、按产品统计的收入”)。
- 评估平台选择。 有些平台基于文档数据库构建,另一些基于关系型数据库。常见的例子可参阅 Supabase vs Firebase,分别代表两种类型。
- 避免被锁定。 SQL 是通用标准,因此关系型数据通常更容易在不同服务商之间迁移。
日常类比
SQL 数据库就像一组结构严格、列定义清晰的电子表格:一张表放客户,一张表放订单,每条订单记录通过 ID 指向对应的客户记录。每张表中的每一行都有相同的列。前期需要一些规划,但跨表提问很容易,数据也保持整洁。
NoSQL 文档数据库则像一个装满文件夹的文件柜。每位客户的文件夹可以把他的资料和订单都放在一起,某个文件夹还可以放其他文件夹没有的文件。要快速拿到某个客户的全部信息很方便。但要回答“上个月每个人都买了什么?”,则需要打开许多文件夹。
真正的区别
| SQL(关系型) | NoSQL | |
|---|---|---|
| 数据形态 | 具有固定列的表 | 文档、键值、宽列或图 |
| 结构 | 预先定义模式,通过迁移修改 | 通常灵活;结构如果有约束,也是由应用代码来强制执行的 |
| 关系 | 内置:外键和连接(JOIN) | 通常通过嵌套数据或应用代码处理 |
| 查询语言 | SQL,通用标准 | 每个产品各不相同 |
| 一致性 | 强事务是标准配置 | 因产品和设置而异;许多产品现在也提供事务 |
| 扩展方式 | 传统上是纵向扩展(使用更大的服务器);横向扩展可行但更难 | 许多产品从设计上就支持分散到多台服务器 |
| 擅长 | 商业数据、报表,以及关系众多的数据 | 海量简单记录、缓存、灵活的内容 |
| 代表产品 | Postgres、MySQL、SQLite、SQL Server | MongoDB、Redis、DynamoDB、Firestore、Cassandra、Neo4j |
“NoSQL”并不是一种东西。主要有以下几类:
| 类型 | 数据存储方式 | 典型用途 |
|---|---|---|
| 文档型(MongoDB、Firestore) | 类 JSON 文档 | 内容、目录、记录结构多样的应用 |
| 键值型(Redis、DynamoDB) | 通过键查找对应的值 | 缓存、会话、计数器 |
| 宽列型(Cassandra) | 列集合灵活的行 | 数据量巨大、写入密集的数据集 |
| 图型(Neo4j) | 节点与连接关系 | 社交网络、推荐 |
实例:同一份店铺数据,两种存法
以一家小型网店为例,其中有一位客户和她的订单。
SQL(关系型): 数据被拆分到多张表中,并通过 ID 关联。
-- customers: id=1, name='Lena Ortiz'
-- orders: id=101, customer_id=1, total=42.00
-- id=103, customer_id=1, total=25.00
SELECT c.name, SUM(o.total)
FROM customers c JOIN orders o ON o.customer_id = c.id
GROUP BY c.name;
如果 Lena 更改了邮箱,只需在一处修改。统计“本月每位客户的总销售额”也只需一条查询。
NoSQL(文档型): 她的订单可以直接存放在她的文档内部。
{
"_id": "cust_1",
"name": "Lena Ortiz",
"email": "lena@example.com",
"orders": [
{ "id": 101, "total": 42.00, "items": ["Green tea"] },
{ "id": 103, "total": 25.00, "items": ["Teapot"] }
]
}
加载 Lena 的个人资料页并显示她的全部订单只需一次读取。但那些跨越所有客户的问题(例如本月最畅销的产品)需要更多工作;如果同一产品的详细信息被复制到许多订单中,保持它们同步就成了应用自己的责任。
两者并无对错,关键在于你的应用最常做哪种操作。
如何选择
如果符合以下情况,关系型 SQL 数据库通常是合适的默认选择:
- 你的数据关系众多:用户、团队、预约、发票、产品。
- 你需要跨记录进行报表、筛选和汇总。
- 正确性很重要:资金、库存水平、权限。
如果符合以下情况,则值得考虑 NoSQL 数据库:
- 你需要快速的缓存或会话存储。Redis 在这方面很常见,通常与 SQL 数据库一同使用。
- 你的记录数量巨大、结构简单且彼此独立,例如事件日志或传感器读数。
- 你使用的平台是围绕某种 NoSQL 构建的,例如 Firebase 的 Firestore,而其实时功能正是主要卖点。
许多应用会同时使用两者:以 SQL 作为主要的数据来源,再用 NoSQL 存储来做缓存或实现某项特定功能。
关键术语
| 术语 | 含义 |
|---|---|
| 关系型数据库 | 由相互关联的表组成的 SQL 数据库。 |
| 模式(Schema) | 数据定义好的结构。 |
| 连接(Join) | 在一次查询中合并两张表中相关的行。 |
| 文档(Document) | 文档数据库中自包含的类 JSON 记录。 |
| 反规范化(Denormalisation) | 为了加快读取速度,将数据复制到多个位置。 |
| ACID | 保证事务可靠性的特性:原子性、一致性、隔离性和持久性。 |
| 水平扩展(Horizontal scaling) | 将数据分散到多台服务器,而不是依赖一台更大的服务器。 |
常见误解
- “NoSQL 意味着没有模式。” 你的数据始终有其形态。在 NoSQL 中,数据库可能不会强制执行该形态,因此需要由你的代码来保证。
- “SQL 无法扩展。” 关系型数据库可以支撑非常大型的服务。大多数应用永远不会接近它们的上限。
- “NoSQL 总是更快。” 只有在它所设计的访问模式下才是如此。跨多表的综合报表可能会更慢。
- “选定一种就得永远用下去。” 许多应用会同时结合两者。而且 Postgres 等 SQL 数据库也能存储 JSON,因此少量灵活字段并不需要 NoSQL。
- “NoSQL 意味着不能使用 SQL。” 这个名称通常被理解为“不仅是 SQL”(Not only SQL),而且一些 NoSQL 产品也提供类 SQL 的查询语言。
可以向你的 AI 构建器提出的问题
- “这个应用使用哪种数据库?为什么它适合我的数据?”
- “请画出表或集合的结构以及它们之间的关系。”
- “六个月后我会想要哪些报表?这个数据库能轻松回答它们吗?”
- “如果有几个字段确实比较灵活,就把它们以 JSON 形式存在 Postgres 中,而不是再增加一个数据库。”
- “只有当我们发现了可以测量的速度问题时,才添加缓存。”
Mythex 中的数据库
Mythex 会为每个需要数据库的项目提供一个专用的 Postgres 数据库,即关系型 SQL 数据库。你可以在应用需要时通过聊天提出请求,也可以使用 /database 命令添加(数据库文档)。这适合大多数商业应用:用户、预约、订单和报表。如果你需要某个外部服务,例如托管的文档数据库,智能体可以编写代码,使用你保存在项目密钥中的凭据来连接它。要进一步了解 SQL 语言本身,请阅读 什么是 SQL。
常见问题
SQL 和 NoSQL 的主要区别是什么?
SQL 数据库把数据存放在具有固定结构的表中,并将相关的表关联起来,使用 SQL 进行查询。NoSQL 数据库采用其他模型,例如文档、键值对、宽列或图,通常结构更灵活,而且每个产品都有自己的查询方式。
NoSQL 比 SQL 更快吗?
一般来说并非如此。两者都在其设计的访问模式下表现良好。键值存储在按键获取单条数据时非常快;关系型数据库则擅长过滤、关联和汇总相关数据。设计和索引的重要性远高于数据库类别本身。
对于初创公司或小型应用,哪种更好?
对于大多数商业应用,例如客户、订单、预约、用户和权限,Postgres 等关系型 SQL 数据库是一个稳妥的默认选择。NoSQL 适合特定需求,例如缓存、某些平台中的实时同步,或者海量的简单独立记录。
MongoDB 是 SQL 还是 NoSQL?
MongoDB 是 NoSQL 文档数据库。它将记录存储为灵活的类 JSON 文档,而不是表中的行。
SQL 数据库能存储 JSON 吗?
可以。Postgres 提供了 jsonb 类型,用于存储和查询 JSON,MySQL 和 SQLite 也支持 JSON。这样许多应用就能保留关系型的核心,再加上少量灵活字段,而无需额外的 NoSQL 数据库。