16. NoSQL
16. NoSQL
NoSQL 是 “Not Only SQL” 的缩写,指的是非关系型数据库。与传统的 SQL(关系型数据库 RDBMS)不同,NoSQL 数据库没有标准的查询语言和固定的表结构,主要用于解决传统关系型数据库在某些特定场景下的局限性,尤其是在可扩展性和性能方面,适用于非结构化或半结构化数据的存储和操作。
NoSQL 和 SQL 的对比
特性 | SQL 数据库 | NoSQL 数据库 |
---|---|---|
结构 | 固定的表结构 (Schema) | 动态或无固定 Schema |
数据结构 | 表(Rows & Columns) | 样化(Key-Value, 文档, 图等) |
查询语言 | 使用 SQL 标准查询语言 | 没有统一的查询语言 |
扩展性 | 垂直扩展 (增加硬件资源) | 水平扩展 (增加服务器节点) |
一致性模型 | 强一致性 (ACID) | 最终一致性 (BASE) |
适用场景 | 事务性强、数据模型固定 | 海量数据、高并发、灵活数据结构 |
SQL 强调数据一致性和结构化,而 NoSQL 则优先考虑扩展性和灵活性。NoSQL 并不是要取代 SQL,而是针对特定需求提供补充,两者的选择通常取决于具体的需求和应用场景。
NoSQL 的动机:扩展性(Scale)
在现代分布式系统中,尤其是互联网规模的应用,传统的关系型数据库 RDBMS 面临以下挑战:
- 扩展性不足: SQL 数据库因为 ACID 特性限制,很难在集群中实现水平扩展。
- 高并发需求: 随着用户量和数据量的爆炸式增长,单点数据库性能无法满足需求。
- 灵活性不足: 固定的 Schema 难以应对频繁变化或不确定的业务需求。
NoSQL 通过牺牲部分一致性,提高扩展性(Scale)和性能,是为了解决这些问题而生的。
垂直扩展 vs 水平扩展
- 垂直扩展(Vertical Scaling):增加单节点的硬件资源(如内存和 CPU),缺点是成本高,性能提升有限。
- 水平扩展(Horizontal Scaling):增加更多服务器组成集群,分散数据存储和计算压力。优点是更高的扩展性、更低的成本,随之而来的挑战是数据分片 (Sharding) 和分布式一致性。
分片 (Sharding)
分片是 NoSQL 数据库实现水平扩展的核心技术。
- 将数据分成多个部分,每个分片存储在不同的节点上。
- 通过哈希、范围等方式决定数据存储位置。
示例:
- 用户 ID
1-1000
存储在节点 A。 - 用户 ID
1001-2000
存储在节点 B。
下一节我们将详细讲解分片的原理。
最终一致性 (Eventual Consistency)
为了实现高性能和扩展性,NoSQL 通常不遵守严格的 ACID 原则,而采用 BASE 模型:
- 基本可用 (Basically Available): 系统总是可以响应请求,但可能返回旧数据。
- 软状态 (Soft State): 数据状态可能处于不一致。
- 最终一致性 (Eventual Consistency): 数据最终达到一致。
示例场景:
- 数据写入主节点(Leader),异步更新到从节点(Followers)。
- 用户短时间内访问从库,可能读取到旧数据。
- 允许短时间内不同节点的数据状态不一致,以换取更高的性能和扩展性。
NoSQL 的四种主要类型
键值存储 (Key-Value Store)
- 数据结构: 简单的键值对(Key-Value),值是平面的。
- 优势: 最简单的 NoSQL 模型,高性能,通常用于缓存、高速查找场景。
- 示例: Redis、Memcached、etcd。
- 适用场景: 存储会话信息、购物车数据、配置文件等,通常是将 SQL 数据库作为主存储,用键值数据库做缓存层。
示例:
"user123": "Alice" "user124": "Bob"
文档存储 (Document Store)
- 数据结构: 数据以 JSON 或类似格式存储,支持嵌套的键值对。
- 优势: 无 Schema 设计,灵活性强,支持大规模数据存储,适合处理半结构化数据。
- 示例: MongoDB、CouchDB。
- 适用场景: 动态数据结构、大规模存储和查询,如内容管理系统(CMS)、实时分析、产品目录等。
示例:
{ "id": 1, "name": "Alice", "orders": [ { "id": 101, "item": "Laptop" }, { "id": 102, "item": "Phone" } ] }
宽列存储 (Wide-Column Store)
- 数据结构: 基于表格存储,但行和列的 Schema 非固定。
- 优势: 支持海量数据,擅长快速写入。
- 示例: Cassandra、Google BigTable。
- 适用场景: 大规模写操作为主,读操作较少,如时序数据、日志系统。
示例:
Key ColumnFamily:User user123 name: Alice, email: alice@mail user124 name: Bob, email: bob@mail
图数据库 (Graph Database)
- 数据结构: 以节点和边的形式建模。
- 优势: 专注于存储和操作关系型数据。
- 示例: Neo4j、JanusGraph。
- 适用场景: 社交网络关注与粉丝关系、推荐系统、社交图谱关系分析。
示例:
Alice -- Knows --> Bob Alice -- Likes --> Music