【MySQL】与MongoDB的区别,字符集,三范式,存储引擎InnoDB、MyISAM

devtools/2025/3/5 9:20:44/

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 原则(原子性、一致性、隔离性、持久性)。
  • 事务管理完善,支持 COMMITROLLBACK

示例:事务操作

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)字符存储占用

存储 "你好"

  • GBK2 × 2 = 4 字节
  • UTF-83 × 2 = 6 字节
  • utf8mb44 × 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 中,字符集可以在 不同层级 进行设置,分别是:

  1. 服务器级(Server)
  2. 数据库级(Database)
  3. 表级(Table)
  4. 列级(Column)

1. 作用范围

级别影响范围设置方式
服务器级(Server)整个 MySQL 服务器my.cnf 配置文件
数据库级(Database)数据库的所有表CREATE DATABASE
表级(Table)该表的所有列CREATE TABLE
列级(Column)仅影响该列VARCHAR(50) CHARACTER SET utf8mb4

2. 具体示例

(1)服务器级

默认字符集设置(修改 my.cnf 配置文件):

[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,  -- 该列为 GBKemail 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张三13800138000
2李四13900139000

不符合 1NF(多值存储):

ID姓名电话
1张三13800138000, 13900239000
2李四13900139000

❌ 问题: 电话 列含多个值,查询 13900139000 属于谁时,需要拆分字符串,影响查询效率。

✅ 解决办法:
如果一个人有多个手机号,就拆成多行创建新表

ID姓名电话
1张三13800138000
1张三13900239000

第二范式(2NF)——“消除部分依赖”

要求:

  • 必须先满足 1NF
  • 所有列必须完全依赖于主键,不能“部分依赖”
  • 适用于复合主键的情况(主键由多个列组成)

举例:

不符合 2NF:

订单ID(主键)商品ID(主键)商品名称订单日期
1001A1苹果2024-03-01
1001A2香蕉2024-03-01

❌ 问题:

  • 商品名称 只依赖于 商品ID,但和 订单ID 没关系,属于 “部分依赖”
  • 如果同一个商品出现在多个订单中,商品名称就会重复,导致冗余!

✅ 解决办法:
拆分为两张表:

  1. 订单表(去掉商品名称,只存 订单ID订单日期
  2. 商品表(存 商品ID商品名称
  3. 订单-商品关联表(订单ID + 商品ID 作为联合主键)
订单ID(主键)订单日期
10012024-03-01
商品ID(主键)商品名称
A1苹果
A2香蕉
订单ID商品ID
1001A1
1001A2

✅ 这样,商品信息只存一份,避免冗余!


第三范式(3NF)——“消除传递依赖”

要求:

  • 必须先满足 2NF
  • 非主键列不能依赖于其他非主键列
  • 即:所有非主属性只能依赖主键,不能依赖其他字段

举例

不符合 3NF:

学号(主键)姓名院系院系地址
1001张三计算机系A栋201
1002李四计算机系A栋201

❌ 问题:

  • 院系地址 依赖于 院系,但和 学号 没直接关系,属于 “传递依赖”
  • 如果计算机系的地址变了,需要修改所有该系的学生数据,容易出错!

✅ 解决办法:
拆分表,建立 院系表

学号(主键)姓名院系
1001张三计算机系
1002李四计算机系
院系(主键)院系地址
计算机系A栋201

这样,如果院系地址变了,只需要修改 院系表,避免数据不一致。


最终总结

范式要求解决的问题
1NF列是原子值,不能存多个值不能在一列存多个数据,避免拆分字符串查询
2NF列必须完全依赖于主键不能部分依赖,避免数据冗余
3NF不能有“传递依赖”非主键列只能依赖主键,避免数据重复

满足三范式后,数据库规范,数据更一致,但查询可能变复杂。
在实际项目中,会在范式和性能之间折中,适当 反范式(Denormalization) 以提升查询速度。


InnoDB 与 MyISAM 区别

MySQL 提供了多种 存储引擎,最常见的就是 InnoDB 和 MyISAM。它们的主要区别体现在 事务支持、锁机制、性能、缓存机制等 方面。


1. 事务支持

事务(Transaction)一组操作的集合,要么全部执行,要么全部不执行,保证数据一致性(ACID)。
InnoDB 支持事务,可以 ROLLBACK(回滚)数据。
MyISAM 不支持事务,一旦执行 INSERTUPDATEDELETE,就无法撤销。

📌 举例:

-- 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
高并发网站InnoDB

7. 其他区别

特点InnoDBMyISAM
事务支持不支持
外键支持不支持
锁机制行锁表锁
MVCC支持不支持
索引存储聚簇索引非聚簇索引
全文索引MySQL 5.6+ 支持支持
崩溃恢复支持不支持
数据存储不保存行数保存行数
读写场景读写均衡读多写少

总结

  • InnoDB 适合 高并发、事务场景(如订单、支付)。
  • MyISAM 适合 查询多、写入少的场景(如日志、统计)。
  • 实际应用中,一般推荐使用 InnoDB,除非有特殊需求(如超大规模的只读数据)。

https://github.com/0voice


http://www.ppmy.cn/devtools/164709.html

相关文章

【氮化镓】基于SiC脉冲I-V系统研究Schottky型p-GaN HEMT正栅极ESD机制

这篇文章题为《Investigating Forward Gate ESD Mechanism of Schottky-Type p-GaN Gate HEMTs Using a SiC-Based High-Speed Pulsed I-V Test System》,发表于《IEEE Electron Device Letters》2024年7月刊。研究重点是探讨肖特基型p-GaN门极高电子迁移率晶体管(HEMTs)在正…

【竞技宝】CS2-EPLS21:失之毫厘差之千里 TYLOO惜败

北京时间2025年3月4日,CS2的EPL第21赛季继续进行。昨日第二轮第二场比赛迎来2-0组TYLOO对阵GL。以下为本场比赛的详细战报。 图一荒漠迷城 GL 13-7 TYLOO 图一为TYLOO选图荒漠迷城,上半场TYLOO先做进攻方,手枪局,TYLOO采用拱门夹…

Stable Diffusion Prompt编写规范详解

Stable Diffusion Prompt编写规范详解 一、语法结构规范 (一)基础模板框架 [质量强化] [主体特征] [环境氛围] [风格控制] [镜头参数]质量强化:best quality, ultra detailed, 8k resolution‌主体特征:(1girl:1.3), long …

20241130 RocketMQ本机安装与SpringBoot整合

目录 一、RocketMQ简介 ???1.1、核心概念 ???1.2、应用场景 ???1.3、架构设计 2、RocketMQ Server安装 3、RocketMQ可视化控制台安装与使用 4、SpringBoot整合RocketMQ实现消息发送和接收? ? ? ? ? 4.1、添加maven依赖 ???4.2、yaml配置 ???4.3、…

迷你世界脚本道具接口:Item

道具接口:Item 彼得兔 更新时间: 2023-04-26 10:26:18 继承自 Actor 具体函数名及描述如下: 序号 函数名 函数描述 1 getItemName(...) 获取道具名称 2 getItemId(...) 获取actor对应的道具ID,如球类等 3 getDropItemNum(...) …

第十天-字符串:编程世界的文本基石

在编程的广阔领域中,字符串是极为重要的数据类型,它就像一座桥梁,连接着人类的自然语言和计算机能够理解与处理的数字信息。下面,让我们深入探索字符串的世界。 一、字符串简介 字符串是由零个或多个字符组成的有序序列&#xff…

希音(Shein)前端开发面试题集锦和参考答案

用 Node 写过什么工具或 npm 包 在实际开发中,使用 Node 编写过多种实用工具和 npm 包。 自动化构建工具 开发了一个简单的自动化构建工具,用于处理前端项目的资源压缩和合并。在前端项目中,为了优化性能,需要对 CSS 和 JavaScript 文件进行压缩,减少文件体积,同时将多个…

测试工程师的DeepSeek提效2:自动化测试应用

1.背景: 在当今快速迭代的软件开发环境中,测试工程师面临着日益复杂的测试任务和紧迫的时间压力。DeepSeek作为一种先进的AI工具,为测试工程师提供了强大的支持,帮助他们自动化测试、质量保障方面实现突破。本文将详细介绍DeepSeek在测试工程师日常工作中的应用技巧,并通…