系列文章目录
《【MySQL】第一章 MySQL 5.7的安装与卸载》
《【MySQL】第二章 初识数据库》
文章目录
什么是数据库
整体角度:数据库是系统
当我们登录 MySQL 后,再新打开一个终端可以使用 ps
命令查看 MySQL 相关运行进程:
bash
LJH@iZ7xvhuhaslv4h5dm1d1svZ:~$ ps axj | grep mysql
1 76840 76839 76839 ? -1 Sl 114 0:17 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
79334 79344 79344 79334 pts/1 79344 S+ 1000 0:00 mysql -uroot -px xx
79227 79349 79348 79227 pts/0 79348 S+ 1000 0:00 grep --color=auto mysql
从输出结果中,我们不仅看到了 mysql 进程,还看到了 mysqld 进程。
MySQL 不是一个单一软件吗,为什么会有两个?
我们常把 "MySQL 数据库"称为"MySQL",并且启动时使用的是程序也是 mysql
,所以我们可能下意识地认为"MySQL = mysql"。实际上,这种认知是不正确的。
从宏观的整体角度来看,MySQL 或者说 数据库是一套专注于解决数据的高效存储、检索和管理问题的系统。
以 MySQL 为例,数据库系统通常包含以下核心部分:
- 客户端程序(Client)
客户端是用户与数据库交互的工具。在 MySQL 中,客户端程序mysql
就是一个典型代表。用户通过它向数据库服务端发送 SQL 语句,从而完成对数据的操作,如查询、插入和删除等。 - 服务端程序(Server)
服务端程序是数据库的核心,负责实际的数据管理任务。在 MySQL 中,服务端程序mysqld
作为守护进程运行,负责处理客户端请求、执行 SQL 语句、维护数据的一致性和安全性等。 - 数据库文件(Files)
数据最终以文件的形式存储在硬盘上。MySQL 的服务端将用户的数据组织成特定格式的文件(如.ibd
文件、事务日志文件等),以便高效地存取和管理。
结论:数据库是一个协作系统,客户端和服务端共同完成数据的交互,而数据库文件则作为数据的持久化载体。
数据库客户端和数据库服务端有可能会跨主机进行网络通信,所以有时候我们也会把数据库系统称为网络服务。
局部角度:数据库是文件
数据库文件在 MySQL 的作用
- 数据存储 :数据表中的每一行、每一列的值最终都会被写入特定的存储文件。MySQL 使用 InnoDB 存储引擎时,这些数据会存储在
.ibd
文件中。 - 索引优化:数据库文件不仅存储数据,还包含索引信息。索引被设计为高效的结构(如 B+ 树),以便加速查询操作。
- 事务日志 :MySQL 的事务管理依赖于日志文件(如
ib_logfile
),它记录了对数据的每次修改,以确保系统在崩溃时可以恢复数据。
从微观的局部视角来看,数据库的核心本质就是文件。数据库就是一套经过特定优化的文件集合,这些文件构成了数据存储的基础。
常见客户端登录选项
选项 | 含义 |
---|---|
-u 或 --user | 指定要登录的用户名,例如-u root |
-p 或 --password | 用于提示输入密码。如果后面直接跟着密码,会在命令行中显示,但通常推荐不直接使用,以保护安全,例如-p123123 |
-h 或 --host | 指定要连接的 MySQL 服务器的主机名或 IP 地址,例如-h 127.0.0.1 |
-P 或 --port | 指定 MySQL 服务器的端口号,默认是 3306 |
--protocol | 指定连接协议,可以是 TCP 、UNIX 或 MEMORY ,默认为TCP |
--default-character-set | 设置客户端的默认字符集,例如 --default-character-set** **utf8 或 --default-character-set utf8mb4 |
-D 或 --database | 在登录时指定要使用的数据库,例如-D DatabaseName |
--ssl-mode | 指定 SSL 连接的模式,例如DISABLED (禁用)、PREFERRED (首选)等 |
举例:
sql
mysql -u root -p123123 -h 192.168.1.100 -P 3306 --protocol=TCP --default-character-set=utf8 --database=my_database
见一见数据库
目标:
- 建立一个数据库 -- 查数据库、建库的 SQL 语句
- 建立一张表结构 -- 查表、建表的 SQL 语句
- 插入一些数据 -- 插入、查询的 SQL 语句
- 观察一下以上操作在 Linux 文件中如何表现以加深对于 MySQL 数据库的了解
准备
启动终端1,这个终端用于 SQL 语句的执行。
在终端1的 Bash 输入 mysql -uroot -p
并输入密码登录 MySQL 客户端。
我们能看到命令行提示符由 LJH@iZ7xvhuhaslv4h5dm1d1svZ:~$
变成了 mysql>
。
在 mysql>
提示符下我们输入的命令叫做 SQL 指令或者 SQL 语句。
sql
LJH@iZ7xvhuhaslv4h5dm1d1svZ:~$ mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.42 MySQL Community Server (GPL)
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
然后在终端1输入 show databases;
能够查看到当前数据库下已经存在的所有数据库。
(注意:SQL 语句一定要以 ;
结束,否则不被视为一句完整的 SQL 语句)
sql
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| gomoku |
| learning |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)
启动终端2,这个终端用于观察数据库在 Linux 中的存在形式。
MySQL 相关的配置文件一般放在 /etc/mysql
目录下,但是由于发行版不同配置文件的结构稍有不同。
在 Ubuntu-20.04 中,MySQL 服务端相关的配置文件是 /etc/mysql/mysql.conf.d/mysqld.cnf
,在这个配置文件中有这么一项 datadir = /var/lib/mysql
,这是 MySQL 网络服务的数据库文件的存放目录,也就是我们使用show databases;
语句查到的数据库的存放目录,这个目录就是我们接下来的观察对象。
普通用户使用cd
命令无法直接进入/var/lib/mysql
,只有超级用户才有权限,因此,在终端2的Bash输入su -
并输入密码切换成超级用户,然后进入/var/lib/mysql
目录,输入ls
命令查看。
对比show databases;
语句的结果和ls /var/lib/mysql
命令的结果我们就可以发现,MySQL中的数据库在Linux文件系统中以目录的形式存在。
建库
切换回终端1,准备开始新建一个数据库。
输入create database helloworld;
创建一个名字为helloworld
的新数据库。
再输入show databases;
能够看到新创建好的helloworld
数据库出现在结果列表上。
sql
mysql> create database helloworld;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| gomoku |
| helloworld |
| learning |
| mysql |
| performance_schema |
| sys |
+--------------------+
7 rows in set (0.00 sec)
切换回终端2 ,在/var/lib/mysql
目录下输入ls
能够看到多了一个叫做helloworld
的目录,由此可以证明在MySQL中建立数据库的本质就是在Linux下新建一个目录。
反向证明:
先在
/var/lib/mysql
目录下创建一个叫做newdir
的目录,然后在MySQL客户端中能够找到一个叫做newdir
的数据库就能反向说明数据库是一个目录。事实就是反向证明是正确的。
建表
切换回终端1,准备开始新建一张表结构的相关操作。
建表之前还需要进行选择数据库(切换数据库)的操作,举个通俗的例子解释这个操作的意义,在终端1登录MySQL客户端就像我们在终端2进入/var/lib/mysql
目录,MySQL规定,表结构是在数据库中建立的,因此我们就得选择一个目录并进入,体现在MySQL客户端上就是输入use 数据库名;
这么一句SQL语句。
由于接下来打算在helloworld
目录中新建数据库,所以输入SQL语句use helloworld;
。
复制以下SQL语句粘贴到MySQL客户端中(如果没有输出就再按一下回车)
sql
create table student(
name varchar(32),
age int,
gender varchar(32)
);
执行正确能看到这样的输出
sql
mysql> create table student(
-> name varchar(32),
-> age int,
-> gender varchar(32)
-> );
Query OK, 0 rows affected (0.02 sec)
切换回终端2,观察 **/var/lib/mysql**
目录下的变化。
建表之前,在helloworld
目录只能看到一个叫做db.opt
的文件,获取该文件内容可推断出该文件应该为helloworld
数据库的配置文件。
建表之后,再次查看能够发现helloworld
目录下多了student.frm
和student.ibd
这两个文件
这两个文件具体什么作用现在没法讲,但是能够确定的是,在MySQL中的某个数据库里建立表结构的操作实际上就是在这个数据库对应的Linux目录下建立一批特定结构的文件。
插入数据
切换回终端1,准备对 **helloworld**
数据库中的 **student**
表进行数据的插入。
以下是输入向表插入数据的SQL语句以及查询的SQL语句的执行结果。
sql
# 插入第一条数据
mysql> insert into student (name, age, gender) values ('张三', 18, '男');
Query OK, 1 row affected (0.00 sec)
# 插入第二条数据
mysql> insert into student (name, age, gender) values ('李四', 20, '女');
Query OK, 1 row affected (0.00 sec)
# 查询插入的结果
mysql> select * from student;
+--------+------+--------+
| name | age | gender |
+--------+------+--------+
| 张三 | 18 | 男 |
| 李四 | 20 | 女 |
+--------+------+--------+
2 rows in set (0.00 sec)
切换回终端2,获取两个文件的内容,但是由于cat工具默认是按照文本的方式的读取,与表结构文件有冲突,因此出现乱码,但是依旧能够看到"李四女"这样的字眼,说明在MySQL中向表插入数据就是向表对应的文件中添加内容。
sql
root@iZ7xvhuhaslv4h5dm1d1svZ:/var/lib/mysql/helloworld# ll
total 120
drwxr-x--- 2 mysql mysql 4096 Oct 29 14:12 ./
drwxr-x--- 9 mysql mysql 4096 Oct 29 13:51 ../
-rw-r----- 1 mysql mysql 61 Oct 29 13:44 db.opt
-rw-r----- 1 mysql mysql 8622 Oct 29 14:12 student.frm
-rw-r----- 1 mysql mysql 98304 Oct 29 16:02 student.ibd
root@iZ7xvhuhaslv4h5dm1d1svZ:/var/lib/mysql/helloworld# cat student.ibd
./''@!ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ&&ÿÿÿÿÿÿÿÿªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ./lОµ-/<<'Оµ-/<<-<l'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿթЃÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿթӿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ-<lÿÿÿÿÿÿÿÿ-A½E¿'Ȁ¨A'𥀲infimum
supremum(
§ÿƂ
¨李四女pcA½root@iZ7xvhuhaslv4h5dm1d1svZ:/var/lib/mysql/helloworld# XshellXshellXshell
XshellXshellXshell: command not found
root@iZ7xvhuhaslv4h5dm1d1svZ:/var/lib/mysql/helloworld# cat student.frm
þ
0ł !6Ġ// ÿÿInnoDB
®İPI) nameagegenderJ`!
c`g!ÿnameÿageÿgenderÿroot@iZ7xvhuhaslv4h5dm1d1svZ:/var/lib/mysql/helloworld# XshellXshellXshellXshellXshell
XshellXshellXshellXshellXshell: command not found
总结
在对MySQL数据库的建库、建表和插入数据等操作有了一定认知后,我们可以进一步探讨一个问题:为什么数据库能为程序员提供高效的数据存储、检索和查询能力?
首先,我们需要思考一个问题:建库、建表和插入数据这些操作是由谁来完成的?答案是数据库服务。虽然数据库文件具有特殊的结构,但本质上它们仍然是文件。如果没有数据库服务,程序员就必须自己编写代码来遍历和读取文件内容。
然而,许多专家已经为我们开发了一整套服务。作为使用者,我们可以将需求转化为SQL语句,并通过数据库客户端提交这些语句。数据库客户端会将SQL语句传递给数据库服务,由数据库服务负责执行文件的读写操作。至于数据是如何管理的,我们无需关心,这完全由数据库服务自行处理。这就是为什么使用数据库能为程序员提供高效的数据存储、检索和查询能力的原因。
主流数据库
关系型数据库
数据库 | 特点 |
---|---|
SQL Server | 微软开发,适合中大型项目,尤其受.NET程序员欢迎。 |
Oracle | 甲骨文公司开发,适合大型项目和复杂的业务逻辑,但在并发性能上一般不如MySQL。 |
MySQL | 甲骨文公司开发,世界上最受欢迎的数据库,适合电商、SNS和论坛,处理简单SQL效果好。 |
PostgreSQL | 加州大学伯克利分校开发,支持私用、商用和学术研究,免费使用、修改和分发。 |
SQLite | N/A。轻量级ACID关系型数据库,适合嵌入式设备,资源占用极低。 |
H2 | N/A,用Java开发的嵌入式数据库,可以直接嵌入到应用项目中。 |
非关系型数据库
数据库 | 特点 |
---|---|
MongoDB | 文档数据库,灵活的模式,适合处理大规模数据,支持水平扩展。 |
Cassandra | 分布式列存储,适合高写入负载和高可用性,支持多数据中心部署。 |
Redis | 内存键值存储,速度极快,支持丰富的数据结构,常用于缓存和实时分析。 |
Couchbase | 文档存储,结合了键值和文档数据库的特点,支持强一致性和灵活查询。 |
Neo4j | 图数据库,适合处理复杂关系的数据,提供高效的图查询语言。 |
DynamoDB | 亚马逊提供的完全托管的键值和文档数据库,具备高可用性和可扩展性。 |
服务器、数据库、表的关系
- 所谓安装数据库服务器,只是在机器上安装了一个数据库管理系统程序,这个管理程序可以管理多个数据库,一般开发人员会针对每一个应用创建一个数据库。
- 为保存应用中实体的数据,一般会在数据库中创建多个表,以保存程序中实体的数据。
- 数据库服务器、数据库和表的关系如下:
MySQL架构
这部分的关键在于理解mysqld
的构成。
MySQL 是一个可移植的数据库,几乎能在当前所有的操作系统上运行,如 Unix/Linux、Windows、Mac 和 Solaris。各种系统在底层实现方面各有不同,但是 MySQL 基本上能保证在各个平台上的物理体系结构的一致性。
SQL语句的分类
SQL语句通常可以划分为以下五类:
- 数据定义语言(DDL, Data Definition Language) :
- 用于定义和修改数据库结构,如创建、修改和删除表及其他数据库对象。
- 代表性语句:
CREATE
、ALTER
、DROP
。 - 示例:
CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(50), age INT);
(创建表)ALTER TABLE users ADD email VARCHAR(100);
(修改表结构)DROP TABLE users;
(删除表)
- 数据操作语言(DML, Data Manipulation Language) :
- 用于对数据进行插入、更新和删除操作。
- 代表性语句:
INSERT
、UPDATE
、DELETE
。 - 示例:
INSERT INTO users (name, age) VALUES ('Alice', 30);
(插入数据)UPDATE users SET age = 31 WHERE name = 'Alice';
(更新数据)DELETE FROM users WHERE name = 'Alice';
(删除数据)
- 数据查询语言(DQL, Data Query Language) :
- DML下的一个分支。
- 主要用于从数据库中检索数据。
- 代表性语句:
SELECT
。 - 示例:
SELECT * FROM users;
(查询用户表中的所有数据)
- 数据控制语言(DCL, Data Control Language) :
- 用于控制对数据的访问权限和安全性。
- 代表性语句:
GRANT
、REVOKE
。 - 示例:
GRANT SELECT ON users TO user1;
(授予权限)REVOKE SELECT ON users FROM user1;
(撤销权限)
- 事务控制语言(TCL, Transaction Control Language) :
- 用于管理数据库事务,确保数据的一致性和完整性。
- 代表性语句:
COMMIT
、ROLLBACK
、SAVEPOINT
。 - 示例:
COMMIT;
(提交事务)ROLLBACK;
(回滚事务)SAVEPOINT savepoint_name;
(设置保存点)
查看MySQL存储引擎
存储引擎:数据库管理系统如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法。MySQL的核心就是插件式存储引擎,支持多种存储引擎。
举个比较浅显的例子,你可以把存储引擎看做成一个类,不同的存储引擎就是不同的类,每个类的内部都定制有属于自己的一套存储和管理数据的方案。
查看存储引擎的SQL语句
bash
show engines;
执行示例
bash
mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/NULL storage engine (anything you write to it disappears) | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
存储引擎的对比图