MySQL 数据表与索引设计艺术:打造高效数据存取架构

🐇明明跟你说过:个人主页

🏅个人专栏:《MySQL技术精粹》🏅

🔖行路有良友,便是天堂🔖

目录

一、引言

1、什么是MySQL

2、MySQL适用场景

二、MySQL的数据存储与检索

1、数据表设计

[1.1 什么是数据表](#1.1 什么是数据表)

[1.2 如何设计数据表](#1.2 如何设计数据表)

2、索引设计

[2.1 什么是索引](#2.1 什么是索引)

[2.2 为什么需要索引](#2.2 为什么需要索引)

[2.3 索引的基本类型](#2.3 索引的基本类型)

[3.4 如何选择合适的索引](#3.4 如何选择合适的索引)

3、数据类型

[3.1 数值类型](#3.1 数值类型)

[3.2 字符串类型](#3.2 字符串类型)

[3.3 日期和时间类型](#3.3 日期和时间类型)

4、存储格式

[4.1 存储引擎 (Storage Engines)](#4.1 存储引擎 (Storage Engines))

[4.2 表的存储格式](#4.2 表的存储格式)

[4.3 MySQL 数据存储的物理结构](#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);

这种索引只会加速基于单个字段的查询。

复合索引(多列索引)

复合索引是由多个字段组成的索引。当你经常用多个字段一起进行查询时,可以为这些字段创建复合索引。比如,如果你经常根据 usernameemail两个字段同时查询用户信息,可以创建复合索引。

CREATE INDEX idx_username_email ON users(username, email);

复合索引的顺序非常重要。它会根据索引字段的顺序来优化查询。如果你经常查询 usernameemail, 那么这个复合索引会非常有效。但如果查询条件只包含 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: 范围为 -128127 (有符号)或 0255(无符号)。用于存储非常小的整数。
  • SMALLINT: 范围为 -32,76832,767 (有符号)或 065,535(无符号)。
  • MEDIUMINT: 范围为 -8,388,6088,388,607 (有符号)或 016,777,215(无符号)。
  • INT(或 INTEGER): 范围为**-2,147,483,648** 到 2,147,483,647 (有符号)或 04,294,967,295(无符号)。这是最常用的整数类型。
  • BIGINT: 范围为 -9,223,372,036,854,775,8089,223,372,036,854,775,807 (有符号)或018,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 使用表空间来存储数据和索引。表空间有两种类型:
  1. 共享表空间: 所有的 InnoDB 表都存储在同一个表空间文件中(通常是ibdata1)。这使得多个表的数据存储在一个文件中,增加了管理的复杂性,但也提供了更高的空间利用率。
  2. 独立表空间: 每个表都使用一个独立的文件存储(.ibd文件),适用于需要管理单独表的情况。
  • **数据页:**InnoDB 使用固定大小的数据页(通常是 16KB)来存储表的数据和索引。每个页由多个行组成,每个页通过 B+ 树索引链接。

MyISAM 存储格式

  • **数据文件(.MYD 文件):**存储表的实际数据。
  • **索引文件(.MYI 文件):**存储表的索引信息。
  • **存储结构:**MyISAM 使用一个非聚集索引结构,每个数据表的记录和索引是分开存储的。每个 MyISAM 表的索引和数据都是独立的文件。

MEMORY 存储格式

  • **内存存储:**MEMORY 引擎将所有的数据存储在内存中。数据表在内存中存储,表的数据会保存在操作系统的内存中,而不是写入磁盘。
  • **临时数据:**当 MySQL 重启时,内存中的数据将丢失,适合用于存储临时的数据。

💕💕💕每一次的分享都是一次成长的旅程,感谢您的陪伴和关注。希望这些关于MySQL的文章能陪伴您走过技术的一段旅程,共同见证成长和进步!😺😺😺

🧨🧨🧨让我们一起在技术的海洋中探索前行,共同书写美好的未来!!!

相关推荐
余衫马4 小时前
CentOS7 离线安装 Postgresql 指南
数据库·postgresql
E___V___E5 小时前
MySQL数据库入门到大蛇尚硅谷宋红康老师笔记 高级篇 part 2
数据库·笔记·mysql
m0_748254885 小时前
mysql之如何获知版本
数据库·mysql
小金的学习笔记5 小时前
如何在本地和服务器新建mysql用户和密码
运维·服务器·mysql
mikey棒棒棒6 小时前
Redis——优惠券秒杀问题(分布式id、一人多单超卖、乐悲锁、CAS、分布式锁、Redisson)
数据库·redis·lua·redisson·watchdog·cas·并发锁
星星点点洲6 小时前
【操作幂等和数据一致性】保障业务在MySQL和COS对象存储的一致
java·mysql
水手胡巴7 小时前
oracle apex post接口
数据库·oracle
_院长大人_7 小时前
Docker Mysql 数据迁移
mysql·adb·docker
史迪仔01129 小时前
【SQL】SQL多表查询
数据库·sql
Quz9 小时前
MySQL:修改数据库默认存储目录与数据迁移
数据库·mysql