🐇明明跟你说过:个人主页
🏅个人专栏:《MySQL技术精粹》🏅
🔖行路有良友,便是天堂🔖
目录
一、引言
1、什么是MySQL
2、MySQL适用场景
二、MySQL的数据存储与检索
1、数据表设计
1.1 什么是数据表
1.2 如何设计数据表
2、索引设计
2.1 什么是索引
2.2 为什么需要索引
2.3 索引的基本类型
3.4 如何选择合适的索引
3、数据类型
3.1 数值类型
3.2 字符串类型
3.3 日期和时间类型
4、存储格式
4.1 存储引擎 (Storage Engines)
4.2 表的存储格式
4.3 MySQL 数据存储的物理结构
一、引言
1、什么是MySQL
MySQL 是一个开源的关系型数据库管理系统(RDBMS),基于 SQL(结构化查询语言)来管理数据库中的数据。它是最流行的数据库管理系统之一,广泛应用于各类 Web 应用程序和软件系统中,尤其是在 LAMP(Linux、Apache、MySQL、PHP/Perl/Python)堆栈中扮演着核心角色。
2、MySQL适用场景
1. Web应用开发
MySQL 最常用于 Web 应用程序的后台数据库,尤其是在 LAMP(Linux、Apache、MySQL、PHP/Python/Perl)或 MERN(MongoDB、Express.js、React、Node.js)架构中,MySQL 作为数据库解决方案广泛应用于:
- 内容管理系统(CMS):如 WordPress、Drupal、Joomla 等,通常使用 MySQL 存储文章、用户、评论等数据。
- 电子商务平台:如 Magento、PrestaShop 和 OpenCart 等,MySQL 用于存储产品目录、订单数据、用户信息等。
- 社交媒体应用:MySQL 可以存储用户数据、朋友关系、帖子、评论等信息。
- 在线论坛与博客:如 Discourse、phpBB 等,MySQL 可以管理帖子、用户账户、评论等内容。
2. 内容管理与发布系统
MySQL 广泛用于内容管理系统(CMS),如 WordPress、Drupal 和 Joomla。它存储网站的内容(文章、图片、视频、评论、用户信息等)以及管理用户权限和访问控制的元数据。MySQL 在这些系统中的高效查询和可扩展性使其成为理想选择。
3. 电子商务系统
电子商务平台(如 Magento、WooCommerce、PrestaShop)依赖于 MySQL 来存储产品、订单、客户、支付、库存等信息。MySQL 支持高并发的查询和交易,确保订单处理的快速响应。它的事务处理特性确保了订单数据的一致性和完整性。
二、MySQL的数据存储与检索
1、数据表设计
1.1 什么是数据表
在 MySQL 中,数据表是用来存储数据的结构。可以将数据表想象成一个 Excel 表格,每一行代表一条记录,每一列代表一个数据字段(属性)。比如,一个存储用户信息的表,可能有字段:用户ID、用户名、电子邮箱、创建时间等。
1.2 如何设计数据表
设计数据表时,我们需要考虑以下几个重要方面:
字段(列)的选择
每个数据表都会有多个字段。字段是表中数据的属性,决定了你能存储什么样的数据。举个例子:
假设你要设计一个存储“用户信息”的数据表,可能会有以下字段:
- user_id:用户的唯一标识符(整数型)。
- username:用户名(字符串类型)。
- email:电子邮件地址(字符串类型)。
- created_at:账号创建时间(日期时间类型)。
每个字段都有对应的数据类型,比如 INT 表示整数,VARCHAR 表示可变长度的字符串,DATETIME 表示日期时间等。选择正确的数据类型可以节省存储空间,提升查询效率。
主键(Primary Key)
主键是数据表中唯一标识一行数据的字段,它的值不能重复,不能为空。每个数据表应该有一个主键。通常我们用“自增ID”作为主键,它会自动为每一条记录分配一个唯一的 ID。
比如,user_id 字段可以作为 users 表的主键。它保证了每个用户在表中都有一个唯一标识。
外键(Foreign Key)
外键是用来在两个数据表之间建立关联的字段。它是一个数据表中的字段,指向另一个数据表的主键。外键可以帮助保持数据一致性,确保关联的记录始终有效。
举个例子,如果有一个“订单”表和“用户”表,订单表中可能包含一个 user_id 字段,用来表示订单属于哪个用户。这个 user_id 字段就是外键,它指向“用户”表中的主键 user_id。
数据规范化(Normalization)
数据规范化是指通过合理地划分数据表来减少冗余数据,并确保数据一致性。常见的规范化范式有:
- 第一范式(1NF):保证每列的数据都是原子性的,即每个字段只能包含一个值。
- 第二范式(2NF):在满足 1NF 的基础上,保证每个非主键字段完全依赖于主键字段。
- 第三范式(3NF):在满足 2NF 的基础上,确保没有非主键字段依赖于其他非主键字段。
例如,假设你有一个包含用户信息的表,字段包括 user_id、username、email、city(用户城市)等。如果你将所有用户信息存储在一个表中,就可能出现冗余。例如,许多用户都在同一个城市,这样会导致城市名重复出现。为了减少冗余,可以将“城市”单独放到另一个表中,建立一个与用户表的关联。
2、索引设计
2.1 什么是索引
可以把索引理解为一本书的“目录”。当你想要找到书中的某一章或某一节内容时,你不需要从头到尾阅读每一页,而是可以直接查阅目录,快速定位到需要的地方。
在 MySQL 中,索引就是为了加速查询操作,帮助数据库更快速地找到需要的数据。没有索引,数据库就需要逐行扫描(全表扫描)来查找数据,这会非常慢。
2.2 为什么需要索引
数据库在存储大量数据时,查询效率可能会非常低。比如,有一个包含数百万行数据的表,如果每次查询都要扫描整个表,那就会非常浪费时间和资源。
通过为数据表创建索引,MySQL 可以通过查找索引来直接定位到相关记录,而不必扫描整个表。这样可以显著提升查询性能。
2.3 索引的基本类型
MySQL 支持几种常见的索引类型,每种类型有不同的使用场景。
单列索引
单列索引是最常见的一种索引类型,它为表中的一个字段创建索引。比如,如果你经常按 email 字段查询用户信息,可以为 email 字段创建单列索引。
CREATE INDEX idx_email ON users(email);
这种索引只会加速基于单个字段的查询。
复合索引(多列索引)
复合索引是由多个字段组成的索引。当你经常用多个字段一起进行查询时,可以为这些字段创建复合索引。比如,如果你经常根据 username 和 email 两个字段同时查询用户信息,可以创建复合索引。
CREATE INDEX idx_username_email ON users(username, email);
复合索引的顺序非常重要。它会根据索引字段的顺序来优化查询。如果你经常查询 username 和 email,那么这个复合索引会非常有效。但如果查询条件只包含 email,而没有 username,这个索引的效果就不好。
唯一索引
唯一索引保证了列中每个值的唯一性。一般来说,主键就是唯一索引。如果你想确保某个字段的值不能重复,可以使用唯一索引。
CREATE UNIQUE INDEX idx_unique_email ON users(email);
这样,email 字段就无法插入重复的值。
全文索引
全文索引(FULLTEXT)用于加速对文本数据的搜索,尤其是对于大文本字段(如文章、评论等)。它允许对文本中的单词进行快速搜索。全文索引适用于搜索操作,而不是精确匹配。
CREATE FULLTEXT INDEX idx_fulltext_content ON articles(content);
3.4 如何选择合适的索引
索引并不是越多越好,过多的索引会导致数据库在执行插入、删除和更新操作时变得更慢。所以,在设计索引时,需要根据查询的实际需求来选择合适的索引。
查询频繁的字段
- 为那些在查询中经常作为条件的字段创建索引。例如,如果你经常根据 email 来查找用户,就可以为 email 创建索引。
复合索引
- 如果查询经常使用多个字段的组合(比如 username 和 email),可以考虑创建复合索引,而不是为每个字段单独创建索引。
避免冗余索引
- 如果已经有复合索引包含了某个字段,就不需要为该字段单独创建索引了。否则,索引会变得冗余,影响性能。
3、数据类型
3.1 数值类型
数值类型用于存储整数和浮动小数点的数字。MySQL 提供了多种数值类型,主要分为整数类型、浮动小数点类型和定点数类型。
整数类型
整数类型用于存储没有小数部分的数字。常见的整数类型包括:
- TINYINT: 范围为 -128 到 127(有符号)或 0 到 255(无符号)。用于存储非常小的整数。
- SMALLINT: 范围为 -32,768 到 32,767(有符号)或 0 到 65,535(无符号)。
- MEDIUMINT: 范围为 -8,388,608 到 8,388,607(有符号)或 0 到 16,777,215(无符号)。
- INT(或 INTEGER): 范围为 -2,147,483,648 到 2,147,483,647(有符号)或 0 到 4,294,967,295(无符号)。这是最常用的整数类型。
- BIGINT: 范围为 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807(有符号)或 0 到 18,446,744,073,709,551,615(无符号)。用于存储非常大的整数。
浮动小数点类型
浮动小数点类型用于存储带有小数部分的数值。常见的浮动小数点类型有:
- FLOAT: 单精度浮点数。存储的数值精度较低,适合存储占用空间较小的数值。其精度为 7 位十进制数。
- DOUBLE: 双精度浮点数,精度更高,适合存储需要高精度的数值。其精度为 15 位十进制数。
- REAL: 实际上是 DOUBLE 类型的别名。
3.2 字符串类型
字符串类型用于存储各种文本数据,MySQL 提供了多种类型的字符串字段。
字符类型
- CHAR(M): 固定长度的字符串,M 表示字符的长度,最大可达 255 字符。即使插入的字符串长度小于 M,它也会用空格填充至指定的长度。
- VARCHAR(M): 可变长度的字符串,M 表示最大字符长度,最大值为 65,535 字符。VARCHAR 根据实际存储的字符长度来分配空间,不会浪费空间。
- TEXT: 用于存储大文本数据,最大长度为 65,535 字符。TEXT 类型用于存储超过 VARCHAR 能存储的字符串,通常用于存储长文本内容。
- TINYTEXT: 最大长度为 255 字符的文本。
- MEDIUMTEXT: 最大长度为 16,777,215 字符的文本。
- LONGTEXT: 最大长度为 4,294,967,295 字符的文本。
二进制数据类型
二进制数据类型用于存储原始二进制数据,如图像、文件等。
- BINARY(M): 固定长度的二进制数据,M 表示长度,最大可达 255 字节。
- VARBINARY(M): 可变长度的二进制数据,M 表示最大字节数,最大为 65,535 字节。
- BLOB: 用于存储大块二进制数据,最大为 65,535 字节。BLOB 与 TEXT 类似,但用于二进制数据。
- TINYBLOB: 最大为 255 字节的二进制数据。
- MEDIUMBLOB: 最大为 16,777,215 字节的二进制数据。
- LONGBLOB: 最大为 4,294,967,295 字节的二进制数据。
3.3 日期和时间类型
日期和时间类型用于存储日期和时间信息,MySQL 提供了多种类型来表示不同的日期和时间。
- DATE: 用于存储日期,格式为 YYYY-MM-DD,范围是 1000-01-01 到 9999-12-31。
- DATETIME: 用于存储日期和时间,格式为 YYYY-MM-DD HH:MM:SS,范围是 1000-01-01 00:00:00 到 9999-12-31 23:59:59。
- TIMESTAMP: 用于存储时间戳,表示从 1970-01-01 00:00:00 UTC 到当前时间的秒数。通常用于记录数据的创建或修改时间。范围是 1970-01-01 00:00:01 到 2038-01-19 03:14:07。
- TIME: 用于存储时间,格式为 HH:MM:SS,范围是 -838:59:59 到 838:59:59。
- YEAR: 用于存储年份,格式为 YYYY,范围是 1901 到 2155。
4、存储格式
4.1 存储引擎 (Storage Engines)
MySQL 支持多种存储引擎,每种引擎有不同的数据存储格式和特性。常见的存储引擎有:
InnoDB(默认存储引擎)
- 事务支持:InnoDB 是 MySQL 默认的存储引擎,支持事务、ACID(原子性、一致性、隔离性、持久性)特性。
- 行级锁定:InnoDB 支持行级锁定,提高并发性能。
- 数据存储格式:InnoDB 使用聚集索引(Clustered Index)来存储数据。数据表中的数据是按主键顺序存储的,因此主键的选择对性能有重要影响。
- 数据文件:InnoDB 数据存储在 ibdata 文件中(默认情况下),此外还有每个表的独立表空间文件(.ibd 文件)用于存储表和索引数据。
- 表的存储格式:每个 InnoDB 表都有自己的表空间文件。数据和索引存储在一个单独的文件中,这个文件包含了该表的所有信息。
MyISAM
- 不支持事务:MyISAM 不支持事务,不提供 ACID 保证,但由于其简单性和高效性,通常适用于读多写少的应用场景。
- 表级锁定:MyISAM 使用表级锁定,适用于并发性较低的情况,多个查询可以共享锁,但对写操作会造成阻塞。
- 数据存储格式:MyISAM 使用的是非聚集索引的存储格式。数据和索引分别存储在不同的文件中:数据存储在 .MYD 文件中,索引存储在 .MYI 文件中。
- 存储效率:MyISAM 通常比 InnoDB 存储效率高,但不适用于对事务和并发要求较高的场景。
MEMORY
- 内存存储:MEMORY 引擎将所有数据存储在内存中,因此它提供非常快速的读写操作。但因为数据存储在内存中,系统重启后数据将丢失。
- 数据存储格式:数据表存储在内存中,类似于临时表。数据文件实际上存在于 RAM 中,不会被写入磁盘。
- 适用场景:适用于存储临时数据或需要高速读写的操作,比如缓存。
CSV
- 以逗号分隔的文件:CSV 存储引擎将每个表的数据存储为一个以逗号分隔值的文本文件,每行代表一条记录。
- 适用场景:适用于需要将数据导入或导出为 CSV 格式的应用场景。它不适用于高效查询,因为缺乏索引。
ARCHIVE
- 压缩存储:ARCHIVE 引擎用于存储大量历史数据,可以压缩数据以节省空间。数据只能追加,不能进行更新或删除。
- 适用场景:适合用于存储日志或归档数据,不适合频繁更新的表。
NDB(Clustered)
- 高可用性和分布式存储:NDB 是 MySQL 集群的存储引擎,适用于分布式数据库架构,支持多节点的高可用性和高扩展性。
- 数据存储格式:NDB 数据存储在集群的不同节点中,表和索引被分布在集群中。
4.2 表的存储格式
MySQL 中的数据表存储格式,取决于所使用的存储引擎。常见的存储格式有两种:聚集索引存储格式和非聚集索引存储格式。
聚集索引存储格式(InnoDB)
- 在 InnoDB 存储引擎中,数据表默认使用聚集索引(Clustered Index)存储。
- 聚集索引是将数据行按照主键值排序并存储在数据文件中。每个数据表的实际数据行就是主键索引的叶子节点。
- 如果没有主键,InnoDB 会选择一个唯一索引作为聚集索引;如果表没有唯一索引,InnoDB 会隐式创建一个 6 字节的主键作为聚集索引。
- 优势:通过聚集索引存储数据,查询效率高,尤其是基于主键或索引的查询。
- 劣势:对于大量更新或删除操作,聚集索引会导致数据的物理存储块的频繁调整,可能会影响性能。
非聚集索引存储格式(MyISAM)
- 在 MyISAM 存储引擎中,数据表使用非聚集索引(Non-clustered Index)存储。
- 数据表的记录和索引是独立存储的。索引存储在一个单独的文件(.MYI),数据存储在另一个文件(.MYD)中。
- 在查询时,首先通过索引查找记录的地址,然后再根据地址去读取对应的记录。
- 优势:对只读查询性能较好,存储和删除操作简单,索引文件和数据文件分开。
- 劣势:查询时需要多次磁盘访问,效率相对较低。
4.3 MySQL 数据存储的物理结构
MySQL 在磁盘上存储数据时,使用不同的存储引擎和存储格式,每种存储引擎有不同的文件存储结构。
InnoDB 存储格式
- 表空间:InnoDB 使用表空间来存储数据和索引。表空间有两种类型:
- 共享表空间:所有的 InnoDB 表都存储在同一个表空间文件中(通常是 ibdata1)。这使得多个表的数据存储在一个文件中,增加了管理的复杂性,但也提供了更高的空间利用率。
- 独立表空间:每个表都使用一个独立的文件存储(.ibd 文件),适用于需要管理单独表的情况。
- 数据页:InnoDB 使用固定大小的数据页(通常是 16KB)来存储表的数据和索引。每个页由多个行组成,每个页通过 B+ 树索引链接。
MyISAM 存储格式
- 数据文件(.MYD 文件):存储表的实际数据。
- 索引文件(.MYI 文件):存储表的索引信息。
- 存储结构:MyISAM 使用一个非聚集索引结构,每个数据表的记录和索引是分开存储的。每个 MyISAM 表的索引和数据都是独立的文件。
MEMORY 存储格式
- 内存存储:MEMORY 引擎将所有的数据存储在内存中。数据表在内存中存储,表的数据会保存在操作系统的内存中,而不是写入磁盘。
- 临时数据:当 MySQL 重启时,内存中的数据将丢失,适合用于存储临时的数据。
💕💕💕每一次的分享都是一次成长的旅程,感谢您的陪伴和关注。希望这些关于MySQL的文章能陪伴您走过技术的一段旅程,共同见证成长和进步!😺😺😺
🧨🧨🧨让我们一起在技术的海洋中探索前行,共同书写美好的未来!!!