【MySQL】与MongoDB的区别,字符集,三范式,存储引擎InnoDB、MyISAM
- 互联网
- 2025-09-11 00:15:01

MongoDB vs MySQL:区别与应用场景
1. 数据模型 MongoDB 非关系型(NoSQL),存储的是 JSON 格式 的 文档(Document)。数据结构灵活,不要求每个文档有相同的字段,适合存储 动态变化的数据。
例子: 存储用户信息(user 集合):
{ "name": "张三", "age": 25, "hobbies": ["篮球", "编程"], "address": { "city": "北京", "zip": "100000" } } 没有固定的表结构,可以随时增加新字段,如 hobbies 这个数组字段。MySQL 关系型数据库(RDBMS),数据存储在 表(Table) 里,数据结构固定。表结构必须事先定义,不能随意增加字段。
例子: 创建 users 表:
CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50), age INT, city VARCHAR(50), zip VARCHAR(10) );插入数据:
INSERT INTO users (name, age, city, zip) VALUES ("张三", 25, "北京", "100000"); 必须定义所有字段,如果后续想存 hobbies,就需要 修改表结构。提炼要点 MongoDBMySQL数据存储JSON 文档(BSON)表(行 + 列)结构无固定模式(Schema-less)结构固定(Schema-based)灵活性可以存储不同结构的数据需要事先定义表结构
2. 查询语言 MongoDB 不使用 SQL,查询基于 JavaScript 语法。无需 JOIN,数据通常以嵌套文档形式存储,避免多表查询的性能问题。
查询用户年龄大于 20 岁的文档:
db.users.find({ "age": { $gt: 20 } })MySQL 使用 SQL(Structured Query Language),标准化查询语言。支持复杂查询和多表 JOIN。
查询用户年龄大于 20 岁的数据:
SELECT * FROM users WHERE age > 20;提炼要点 MongoDBMySQL查询语言MongoDB 查询语法SQL多表查询依靠文档嵌套存储,减少 JOIN通过 JOIN 关联多个表查询灵活性适合非结构化数据适合结构化数据
3. 数据一致性与事务 MongoDB 默认是最终一致性(数据可能有短暂的不同步)。MongoDB 4.0+ 支持事务,但性能比 SQL 事务 稍逊。
示例:原子更新文档
db.users.updateOne({ "name": "张三" }, { $set: { "age": 26 } }) 仅更新匹配的文档,不影响其他数据。MySQL 提供强一致性,符合 ACID 原则(原子性、一致性、隔离性、持久性)。事务管理完善,支持 COMMIT 和 ROLLBACK。
示例:事务操作
START TRANSACTION; UPDATE users SET age = 26 WHERE name = "张三"; COMMIT; 如果操作失败,可 ROLLBACK 取消更改,保证数据一致性。提炼要点 MongoDBMySQL数据一致性默认最终一致性强一致性(ACID)事务支持4.0+ 版本支持多文档事务原生支持事务
4. 扩展性 MongoDB 水平扩展(Sharding):数据可以分布到 多个服务器 上,提高处理能力。适合大规模数据,比如 社交平台、大数据存储。
MySQL 主要依赖垂直扩展(提升单台服务器性能,如增加内存、CPU)。水平扩展较复杂,通常使用 分库分表、读写分离 来优化。
提炼要点 MongoDBMySQL扩展方式水平扩展(Sharding)垂直扩展(升级服务器)适用场景大规模数据存储传统业务应用
5. 适用场景 MongoDB 适用场景
✅ 动态数据存储(如社交平台、内容管理系统) ✅ 大数据存储与实时分析(日志、物联网数据) ✅ 快速开发(无需预定义表结构)
示例:社交媒体平台
用户帖子包含 文本、图片、视频、点赞、评论 等,格式复杂且变化快,MongoDB 更适合。MySQL 适用场景
✅ 高事务要求(如银行、支付系统) ✅ 数据结构固定(如企业 ERP、CRM 系统) ✅ 复杂查询与报表分析(多表 JOIN)
示例:银行系统
账户交易需要 强一致性 和 事务支持,MySQL 更适合。总结 MongoDBMySQL适合场景大数据、动态数据、实时分析事务、数据完整性要求高示例社交平台、日志存储银行、ERP、CRM
最终总结 维度MongoDBMySQL数据存储JSON 文档(BSON)表(行 + 列)查询语言Mongo 查询语法(基于 JavaScript)SQL事务支持4.0+ 支持事务,但不如 SQL 强支持 ACID 事务扩展性水平扩展(Sharding)垂直扩展(升级服务器)适合场景大数据、内容管理、社交平台事务处理、金融系统 选择建议 如果是 高并发、大数据、非结构化存储,✅ MongoDB 更合适。如果是 事务、数据一致性要求高,✅ MySQL 更合适。
1. 什么是字符集?
字符集(Character Set)决定了 数据库如何存储、读取和表示字符。如果字符集选择不当,可能会导致:
存储占用不合理(存储空间变大或变小)。数据查询性能下降(字符编码转换耗时)。数据乱码(字符存储和解析方式不一致)。2. 常见 MySQL 字符集 字符集每个字符最大占用字节特点GBK2适合中文,存储空间比 UTF-8 少,但不支持特殊符号和国际化。UTF-83国际通用字符集,支持多语言,适合中英文混合。latin11MySQL 早期默认字符集,仅支持英文。utf8mb44完全兼容 UTF-8,支持 Emoji 表情和特殊符号。
3. 字符集选择规则
✅ 外贸、国际业务(多语言) → utf8mb4(保证兼容性) ✅ 国内中文网站 → GBK(存储效率高) ✅ 纯英文数据 → latin1(存储空间最小,性能好)
4. 影响示例 (1)字符存储占用
存储 "你好":
GBK:2 × 2 = 4 字节UTF-8:3 × 2 = 6 字节utf8mb4:4 × 2 = 8 字节示例:创建 UTF-8 表
CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) CHARACTER SET utf8mb4 );(2)乱码问题
如果客户端和数据库字符集不同,可能会出现乱码:
SHOW VARIABLES LIKE 'character%';解决方法:
SET NAMES utf8mb4;MySQL 字符集的设置层级
在 MySQL 中,字符集可以在 不同层级 进行设置,分别是:
服务器级(Server)数据库级(Database)表级(Table)列级(Column)1. 作用范围 级别影响范围设置方式服务器级(Server)整个 MySQL 服务器my f 配置文件数据库级(Database)该数据库的所有表CREATE DATABASE表级(Table)该表的所有列CREATE TABLE列级(Column)仅影响该列VARCHAR(50) CHARACTER SET utf8mb4
2. 具体示例 (1)服务器级
默认字符集设置(修改 my f 配置文件):
[mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci作用:
影响新建的 数据库默认字符集,但不会修改已有数据库。服务器重启后生效。(2)数据库级 CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
作用:
影响新建的 表默认字符集,但不会修改已有表。仅影响 新建的表,不会影响已有表的数据存储格式。(3)表级 CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) ) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
作用:
该表的 所有列 默认使用 utf8mb4,但可以在列级别单独更改字符集。(4)列级 CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) CHARACTER SET gbk, -- 该列为 GBK email VARCHAR(100) CHARACTER SET utf8mb4 -- 该列为 UTF8MB4 );
作用:
该表的 name 字段用 GBK 存储,而 email 字段用 UTF8MB4 存储。3. 重要结论 优先级:列级 > 表级 > 数据库级 > 服务器级修改数据库字符集 仅影响 新建的表,不会更改已有表的数据存储。修改表或列的字符集 可能会 影响已有数据(可能会导致数据转换或乱码)。
4. 修改已有表的字符集
如果想修改已有数据的字符集:
ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4;注意: 这个操作会导致数据库重新编码,可能会有 数据损坏 或 查询性能下降,需要 谨慎测试 后再操作。
数据库三范式(举例+要点)
范式(Normal Form, NF) 是数据库设计的一套规则,目的是 减少数据冗余,提高数据一致性。 三范式(1NF、2NF、3NF)是数据库设计的基本要求,满足 越高范式 的数据库,数据重复率越低,但查询可能变复杂。
第一范式(1NF)—— 列的“原子性”
要求:
数据必须是“最小单元”,不能再拆分。表中每一列只能存储单一值,不能有 数组、列表、逗号分隔的多个值。✅ 符合 1NF(原子性数据):
ID姓名电话1张三138001380002李四13900139000❌ 不符合 1NF(多值存储):
ID姓名电话1张三13800138000, 139002390002李四13900139000❌ 问题: 电话 列含多个值,查询 13900139000 属于谁时,需要拆分字符串,影响查询效率。
✅ 解决办法: 如果一个人有多个手机号,就拆成多行或 创建新表:
ID姓名电话1张三138001380001张三13900239000第二范式(2NF)——“消除部分依赖”
要求:
必须先满足 1NF所有列必须完全依赖于主键,不能“部分依赖”适用于复合主键的情况(主键由多个列组成) 举例:❌ 不符合 2NF:
订单ID(主键)商品ID(主键)商品名称订单日期1001A1苹果2024-03-011001A2香蕉2024-03-01❌ 问题:
商品名称 只依赖于 商品ID,但和 订单ID 没关系,属于 “部分依赖”。如果同一个商品出现在多个订单中,商品名称就会重复,导致冗余!✅ 解决办法: 拆分为两张表:
订单表(去掉商品名称,只存 订单ID 和 订单日期)商品表(存 商品ID 和 商品名称)订单-商品关联表(订单ID + 商品ID 作为联合主键) 订单ID(主键)订单日期10012024-03-01 商品ID(主键)商品名称A1苹果A2香蕉 订单ID商品ID1001A11001A2✅ 这样,商品信息只存一份,避免冗余!
第三范式(3NF)——“消除传递依赖”
要求:
必须先满足 2NF非主键列不能依赖于其他非主键列即:所有非主属性只能依赖主键,不能依赖其他字段。 举例❌ 不符合 3NF:
学号(主键)姓名院系院系地址1001张三计算机系A栋2011002李四计算机系A栋201❌ 问题:
院系地址 依赖于 院系,但和 学号 没直接关系,属于 “传递依赖”。如果计算机系的地址变了,需要修改所有该系的学生数据,容易出错!✅ 解决办法: 拆分表,建立 院系表:
学号(主键)姓名院系1001张三计算机系1002李四计算机系 院系(主键)院系地址计算机系A栋201这样,如果院系地址变了,只需要修改 院系表,避免数据不一致。
最终总结 范式要求解决的问题1NF列是原子值,不能存多个值不能在一列存多个数据,避免拆分字符串查询2NF列必须完全依赖于主键不能部分依赖,避免数据冗余3NF不能有“传递依赖”非主键列只能依赖主键,避免数据重复
满足三范式后,数据库更规范,数据更一致,但查询可能变复杂。 在实际项目中,会在范式和性能之间折中,适当 反范式(Denormalization) 以提升查询速度。
InnoDB 与 MyISAM 区别
MySQL 提供了多种 存储引擎,最常见的就是 InnoDB 和 MyISAM。它们的主要区别体现在 事务支持、锁机制、性能、缓存机制等 方面。
1. 事务支持
事务(Transaction) 是 一组操作的集合,要么全部执行,要么全部不执行,保证数据一致性(ACID)。 ✅ InnoDB 支持事务,可以 ROLLBACK(回滚)数据。 ❌ MyISAM 不支持事务,一旦执行 INSERT、UPDATE、DELETE,就无法撤销。
📌 举例:
-- InnoDB 支持事务 START TRANSACTION; UPDATE accounts SET balance = balance - 500 WHERE id = 1; UPDATE accounts SET balance = balance + 500 WHERE id = 2; COMMIT; -- 事务提交如果其中一个 UPDATE 失败:
ROLLBACK; -- 撤销所有修改🔹 如果是 MyISAM,即使 UPDATE 失败,也无法回滚,导致数据可能出错。
2. 锁机制
✅ InnoDB 使用 行锁(Row Lock),即只锁住操作的那一行数据,并发性能高。 ❌ MyISAM 使用 表锁(Table Lock),即使修改一行,也会锁住整个表,并发性能较低。
📌 举例:
-- InnoDB(行锁):多个线程可以同时操作不同的行 UPDATE users SET name = 'Alice' WHERE id = 1; -- MyISAM(表锁):一个操作会锁住整个表,其他线程必须等待 UPDATE users SET name = 'Bob' WHERE id = 2;🔹 高并发场景(如支付、订单系统)用 InnoDB 更合适。
3. MVCC(多版本并发控制)
✅ InnoDB 支持 MVCC,能在不加锁的情况下进行并发读写,提升性能。 ❌ MyISAM 不支持 MVCC,每次查询都要等待表解锁。
📌 举例: 在 InnoDB 里,一个事务可以读到自己开始时的数据,而不受其他事务影响:
-- 事务 A 读取数据 SELECT balance FROM accounts WHERE id = 1; -- 事务 B 修改数据 UPDATE accounts SET balance = balance - 500 WHERE id = 1; -- 事务 A 仍然可以看到未修改前的旧数据 SELECT balance FROM accounts WHERE id = 1;🔹 适用于高并发读取的场景,如社交平台的帖子浏览。
4. 外键支持
✅ InnoDB 支持外键,可以保证数据一致性。 ❌ MyISAM 不支持外键,只能通过应用程序保证数据完整性。
📌 举例:
-- InnoDB:定义外键 CREATE TABLE orders ( id INT PRIMARY KEY, user_id INT, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE );🔹 如果删除 users 表中的用户,orders 里对应的订单也会自动删除(级联删除)。 🔹 MyISAM 不支持这种外键约束,可能导致数据不一致。
5. 索引
✅ InnoDB 使用 聚簇索引(Clustered Index),主键索引和数据存储在一起,查询主键时性能高。 ❌ MyISAM 使用 非聚簇索引(Non-Clustered Index),索引和数据分开存储,查询主键时需要两次访问磁盘。
📌 举例:
-- InnoDB(聚簇索引) SELECT * FROM users WHERE id = 1;🔹 InnoDB 的主键索引直接定位到数据,查询快。 🔹 MyISAM 先通过索引找到数据位置,再去查询数据,查询慢。
6. 读写性能
✅ MyISAM 适合读多写少的场景(如日志、文章存储)。 ✅ InnoDB 适合读写均衡、高并发、事务性强的应用(如支付、订单、银行系统)。
场景适合引擎论坛、日志、统计MyISAM交易、支付、订单InnoDB高并发网站InnoDB7. 其他区别 特点InnoDB ✅MyISAM ❌事务支持不支持外键支持不支持锁机制行锁表锁MVCC支持不支持索引存储聚簇索引非聚簇索引全文索引MySQL 5.6+ 支持支持崩溃恢复支持不支持数据存储不保存行数保存行数读写场景读写均衡读多写少
总结 InnoDB 适合 高并发、事务场景(如订单、支付)。MyISAM 适合 查询多、写入少的场景(如日志、统计)。实际应用中,一般推荐使用 InnoDB,除非有特殊需求(如超大规模的只读数据)。
github /0voice
【MySQL】与MongoDB的区别,字符集,三范式,存储引擎InnoDB、MyISAM由讯客互联互联网栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【MySQL】与MongoDB的区别,字符集,三范式,存储引擎InnoDB、MyISAM”
上一篇
MongoDB高级索引