一文搞懂MySQL数据库

一.数据库基础知识

2019年数据库排名:
一文搞懂MySQL数据库_第1张图片

1.数据库的分类

​ 按照早期的数据库理论,比较流行的数据库模型有三种,分别为层次式数据库、网状数据库和关系型数据库。而在当今的互联网中,最常见的数据库模型主要是两种,即SQL关系型数据库(MySQL)和NoSQL非关系型数据库(Redis)

2.关系型数据库介绍

一文搞懂MySQL数据库_第2张图片

(1)关系型数据库的由来

​ 虽然网状数据库和层次数据库已经很好的解决了数据的集中和共享问题,但是在数据库独立性和抽象级别上扔有很大欠缺。用户在对这两种数据库进行存取时,仍然需要明确数据的存储结构,指出存取路径。而关系型数据库就可以较好的解决这些问题。

我知道这个人的名字了,但是我还想知道他的电话,住址,甚至想知道他所在的公司(company_index)

(2)关系型数据库介绍

​ 关系型数据库模型是把复杂的数据结构归结为简单的二元关系(即二维表格形式)。在关系型数据库中,对数据的操作几乎全部建立在一个或多个关系表格上,通过对这些关联的表格分类、合并、连接或选取等运算来实现数据库的管理。

​ 关系型数据库诞生40多年了,从理论产生发展到现实产品,例如:Oracle和MySQL,Oracle在数据库领域上升到霸主地位,形成每年高达数百亿美元的庞大产业市场。

传统关系数据库:Oracle、MySQL、Microsoft SQL Server、PostgreSQL

大数据常见数据库:Hive、Impala、Presto、ClickHouse

3.非关系型数据库介绍

(1)非关系型数据库诞生背景

​ NoSQL,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSql数据库在特定的场景下可以发挥出难以想象的高效率和高性能,它是作为对传统关系型数据库的一个有效的补充。

​ NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,是一项全新的数据库革命性运动,早期就有人提出,发展至2009年趋势越发高涨。NoSQL的拥护者们提倡运用非关系型的数据存储,相对于铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入。

(2)非关系型数据库种类

1.键值(Key-Value)存储数据库

一文搞懂MySQL数据库_第3张图片

​ 键值数据库就类似传统语言中使用的哈希表。可以通过key来添加、查询或者删除数据库,因为使用key主键访问,所以会获得很高的性能及扩展性

​ 键值数据库主要使用一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署、高并发

典型产品:Memcached、Redis、Ehcache

Redis:将磁盘读到的数据缓存,下次读取直接操作内存,提高读取效率。有自己的持久化策略,数据同步策略。

此外还有:列存储(Column-oriented)数据库,面向文档(Document-Oriented)数据库(MongoDB),图形数据库,时序数据库,搜索引擎存储,xml数据库。

二.数据库三大范式

1.第一范式(1NF):列不可再分

(1)每一列属性都是不可再分的属性值,确保每一列的原子性

(2)两列的属性相近或相似或一样,尽量合并属性一样的列,确保不产冗余数据

一文搞懂MySQL数据库_第4张图片

​ 地址可以拆分为省,市,详细地址。

2.第二范式(2NF)属性完全依赖于主键

一文搞懂MySQL数据库_第5张图片

一文搞懂MySQL数据库_第6张图片

3.第三范式(3NF)属性不依赖于其他非主属性,属性直接依赖于主键

数据不能存在传递关系,即使每个属性都与主键有直接关系不是间接关系。

在这里插入图片描述
一文搞懂MySQL数据库_第7张图片

colleges_name依赖与colleges_index,这时候它就不应该存在于student表中。

一文搞懂MySQL数据库_第8张图片

否则,在更新colleges表中的name属性时,student表中的colleges_name也要同步更改,这样造成了数据冗余。 不便于数据维护,甚至出现数据冲突。

总结:三大范式只是一般设计数据库的基本理念,可以建立冗余较小、结构合理的数据库。如果有特殊情况,当然要特殊对待,数据库设计最重要的是看需求跟性能,需求>性能>表结构。所以不能一味的去追求范式建立数据库,范式是提供一种设计数据库的思想。

三.MySQL数据库

1.简介

​ MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,属于 Oracle旗下产品。MySQL 是最流行的关系型数据库管理系统之一。

​ MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。

​ MySQL所使用的 SQL 语言是用于访问数据库]的最常用标准化语言。MySQL 软件采用了双授权政策,分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择 MySQL 作为网站数据库。(免费)

一文搞懂MySQL数据库_第9张图片

2.SQL

​ SQL 是用于访问和处理数据库的标准的计算机语言。

  • SQL 指结构化查询语言
  • SQL 使我们有能力访问数据库
  • SQL 是一种 ANSI 的标准计算机语言

​ SQL 可与数据库程序协同工作,比如 MS Access、DB2、Informix、MS SQL Server、Oracle、Sybase 以及其他数据库系统。但是由于各种各样的数据库出现,导致很多不同版本的 SQL 语言,为了与 ANSI 标准相兼容,它们必须以相似的方式共同地来支持一些主要的关键词(比如 SELECT、UPDATE、DELETE、INSERT、WHERE 等等),这些就是我们要学习的SQL基础。

(1)表

​ 一个数据库通常包含一个或多个表。每个表由一个名字标识(例如“客户”或者“订单”)。表包含带有数据的记录(行)。

一文搞懂MySQL数据库_第10张图片

(2)CREATE TABLE – 创建表
CREATE TABLE 表名称
(
列名称1 数据类型,
列名称2 数据类型,
列名称3 数据类型,
....
);

一文搞懂MySQL数据库_第11张图片

实例:

​ 本例演示如何创建名为 “Persons” 的表。

​ 该表包含 5 个列,列名分别是:“Id_P”、“LastName”、“FirstName”、“Address” 以及 “City”:

CREATE TABLE Persons
(
Id_P int,
LastName varchar(255),
FirstName varchar(255),
Address varchar(255),
City varchar(255)
);

在这里插入图片描述

(3)INSERT – 插入数据

​ INSERT INTO 语句用于向表格中插入新的行。

语法:

INSERT INTO 表名称 VALUES (1,2,....);

​ 我们也可以指定所要插入数据的列:

INSERT INTO table_name (1,2,...) VALUES (1,2,....);

实例:

​ 本例演示 “Persons” 表插入记录的两种方式:

1、插入新的行

INSERT INTO Persons VALUES (1, 'Gates', 'Bill', 'Xuanwumen 10', 'Beijing');

2、在指定的列中插入数据

INSERT INTO Persons (LastName, Address) VALUES ('Wilson', 'Champs-Elysees');

一文搞懂MySQL数据库_第12张图片

插入成功后,数据如下:

在这里插入图片描述

(4)SELECT-查询数据,DISTINCT – 去除重复值

语法:

SELECT * FROM 表名称;
SELECT DISTINCT 列名称 FROM 表名称;

实例:

SELECT LASTNAME FROM Persons;

一文搞懂MySQL数据库_第13张图片

可以发现,在结果集中,Wilson 被列出了多次。

如需从 “LASTNAME” 列中仅选取唯一不同的值,我们需要使用 SELECT DISTINCT 语句:

SELECT DISTINCT LASTNAME FROM Persons;

一文搞懂MySQL数据库_第14张图片

(5)WHERE – 条件过滤

如果需要从表中选取指定的数据,可将 WHERE 子句添加到 SELECT 语句。

语法:

SELECT 列名称 FROM 表名称 WHERE 列 运算符 值;

一文搞懂MySQL数据库_第15张图片

实例:

SELECT * FROM Persons WHERE City='Beijing';

一文搞懂MySQL数据库_第16张图片

(6)AND & OR – 运算符

语法:

SELECT * FROM 表名称 WHERE 列 运算符 值 AND 列 运算符 值;
SELECT * FROM 表名称 WHERE 列 运算符 值 OR 列 运算符 值;
(7)ORDER BY-排序

语法:

SELECT * FROM 表名称 ORDER BY1,2; // 升序
SELECT * FROM 表名称 ORDER BY1,2 DESC; // 降序

一文搞懂MySQL数据库_第17张图片

注意: 按照依赖顺序排列,列1如果相同,按照列2排序,null默认排在最后。

(8)UPDATE – 更新数据
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值;
(9)DELETE – 删除数据
DELETE FROM 表名称 WHERE 列名称 =;
(10)TRUNCATE TABLE – 清除表数据
TRUNCATE TABLE 表名称;
(11)DROP TABLE – 删除表
DROP TABLE 表名称;

还有一些SQL高级语言:如LIKE,IN,AS,多表查询JOIN,联合UNION和常用函数AVG,COUNT等等。

SQL语言

3.事务

(1)事务定义

​ 1.事务:一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元)
​ 2.一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成
​ 3.事务只和DML语句有关,或者说DML语句才有事务。这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同

(2)转账操作理解事务

​ 关于银行账户转账操作,账户转账是一个完整的业务,最小的单元,不可再分————————也就是说银行账户转账是一个事务

以下是银行账户表t_act(账号、余额),进行转账操作

actno		balance
1			500
2			100
1
2
3

转账操作

update t_act set balance=400 where actno=1;
update t_act set balance=200 where actno=2;

​ 以上两台DML语句必须同时成功或者同时失败。最小单元不可再分,当第一条DML语句执行成功后,并不能将底层数据库中的第一个账户的数据修改,只是将操作记录了一下;这个记录是在内存中完成的;当第二条DML语句执行成功后,和底层数据库文件中的数据完成同步。若第二条DML语句执行失败,则清空所有的历史操作记录,要完成以上的功能必须借助事务

(3)事务四大特征(ACID)

原子性(A):事务是最小单位,不可再分,要么全部完成,要么全部不完成。

一致性©:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。

例如:现有完整性约束a+b=10,如果一个事务改变了a,那么必须得改变b,使得事务结束后依然满足a+b=10,否则事务失败。

隔离性(I):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。

持久性(D):是事务的保证,事务终结的标志(内存的数据持久到硬盘文件中)

(4)事务操作
提交操作(事务成功)

start transaction

DML语句

commit

  mysql> start transaction;#手动开启事务
  mysql> insert into t_user(name) values('pp');
  mysql> commit;#commit之后即可改变底层数据库数据
  mysql> select * from t_user;
  +----+------+
  | id | name |
  +----+------+
  |  1 | jay  |
  |  2 | man  |
  |  3 | pp   |
  +----+------+
  3 rows in set (0.00 sec)
回滚操作(事务失败)

start transaction

DML语句

rollback

  mysql> start transaction;
  mysql> insert into t_user(name) values('yy');
  mysql> rollback;
  mysql> select * from t_user;
  +----+------+
  | id | name |
  +----+------+
  |  1 | jay  |
  |  2 | man  |
  |  3 | pp   |
  +----+------+
  3 rows in set (0.00 sec)
(5)无隔离级别会引发的后果

如果事务不设置隔离,会发生什么事呢?

脏读(Dirty Read)

脏读是指一个事务对数据进行了修改,而这种修改还没有提交到数据库中,另外一个事务也访问这个数据,然后使用了这个未提交到数据库的数据。

张三的工资:5000 

事务A:		工资 = 8000		事务A尚未提交
事务B:		读取张三的工资		读取到工资=8000
事务A:		发生异常		回滚事务		工资回滚为5000
所以事务B读取到工资=8000为脏数据,事务B做了一次脏读
不可重复读(Non-repeatable Read)

不可重复读是指对于数据库中的某个数据,一个事务范围内的多次查询却返回了不同的结果,这是由于在查询过程中,数据被另外一个事务修改并提交了。

事务A:	读取张三的工资=5000	后续操作中	事务未提交
事务B:	张三的工资改为8000					提交事务
事务A:	再次读取张三的工资	工资=8000		
在一个事务中前后两次读取的结果并不致,这就产生了不可重复读
幻读(Phantom Read)

幻读指的是多个事务一起执行时发生的一种现象。例如事务T1对表中某列的所有行数据进行了集中修改,同时,事务T2向表中插入一行新数据。那么,之后操作事务T1的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。。

工资为5000的员工有10人
事务A:	读取所有工资为5000的人数=10人		事务未提交
事务B:	插入一条人的数据	工资=5000		提交事务
事务A:	修改所有工资为5000的人的工资为6000	事务未提交	
改变了11条数据
事务A		 读取所有工资为5000的人数=10人		事务未提交
此时产生了幻读。
【补充】区分三者

脏读读取到的是一个未提交的数据,不可重复读读取到的是前一个事务提交的数据
不可重复读的重点是修改: 同样的条件,你读取过的数据,再次读取出来发现值不一样了
幻读的重点在于新增或者删除:同样的条件,第 1 次和第 2 次读出来的记录数不一样

(6)事务隔离级别

事物A和事物B之间具有一定的隔离性
隔离性有隔离级别(4个)

​ 读未提交:read uncommitted

​ 读已提交:read committed

​ 可重复读:repeatable read

​ 串行化:serializable

一文搞懂MySQL数据库_第18张图片

1、 读未提交

- 事物A和事物B,事物A未提交的数据,事物B可以读取到
- 这里读取到的数据叫做“脏数据”
- 这种隔离级别最低,这种级别一般是在理论上存在,数据库隔离级别一般都高于该级别

2、读已提交

- 事物A和事物B,事物A提交的数据,事物B才能读取到
- 这种隔离级别高于读未提交
- Oracle默认隔离级别

3、可重复读

- 事务A和事务B,事务A提交之后的数据,事务B读取不到
- 这种隔离级别可以避免“不可重复读取”,达到可重复读取
- MySQL默认级别
- 虽然可以达到可重复读取,但是会导致“幻像读”
注意:innoDB某些版本已经通过一些方法解决了幻读问题,所以不必担心。

4、串行化

- 事务A和事务B,事务A在操作数据库时,事务B只能排队等待
- 这种隔离级别很少使用,吞吐量太低,用户体验差
- 这种级别可以避免“幻像读”,每一次读取的都是数据库中真实存在数据,事务A与事务B串行,而不并发

4.索引

​ 索引是对数据库表中一列或多列的值进行排序的一种结构。MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度

优点:

索引大大减小了服务器需要扫描的数据量,从而大大加快数据的检索速度,这也是创建索引的最主要的原因

​ 索引可以帮助服务器避免排序和创建临时表

​ 索引可以将随机IO变成顺序IO

​ 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

缺点:

创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加

​ 索引需要占物理空间,除了数据表占用数据空间之外,每一个索引还要占用一定的物理空间,如果需要建立聚簇索引,那么需要占用的空间会更大

​ 对表中的数据进行增、删、改的时候,索引也要动态的维护,这就降低了整数的维护速度

​ 如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果。

对于非常小的表,大部分情况下简单的全表扫描更高效;

(1)InnoDB索引结构

​ B-树就是B树,多路搜索树,树高一层意味着多一次的磁盘I/O,下图是3阶

一文搞懂MySQL数据库_第19张图片

注意B树的非叶结点不单单只有索引,还能存放数据

  • 关键字集合分布在整颗树中;

  • 任何一个关键字出现且只出现在一个结点中;

  • 搜索有可能在非叶子结点结束;

  • 其搜索性能等价于在关键字全集内做一次二分查找;

  • 自动层次控制;

B+树是B-树的变体,也是一种多路搜索树

一文搞懂MySQL数据库_第20张图片

B+树非叶子节点不存数据,一次io可以读取更大的索引集,减少了IO次数,加快了搜索速度。

  • 所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;
  • 不可能在非叶子结点命中;
  • 非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;
  • 每一个叶子节点都包含指向下一个叶子节点的指针,从而方便叶子节点的范围遍历。
  • 更适合文件索引系统;

InnoDB中的页大小为16KB,且不可以更改

InnoDB是B+树结构的

(2)索引类型

**Mysql目前主要有以下几种索引类型:**FULLTEXT,HASH,BTREE,RTREE。

  1. FULLTEXT
    即为全文索引,目前只有MyISAM引擎支持。其可以在CREATE TABLE ,ALTER TABLE ,CREATE INDEX 使用,不过目前只有 CHAR、VARCHAR ,TEXT 列上可以创建全文索引。

​ 全文索引并不是和MyISAM一起诞生的,它的出现是为了解决WHERE name LIKE “%word%"这类针对文本的模糊查询效率较低的问题。

  1. HASH
    由于HASH的唯一(几乎100%的唯一)及类似键值对的形式,很适合作为索引。

​ HASH索引可以一次定位,不需要像树形索引那样逐层查找,因此具有极高的效率。但是,这种高效是有条件的,即只在“=”和“in”条件下高效,对于范围查询、 排序及组合索引仍然效率不高。

  1. BTREE
    BTREE索引就是一种将索引值按一定的算法,存入一个树形的数据结构中(二叉树),每次查询都是从树的入口root开始,依次遍历node,获取leaf。这是MySQL里默认和最常用的索引类型。

  2. RTREE
    RTREE在MySQL很少使用,仅支持geometry数据类型,支持该类型的存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种。

​ 相对于BTREE,RTREE的优势在于范围查找。

(3)索引种类

普通索引:仅加速查询

唯一索引:加速查询 + 列值唯一(可以有null)

主键索引:加速查询 + 列值唯一(不可以有null)+ 表中只有一个

组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并

全文索引:对文本的内容进行分词,进行搜索

(4)索引操作
创建索引:
--创建普通索引CREATE INDEX index_name ON table_name(col_name);
--创建唯一索引CREATE UNIQUE INDEX index_name ON table_name(col_name);
--创建普通组合索引CREATE INDEX index_name ON table_name(col_name_1,col_name_2);
--创建唯一组合索引CREATE UNIQUE INDEX index_name ON table_name(col_name_1,col_name_2);

通过修改表结构创建索引:
ALTER TABLE table_name ADD INDEX index_name(col_name);

创建表时直接指定索引:
CREATE TABLE table_name (ID INT NOT NULL,col_name VARCHAR (16) NOT NULL,INDEX index_name (col_name));

删除索引:
--直接删除索引DROP INDEX index_name ON table_name;
--修改表结构删除索引ALTER TABLE table_name DROP INDEX index_name;

其他:
  - 查看表结构
     desc table_name;
  - 查看生成表的SQL
     show create table table_name;
  - 查看索引
     show index from  table_name;
  - 查看执行时间
     set profiling = 1;
     SQL...
     show profiles;


able_name(col_name_1,col_name_2);
–创建唯一组合索引CREATE UNIQUE INDEX index_name ON table_name(col_name_1,col_name_2);

通过修改表结构创建索引:
ALTER TABLE table_name ADD INDEX index_name(col_name);

创建表时直接指定索引:
CREATE TABLE table_name (ID INT NOT NULL,col_name VARCHAR (16) NOT NULL,INDEX index_name (col_name));

删除索引:
–直接删除索引DROP INDEX index_name ON table_name;
–修改表结构删除索引ALTER TABLE table_name DROP INDEX index_name;

其他:

  • 查看表结构
    desc table_name;
  • 查看生成表的SQL
    show create table table_name;
  • 查看索引
    show index from table_name;
  • 查看执行时间
    set profiling = 1;
    SQL…
    show profiles;

你可能感兴趣的:(MySQL,mysql)