跳至主要內容

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 面临以下挑战:

  1. 扩展性不足: SQL 数据库因为 ACID 特性限制,很难在集群中实现水平扩展。
  2. 高并发需求: 随着用户量和数据量的爆炸式增长,单点数据库性能无法满足需求。
  3. 灵活性不足: 固定的 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 的四种主要类型

  1. 键值存储 (Key-Value Store)

    • 数据结构: 简单的键值对(Key-Value),值是平面的。
    • 优势: 最简单的 NoSQL 模型,高性能,通常用于缓存、高速查找场景。
    • 示例: Redis、Memcached、etcd。
    • 适用场景: 存储会话信息、购物车数据、配置文件等,通常是将 SQL 数据库作为主存储,用键值数据库做缓存层。

    示例:

    "user123": "Alice"
    "user124": "Bob"
    

  1. 文档存储 (Document Store)

    • 数据结构: 数据以 JSON 或类似格式存储,支持嵌套的键值对。
    • 优势: 无 Schema 设计,灵活性强,支持大规模数据存储,适合处理半结构化数据。
    • 示例: MongoDB、CouchDB。
    • 适用场景: 动态数据结构、大规模存储和查询,如内容管理系统(CMS)、实时分析、产品目录等。

    示例:

    {
    	"id": 1,
    	"name": "Alice",
    	"orders": [
    		{ "id": 101, "item": "Laptop" },
    		{ "id": 102, "item": "Phone" }
    	]
    }
    

  1. 宽列存储 (Wide-Column Store)

    • 数据结构: 基于表格存储,但行和列的 Schema 非固定。
    • 优势: 支持海量数据,擅长快速写入。
    • 示例: Cassandra、Google BigTable。
    • 适用场景: 大规模写操作为主,读操作较少,如时序数据、日志系统。

    示例:

    KeyColumnFamily:User
    user123name: Alice, email: alice@mail
    user124name: Bob, email: bob@mail

  1. 图数据库 (Graph Database)

    • 数据结构: 以节点和边的形式建模。
    • 优势: 专注于存储和操作关系型数据。
    • 示例: Neo4j、JanusGraph。
    • 适用场景: 社交网络关注与粉丝关系、推荐系统、社交图谱关系分析。

    示例:

    Alice -- Knows --> Bob
    Alice -- Likes --> Music