NoSQL基础知识
NoSQL 核心定义
NoSQL(Not Only SQL)泛指非关系型数据库,核心针对键值、文档、图形等类型数据存储,天生支持分布式、数据冗余和数据分片特性,旨在提供可扩展、高可用、高性能的大规模数据存储解决方案。需澄清常见误解:NoSQL 并非不能存储关系型数据,只是存储方式与关系型数据库不同,典型代表有 Redis、MongoDB、HBase、Cassandra 等。
SQL 与 NoSQL 的核心区别
| 对比维度 | SQL 数据库(关系型) | NoSQL 数据库(非关系型) |
|---|---|---|
| 数据存储模型 | 结构化存储,基于固定行列的表格 | 非结构化存储,支持文档(JSON 类)、键值对、宽列(动态列表格)、图形(节点 + 边) |
| 发展背景 | 1970 年代诞生,核心目标是减少数据冗余 | 2000 年代后期诞生,核心目标是提升扩展性、降低大规模数据存储成本 |
| 典型产品 | Oracle、MySQL、SQL Server、PostgreSQL | 文档型:MongoDB、CouchDB;键值型:Redis、DynamoDB;宽列型:Cassandra、HBase;图形型:Neo4j、Amazon Neptune |
| ACID 支持 | 完整支持 ACID 事务,保障数据一致性 | 多数不支持 ACID,为扩展性和性能权衡;部分支持(如 MongoDB)但与 SQL 数据库存在差异 |
| 性能影响因素 | 依赖磁盘子系统,需优化查询、索引和表结构 | 依赖硬件集群规模、网络延迟及应用调用方式 |
| 扩展方式 | 以垂直扩展(升级服务器性能)、读写分离、分库分表为主 | 以横向扩展(增加服务器节点)为主,基于分片机制实现 |
| 核心用途 | 普通企业级项目的结构化数据存储 | 场景广泛:图形库适用于关系分析(社交、推荐),键值库适用于高并发状态存储等 |
| 查询语法 | 统一结构化查询语言(SQL) | 无统一语法,因数据库类型而异 |
NoSQL 数据库的核心优势
- 灵活性强:架构和数据模型无需固定 schema,支持快速迭代开发,是半结构化、非结构化数据的理想选择;
- 可扩展性高:原生适配分布式部署,通过横向增加服务器节点扩展存储和性能,无需依赖高端服务器;
- 性能优异:针对特定数据模型和访问模式优化(如 Redis 键值查询、MongoDB 文档操作),性能优于关系型数据库处理同类场景;
- 功能专属:提供适配自身数据模型的强大 API 和数据类型(如 Neo4j 的图形遍历 API),简化开发。
4. NoSQL 数据库的主要类型
(1)键值数据库
- 特点:结构最简单,以 "键 - 值" 对存储,value 字段无格式限制,应用可完全控制存储内容;
- 代表产品:Redis、DynamoDB。
(2)文档数据库
- 特点:数据存储于类似 JSON 的文档中,字段与值成对存在,值支持字符串、数字、数组、对象等类型,结构与代码中对象一致,直观易理解;
- 代表产品:MongoDB、CouchDB。
(3)图形数据库
- 特点:以 "节点(实体)+ 边(关系)" 形式存储,专为高度连接的数据集设计,擅长处理实体间关联关系;
- 典型场景:社交网络、推荐引擎、欺诈检测、知识图谱;
- 代表产品:Neo4j、Giraph、Amazon Neptune。
(4)宽列存储数据库
- 特点:基于 "行 + 动态列" 的表格结构,适合存储海量数据,支持高效列级查询和横向扩展;
- 代表产品:Cassandra、HBase。
字符集
核心概念:字符集与字符编码
(1)字符集
字符集是一系列字符的集合(如文字、标点、表情、),不同字符集支持的字符范围不同(例如部分字符集不支持汉字)。
(2)字符编码
字符编码是字符集与计算机二进制数据的映射规则,核心目的是让计算机存储和传输字符。编码是 "字符→二进制" 的转换过程,解码是反向过程;乱码的本质是编码和解码使用了不兼容的字符集。
常见字符集及特性
(1)ASCII
- 适用场景:现代美国英语,仅定义 128 个字符(含 33 个控制字符);
- 编码方式:1 字节(8 位),最高位为校验位,实际使用 7 位,扩展后支持 256 个字符;
- 局限性:不支持汉字、其他国家文字。
(2)GB 系列(中文专用)
- GB2312:收录 6700 + 常用汉字,兼容 ASCII(英文字符 1 字节,汉字 2 字节),不支持生僻字和繁体字;
- GBK:GB2312 的扩展,收录 20000 + 汉字,兼容 GB2312,仍不支持少数民族文字;
- GB18030:最全面的汉字字符集,收录 70000 + 汉字,兼容 GB2312 和 GBK,支持少数民族文字、日韩汉字。
(3)BIG5
- 适用场景:繁体中文,收录 13000 + 汉字,是中国台湾、香港地区的常用字符集。
(4)Unicode & UTF-8
- Unicode:目标是包含世界上所有已知字符,解决不同字符集不兼容的问题,但未规定二进制存储规则;
- UTF-8:Unicode 的主流编码方式,可变长编码(1-4 字节),英文字符 1 字节(兼容 ASCII),汉字 3 字节,emoji 和复杂汉字 4 字节;
- 优势:空间效率高,是目前使用最广泛的字符编码。
MySQL 中的字符集
(1)支持的字符集
MySQL 支持 GB2312、GBK、BIG5、UTF-8 等多种字符集,核心关注utf8和utf8mb4(UTF-8 相关实现)。
(2)默认字符集
- MySQL5.7:默认字符集为
latin1(不支持中文); - MySQL8.0:默认字符集为
utf8mb4(完整 UTF-8 实现)。
(3)字符集层次级别(优先级递增)
- server(实例级):全局默认,可通过
--character-set-server启动参数设置; - database(库级):创建 / 修改数据库时指定,未指定则继承 server 级;
- table(表级):创建 / 修改表时指定,未指定则继承 database 级;
- column(字段级):定义字段时指定,未指定则继承 table 级,优先级最高。
(4)连接字符集
影响客户端与服务器的通信,核心关联 3 个变量:
character_set_client:客户端发送 SQL 的字符集;character_set_connection:服务器翻译 SQL 的字符集;character_set_results:服务器返回结果的字符集;- 修改方式:配置文件指定
default-character-set=utf8mb4,或执行set names utf8mb4SQL 语句。
(5)JDBC 的影响
JDBC 驱动通过characterEncoding、characterSetResults属性影响连接字符集。旧版本驱动(如 mysql-connector-java 8.0.25)可能将characterSetResults默认设为utf8,导致 emoji 显示为问号,需升级驱动并指定字符集为utf8mb4。
UTF-8 使用关键坑点(MySQL 专属)
(1)两套 UTF-8 实现的区别
| 编码方式 | 支持字节数 | 核心限制 | 适用场景 |
|---|---|---|---|
utf8 |
1-3 字节 | 无法存储 emoji、复杂汉字 / 繁体字 | 仅简单中文 + 英文场景 |
utf8mb4 |
1-4 字节 | 完整支持 UTF-8 字符(含 emoji) | 所有场景(推荐默认) |
(2)坑点原因
MySQL 的utf8是早期不完整实现(参考旧 UTF-8 草案),仅支持 3 字节字符;utf8mb4是 UTF-8 标准实现(RFC 3629),支持 4 字节字符,需显式指定才能存储 emoji 等特殊字符。
(3)避坑建议
创建数据库、表或字段时,字符集必须指定为utf8mb4,避免存储 emoji 或复杂汉字时报错(如Incorrect string value)。