数据库是存储数据的仓库,由表的集合组成,通过数据库管理系统进行管理。数据以记录形式按统一格式存储,表用来存储不同的记录。MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,后被 Oracle 旗下收购。它具有开源、免费、体积小等特点,在 WEB 应用方面广泛使用,是最好的关系型数据库管理系统应用软件之一。MySQL 在 1995 年诞生,最初版本只是基础的 SQL 引擎,后不断发展增加功能。其标志小海豚 sakila 由用户命名,来自非洲斯威士兰的方言小镇名。
在不同操作系统下安装 MySQL 步骤不同。
Windows 平台:下载 MySQL Installer,选择安装类型如 “开发者默认”,安装 MySQL 服务器,配置服务器时可设置认证方式和根用户密码等,最后启动服务完成安装。
Linux 平台:基于 Debian 的系统如 Ubuntu 可使用sudo apt update和sudo apt install mysql-server安装;基于 RPM 的系统如 CentOS 或 Fedora 可使用sudo yum install mysql-server安装,安装后启动服务sudo systemctl start mysqld并进行安全配置sudo mysql_secure_installation。
macOS 平台:通过 Homebrew 安装,命令为brew update和brew install mysql,安装后启动服务brew services start mysql并进行安全配置。
数据库创建与管理:使用CREATE DATABASE 数据库名创建数据库,SHOW DATABASES查看数据库,DROP DATABASE 数据库名删除数据库。
表的创建:使用CREATE TABLE 表名(字段名数据类型)创建表,DESCRIBE 表名查看表结构,DROP TABLE 表名删除表。
数据操作:
插入数据:INSERT INTO 表名(字段名) VALUES(值)或INSERT INTO 表名 VALUES(值)。
查询数据:SELECT * FROM 表名查询所有数据,可指定条件查询如SELECT 字段名 FROM 表名 WHERE 条件。
更新数据:UPDATE 表名 SET 字段名=新值 WHERE 条件。
删除数据:DELETE FROM 表名 WHERE 条件或TRUNCATE TABLE 表名删除所有数据。
SQL 通用语法包括 SQL 语句可以单行或多行书写,以分号结尾;MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写;注释有单行注释-- 注释内容或# 注释内容,多行注释/注释内容/。SQL 分类主要有 DDL(数据定义语言)、DML(数据操作语言)、DQL(数据查询语言)、DCL(数据控制语言)。
DDL 用来定义数据库对象,如CREATE、DROP、ALTER等命令用于创建、删除和修改数据库、表等对象。
DML 对表中的数据进行增删改,如INSERT、UPDATE、DELETE命令。
DQL 用于查询数据库数据,主要是SELECT命令。
DCL 控制数据库的访问权限,如GRANT、REVOKE命令。
MySQL 的高级查询功能包括联接操作、子查询、聚合函数等,这些功能可以帮助用户更高效地从数据库中获取所需数据。
联接操作:
内连接通用列字段名称必须一致,去除重复字段,关联表中出现的字段值最终才能出现在结果集中,内连接与连接顺序无关,没有主从表之分。例如:select name, score from student,class where student.class_name = class.class_name;或者select * from student inner join class on student.class_name = class.class_name;。外连接有主从表之分,与连接循序有关。依次遍历主表中记录,与从表中记录进行匹配,如果匹配到则连接展示,否则以 null 填充。如select * from student left join class on student_name = class_name;会全部展示左边 student 内的数据。
子查询:
主要包括单行子查询和多行子查询。单行子查询如select * from student where score > (select score from student where name = ‘张三’);,多行子查询如select * from student where score in (select score from student where class_id = 3) and name like ‘张%’;。
聚合函数:可以对一组数据进行计算并返回一个单一的值。例如AVG()函数用于计算平均值,SUM()函数用于求和等。
索引的创建与使用:
索引用于提高数据库查询的速度。MySQL 支持多种类型的索引,如 B-Tree 索引、哈希索引、全文索引等。
创建索引:可以使用CREATE INDEX语句为表的一个或多个列创建索引,例如CREATE INDEX index_name ON table_name (column1, column2);。在创建表时,也可以定义索引,如CREATE TABLE table_name (column1 INT, column2 VARCHAR(50), INDEX index_name (column1, column2));。还可以使用ALTER TABLE语句添加索引,如ALTER TABLE table_name ADD INDEX index_name (column1, column2);。
索引类型:
普通索引是最基本的索引,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。创建方式有多种,如CREATE INDEX index_name ON table(column(length))、ALTER TABLE table_name ADD INDEX index_name ON (column(length))、在创建表的时候同时创建索引等。
唯一索引与普通索引类似,但索引列的值必须唯一,但允许有空值。创建方式有CREATE UNIQUE INDEX indexName ON table(column(length))、ALTER TABLE table_name ADD UNIQUE indexName ON (column(length))、在创建表的时候直接指定等。
主键索引是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候同时创建主键索引。
组合索引指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合,例如由 id、name 和 age3 个字段构成的索引,索引行中就按 id/name/age 的顺序存放,索引组合中的字段可以是 (id,name,age)、(id,name) 或者 (id)。添加组合索引可以使用ALTER TABLE table ADD INDEX name_city_age (id,name,age);或者CREATE TABLE tab3(id INT(4) NOT NULL, name CHAR(20) NOT NULL, age INT(3) NOT NULL, info VARCHAR(255), INDEX multiIdx(id,name,age));。
全文索引主要用来查找文本中的关键字,而不是直接与索引中的值相比较。跟其它索引大不相同,它更像是一个搜索引擎,而不是简单的 where 语句的参数匹配。全文索引配合match against操作使用,而不是一般的 where 语句加 like。可以在create table,alter table,create index使用,不过目前只有 char、varchar,text 列上可以创建全文索引。例如CREATE TABLE table (id int(11) NOT NULL AUTO_INCREMENT,title char(255) CHARACTER NOT NULL,content text CHARACTER NULL,time int(10) NULL DEFAULT NULL, PRIMARY KEY (id), FULLTEXT (content));、ALTER TABLE article ADD FULLTEXT index_content(content)、CREATE FULLTEXT INDEX index_content ON article(content)。
删除索引:可利用ALTER TABLE或DROP INDEX语句来删除索引。例如DROP INDEX index_name ON table_name;。
查看索引:使用SHOW INDEX FROM 表名;可以查看表的索引。解读索引结果中包含表名、是否唯一索引、索引名称、列在索引中的位置、定义索引的列字段、存储顺序、基数、被编入索引的字符数量、关键字压缩指示、是否包含 NULL、索引类型和注释等信息。
视图的创建与管理:
MySQL 数据库视图是一个虚拟的表,它基于数据库中的一个或多个表的查询结果。视图是一个动态的对象,它并不在数据库中实际存储数据,而是根据定义的查询语句在查询时生成数据。
功能和作用:
简化复杂查询:可以将复杂的查询语句封装成一个视图,简化查询的过程。
数据安全性:可以通过视图限制用户对数据的访问权限,只允许用户查看视图中指定的数据。
数据逻辑分离:可以通过视图隐藏底层数据结构,实现数据逻辑和物理结构的分离,提高数据的可维护性和可扩展性。
创建视图的方法:创建视图的语法如下:CREATE VIEW view_name AS SELECT columns FROM table_name WHERE conditions;。例如,有一个名为 customers 的表,其中包含 id、name 和 email 三个列,创建一个显示 name 和 email 列的视图,命名为 customer_view,代码如下:CREATE VIEW customer_view AS SELECT name, email FROM customers;。
管理视图的方法:
查看视图:使用SHOW CREATE VIEW view_name;语句可以查看视图的定义和结构。
更新视图:使用CREATE OR REPLACE VIEW view_name AS new_query;语句可以更新视图的查询语句。例如,如果需要更新视图的查询语句,可以执行如下代码:CREATE OR REPLACE VIEW customer_view AS SELECT name, email, address FROM customers;。
删除视图:使用DROP VIEW view_name;语句可以删除视图。例如,如果需要删除视图,可以执行如下代码:DROP VIEW customer_view;。
请注意,视图是根据查询语句生成数据,因此在查询时可能会有一定的性能开销。如果需要频繁查询的数据,可以考虑使用其他手段,如创建索引或使用存储过程等。
事务的概念:事务是一个逻辑工作单元,是一组 SQL 语句的集合,这些语句要么全部执行成功,要么全部不执行。
事务的特性:
原子性(Atomicity):事务是一个不可分割的工作单位,事务中的所有操作要么全部成功,要么全部失败回滚。
一致性(Consistency):事务必须使数据库从一个一致性状态变换到另一个一致性状态。
隔离性(Isolation):多个事务并发执行时,一个事务的执行不能被其他事务干扰。
持久性(Durability):一旦事务提交,它对数据库中数据的改变就是永久性的。
操作步骤:
开启事务:使用START TRANSACTION或BEGIN语句开启一个事务。
执行 SQL 语句:在事务中执行一系列 SQL 语句。
提交事务:如果事务中的所有 SQL 语句都执行成功,可以使用COMMIT语句提交事务,使对数据库的更改永久生效。
回滚事务:如果事务中的某些 SQL 语句执行失败,可以使用ROLLBACK语句回滚事务,撤销对数据库的更改。
隔离级别:
MySQL 支持四种隔离级别,分别是读未提交(Read uncommitted)、读已提交(Read committed)、可重复读(Repeatable read)和串行化(Serializable)。
读未提交:一个事务可以读取另一个未提交事务的数据,会导致脏读问题。
读已提交:一个事务只能读取另一个已提交事务的数据,可以避免脏读问题,但可能会出现不可重复读问题。
可重复读:在同一个事务中多次读取同一数据时,结果是一致的,可以避免不可重复读问题,但可能会出现幻读问题。
串行化:最高的隔离级别,通过强制事务串行执行,避免了脏读、不可重复读和幻读问题,但会严重影响数据库的性能。
不同隔离级别可能引发的问题:
脏读:一个事务读取到了另一个事务未提交的数据,然后另一个事务回滚了,导致第一个事务读取到的数据是错误的。
不可重复读:在同一个事务中,多次读取同一数据时,结果不一致。例如,一个事务在读取数据后,另一个事务修改了该数据并提交,导致第一个事务再次读取该数据时结果不同。
幻读:在同一个事务中,执行相同的查询两次,得到的结果集不同。例如,一个事务在查询数据后,另一个事务插入了新的数据并提交,导致第一个事务再次查询时结果集多了一些数据。
存储过程的创建、调用和删除:
创建存储过程:MySQL 存储过程是一些 SQL 语句的集合,可以使用CREATE PROCEDURE语句创建存储过程。语法如下:CREATE PROCEDURE procedure_name([in|out] param1 param_type, [in|out] param2 param_type) BEGIN sql statements; END;。例如:create procedure procedure_name() begin select * from table_name; end;。
调用存储过程:使用CALL语句调用存储过程,例如CALL procedure_name();。
删除存储过程:使用DROP PROCEDURE语句删除存储过程,例如DROP PROCEDURE procedure_name;。
触发器的作用和使用方法:
触发器是一种特殊的存储过程,它在特定的表上发生特定的事件时自动执行。
作用:可以用于实现数据的完整性约束、自动更新相关表的数据等。
使用方法:使用CREATE TRIGGER语句创建触发器。语法如下:CREATE TRIGGER trigger_name trigger_time trigger_event ON table_name FOR EACH ROW trigger_body;。其中,trigger_name是触发器的名称,trigger_time是触发时间(BEFORE 或 AFTER),trigger_event是触发事件(INSERT、UPDATE 或 DELETE),table_name是触发触发器的表名,trigger_body是触发器的主体,包含要执行的 SQL 语句。例如:CREATE TRIGGER trigger_name AFTER INSERT ON table_name FOR EACH ROW BEGIN UPDATE another_table SET column_name = column_name + 1; END;。
1. BinLog 的作用
Bin-log 日志用于记录所有更新了数据或者已经潜在更新了数据的所有语句,以 “事件” 的形式保存,描述数据更改。
主要用途包括数据恢复、主从复制、数据审计和回滚、数据迁移和导入导出、异构系统数据交互、性能监控和分析、数据库监控和预警等。
参数设置包括 log_bin 设置此参数表示启用 binlog 功能,并指定路径名称;log_bin_index 设置此参数是指定二进制索引文件的路径与名称;binlog_do_db 此参数表示只记录指定数据库的二进制日志;binlog_ignore_db 此参数表示不记录指定的数据库的二进制日志;max_binlog_cache_size 此参数表示 binlog 使用的内存最大的尺寸;binlog_cache_size 此参数表示 binlog 使用的内存大小;sync_binlog 控制 bin-log 日志的刷盘频率等。
Bin-log 的本地日志文件采用追加写的模式,当一个日志文件写满后,会创建一个新的 bin-log 日志文件,每个日志文件的命名为 mysql-bin.000001、mysql-bin.000002、mysql-bin.00000x 等,可以通过 show binary logs; 命令查看已有的 bin-log 日志文件。
Bin-log 的本地文件中存储的日志记录共有 Statment、Row、Mixed 三种格式。Statment 模式记录会对数据库产生变更的 SQL 语句,节约空间,性能较好,但恢复数据、主从同步数据时可能会出现数据不一致的情况。Row 模式记录具体哪一个分区中的、哪一个页中的、哪一行数据被修改了,数据精准,但数据量大会导致磁盘 IO、网络带宽开销高。Mixed 模式结合了两者的优劣势,对于可以复制的 SQL 采用 Statment 模式记录,对于无法复制的 SQL 采用 Row 记录。
2. RedoLog 的作用
确保事务的持久性,防止在发生故障的时间点,尚有脏页未写入磁盘,在重启 mysql 服务的时候,根据 redo log 进行重做,从而达到事务的持久性这一特性。
内容是物理格式的日志,记录的是物理数据页面的修改的信息,其 redo log 是顺序写入 redo log file 的物理文件中去的。
事务开始之后就产生 redo log,在事务的执行过程中,便开始写入 redo log 文件中。当对应事务的脏页写入到磁盘之后,redo log 的使命也就完成了,重做日志占用的空间就可以重用(被覆盖)。
3. UndoLog 的作用
保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读。
逻辑格式的日志,在执行 undo 的时候,仅是将数据从逻辑上恢复至事务之前的状态,而不是物理上操作实现的。
事务开始之前,将当前是的版本生成 undo log,undo 也会产生 redo 来保证 undo log 的可靠性。当事务提交之后,undo log 并不能立马被删除,而是放入待清理的链表,由 purge 线程判断是否由其他事务在使用 undo 段中表的上一个事务之前的版本信息,决定是否可以清理 undo log 的日志空间。
4. 主从同步流程
主库接受写请求,数据落磁盘的同时,记录操作到 bin-log。
当主库存在从库的连接时,启动一个 bin-log dump 线程监听 bin-log 的变化。
当 bin-log dump 线程监听到 bin-log 的变化时,将变化的数据推送给从库。
从库的 I/O 线程接收 bin-log 的变化通知,并将其写入到本地的 relay-log。
从库的 SQL 线程从 relay-log 拉取数据,并写入到本地的 DB 文件中,完成主从同步。
1. 用户管理
使用用户名密码登录 MySQL 数据库,如mysql --user=finley --password db_name。
添加新用户,如CREATE USER ‘custom’@‘localhost’ IDENTIFIED BY ‘password’;。
给用户添加数据库操作权限,如GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON bankaccount.* TO ‘custom’@‘localhost’;。
删除用户,如DROP USER ‘jeffrey’@‘localhost’;。
设置用户数据库操作资源限制,如CREATE USER ‘francis’@‘localhost’ IDENTIFIED BY ‘frank’ ->WITH MAX_QUERIES_PER_HOUR 20 -> MAX_UPDATES_PER_HOUR 10 -> MAX_CONNECTIONS_PER_HOUR 5 -> MAX_USER_CONNECTIONS 2;。
修改用户操作数据库资源限制,如ALTER USER ‘francis’@‘localhost’ WITH MAX_QUERIES_PER_HOUR 100;。
密码过期设置,如ALTER USER ‘jeffrey’@‘localhost’ PASSWORD EXPIRE;。
设置 MySQL 密码的有效时间,如SET GLOBAL default_password_lifetime = 180;。
2. 权限控制
MySQL 服务器通过权限表来控制用户对数据库的访问,权限表存放在 MySQL 数据库中,由 MySQL_install_db 脚本初始化。存储账户权限表主要有:user、db、host、tables_priv、columns_priv 和 procs_priv。
user 表是 MySQL 中最重要的一个权限表,记录允许连接到服务器的账号信息,里面的权限是全局级的。db 表存储了用户对某个数据库的操作权限。tables_priv 表用来对表设置操作权限,columns_priv 表用来对表的某一列设置权限。procs_priv 表可以对存储过程和存储函数设置操作权限。
3. 备份与恢复
4. 性能优化和调优
1. 实际项目展示
2. 面试中常见的 MySQL 问题及解答
问题:MySQL 的索引有哪些类型?
解答:MySQL 支持多种类型的索引,如 B-Tree 索引、哈希索引、全文索引等。普通索引允许在定义索引的列中插入重复值和空值;唯一索引索引列的值必须唯一,但允许有空值;主键索引是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值;组合索引指多个字段上创建的索引;全文索引主要用来查找文本中的关键字。
问题:MySQL 的事务隔离级别有哪些?分别有什么特点?
解答:MySQL 支持四种隔离级别,分别是读未提交、读已提交、可重复读和串行化。读未提交一个事务可以读取另一个未提交事务的数据,会导致脏读问题;读已提交一个事务只能读取另一个已提交事务的数据,可以避免脏读问题,但可能会出现不可重复读问题;可重复读在同一个事务中多次读取同一数据时,结果是一致的,可以避免不可重复读问题,但可能会出现幻读问题;串行化最高的隔离级别,通过强制事务串行执行,避免了脏读、不可重复读和幻读问题,但会严重影响数据库的性能。