系统学习Mysql

前言

搞开发天天都是数据库数据库的说,也很好理解数据库就是存储数据的库嘛,但是市面上有哪些数据库呢?这里来系统性的学习一下mysql数据库,相信搞代码开发的都不陌生,mysql是一款关系型数据库,什么叫关系型数据库呢,简单理解就是用行和列(表格)来存储数据的。这里介绍一下mysql的索引,存储引擎,以及使用过程中的各种问题

mysql的三范式

首先我们说一下设计表的时候需要注意什么,这里mysql有三范式,是关系数据库设计中的重要原则,用于确保数据结构合理、减少数据冗余和提高数据的一致性,三范式要求数据库设计中的每个表都必须满足以下三个条件:

第一范式:

数据库表中的每一列都是不可分割的原子值,即每一列都不可再分,这意味着列中不能有多个值或者重复的组合值

如:一个订单表中,不应该有一个 "商品" 列存储多个商品的名称,而应该拆分为多个行,每行对应一个商品。

第二范式:

在满足第一范式的基础上,表中的非主键列(即非唯一标识行的列)必须完全依赖于主键,而非依赖于主键的一部分

如:一个订单详情表,如果包含了订单号和商品号作为复合主键,那么任何关于商品的信息(如商品名称、价格等)都应该依赖于商品号这个完整的主键,而非一部分只依赖订单号

第三范式:

在满足第二范式的基础上,表中的非主键列之间不能存在传递依赖关系,

换句话说:如果一个非主键列依赖于另一个非主键列,那么应该将其抽取出来成为一个新的表,使每个非主键列只依赖于主键

包含员工信息的表,如果存在一个列 "部门地址" 依赖于 "部门名称"而不直是接依赖于主键(例如部门编号),那么最好将 "部门地址" 作为独立的表,通过部门名称关联到主表

通过遵循三范式,可以帮助设计出结构良好、高效的数据库模型,提高数据存储和管理的效率,减少数据冗余和更新异常的发生。

mysql的索引

什么是索引呢,就是一种数据库中用来加快数据检索速度的一种数据结构,它类似于书籍的目录,通过提供一种快速访问数据的方式,帮助数据库系统在执行查询时能够迅速定位到需要的数据行,而不是每次都从头开始遍历整个数据表。她虽然能大大的加快数据的查询,然而索引也并非没有成本。索引会占用额外的存储空间,并且在数据更新时可能会影响性能,因为更新操作不仅要更新表中的数据,还要更新索引。因此,在设计数据库时,需要权衡索引的使用。那么索引有哪些呢:

主键索引

主键索引数据列不允许重复,且不允许为空(NULL),一个表里只能有一个主键索引,是一种特殊的唯一索引

ALTER TABLE tableName ADD PRIMARY KEY (column)

唯一索引

索引数据列必须是唯一的,但是允许空值(NULL)但确定是唯一的NULL

ALTER TABLE tableName ADD UNIQUE (column)

普通索引

普通索引是mysql使用中基本的索引类型,索引列允许重复,允许有空值(NULL)

ALTER TABLE tableName INDEX indexName (cloumn)

全文索引

为了快速检索大文本数据,字段长度比较大时,普通索引“like”查询效率慢就可以使用全文索引,它是基于倒排索引,类似搜索引擎,一开始只有MYISAM存储引擎支持使用,后续INNODB存储引擎在5.6.4 版本之后也支持使用

ALTER TABLE tableName FULLTEXT (cloumn)

前缀索引

文本类型,TEXT,BLOB,或者很长的VACHAR,前缀索引可以指定索引数据列的长度

ALTER TABLE tableName ADD KEY(cloumn(length))

组合索引(复合索引)

指定多个字段,这里需要注意一下只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用,需要遵循最左前缀原则。主键索引,普通索引,唯一索引等都可以使用多个字段形成组合索引

ALTER TABLE tableNAME INDEX indexName (cloumn1,cloumn2,cloumn3...)

空间索引

一种专门用于处理空间数据的索引结构,空间数据通常包括点、线、面等几何对象,这些对象具有空间位置和空间关系,空间索引的目的是为了在这些大量空间数据中快速地进行空间查询。(mysql5.7版本之后支持)一般使用的很少,了解即可。

上述介绍了mysql中常见的索引类型以及其中一种创建方式,描述比较少,仅作了解。还请见谅。

创建索引的方式

常见的索引创建方式有:

1.创建表的同时指定在那些列上加索引

CREATE TABLE my_table (

id INT PRIMARY KEY,

name VARCHAR(50),

age INT,

INDEX idx_name (name)

);

2.使用ALTER TABLE

上述介绍索引中创建方式

3.还有些索引需要特殊的创建方式

删除索引

以使用 DROP INDEX 命令将其删除

DROP INDEX idx_name ON my_table;

索引失效的情况

索引能够大幅的加快查询速度是不假,但是索引使用的过程中要避免索引失效,就是创建了索引但是并没有按照我们预想的方式运行查询,速度也没有达到我们预期的效果下面介绍一些索引会失效的情况

1.没使用最左前缀原则

最左前缀原则要求使用索引查询条件时第一个条件必须是创建索引时的第一个索引列比如:(a,b,c)   where a=1 and b=1 and c=1 正确使用索引 但是 b=1 and c=1 索引失效,这里只是其中一种情况,其实只要不是a放在第一位都是索引失效

2.尽量明确查询列

在使用查询时尽量明确查询列趋向于走覆盖索引,因为使用索引之后再去回表查询所需要的字段如果机制判断索引没有扫描全表来的快就会放弃使用索引,select *尽量不要使用

3.索引列参与计算

举例:where id+1 = 2(失效)

这种情况建议提前算好再进行查询或者sql查询条件放右侧 (where id = 2-1)

4.索引列使用了函数

这种情况跟上一个情况一样都是在查询之前进行了全表扫描

5.错误使用了like关键字

使用like关键字的时候我们要使用%来确定位置,当%在最前面的时候会索引失效,因为索引是排序的他放到最前面破坏了索引排序导致索引失效

6.隐式类型转换

字段类型为VACHAR查询的时候使用INT 比如: idCar = 1002 索引失效

正确应该是 idCar = "1002" 或者 idCar = '1002'

7.查询条件OR关键字

其中一种条件没有索引会导致整条查询索引失效

where id= 1 or age = 2 age没有索引 索引失效

OR两边使用范围查找 会导致索引失效

8.索引列作比较

where age > id  索引失效

一般不要做这样的操作也不会进行

9.不等于 "!=" 或者 "<>"

可能会索引失效,结果集占比比较大的时候就会失效

id!=2 正常走索引因为结果集2占比小

10.查询条件使用isNULL正常走索引,使用isNotNULL失效

11.not in 如果是主键 not in() 则正常,如果是普通索引则失效

12.not exists 失效

13.order by 排序,如果不是覆盖索引则失效

14.全表扫描比索引效率高,主动放弃索引

EXPLAIN执行计划

explain关键字放在查询语句之前可以查看索引的执行计划,是否使用索引,检查索引失效的原因,其中有个type字段表示了查询使用的访问类型,即查询过程中的执行方法。以下是type字段可能的取值以及含义:

TYPE字段:

system:

这是最好的情况,表示查询结果只返回一行结果。这通常是通过直接访问表的PRIMARY KEY 或者唯一索引来完成的。

const:

表示Mysql在查询中找到了常量值,这是在连接的第一个表中进行的。由于这是常量条件,Mysql只会读取一次表中的一行数据。例如通过主键访问一条数据

eq_ref:

类似于const,但在使用了索引的情况下。此类型的查询是通过某个唯一索引来访问表的,对每个索引表只有一行匹配。常见于使用主键索引或者唯一索引来进行连接操作

ref:

表示此查询使用非唯一索引来查询,返回的是所有匹配某个单独值的行,常用于非唯一索引或者索引前缀的连接操作

range:

表示使用了索引来进行范围查询,比如 "BETWEEN", ">", "<" 等

index:

表示Mysql要扫描整个索引列表来找到所需要的行,通常是没有合适的索引情况下,Mysql才会使用这种查询方式

all:

表示全表扫描,这是最差的情况

其他字段以及情况:

这里只介绍几种常见的详细可看引荐文章

MySQL:MySQL的EXPLAIN各字段含义详解_mysql explain 各个字段含义-CSDN博客

Mysql的连接操作

内连接(Inner Join)

结果集包含符合连接条件的行,即两个表中列值匹配的行

SELECT src_in_store.in_store_id,src_store.store_id FROM src_in_store INNER JOIN src_store ON src_in_store.store_id = src_store.store_id

结果:

左连接(Left Join)

左连接返回左表中的所有行,以及右表中符合连接条件的行,如果右表中没有匹配的行,则对应位置会填充为NULL

SELECT src_in_store.in_store_id,src_store.store_id FROM src_in_store LEFT JOIN src_store ON src_in_store.store_id = src_store.store_id

结果:

右连接(Right Join)

右连接与左连接类似,但是它返回右表中的所有行,以及左表中符合连接条件的行,如果左表中没有匹配的行,则对应位置会填充为NULL

SELECT src_in_store.in_store_id,src_store.store_id FROM src_in_store RIGHT JOIN src_store ON src_in_store.store_id = src_store.store_id

结果:

全外连接(Full Join)

全外连接返回左右两个表中所有的行,即使另一个表中没有匹配的行

mysql8.0+支持,mysql8.0之前可以使用UNION代替

交叉连接(Cross Join)

交叉连接返回两个表的笛卡尔积,即左表中的每一行与右表中的每一行组合,不需要ON子句来指定连接条件。

SELECT src_in_store.in_store_id,src_store.store_id FROM src_in_store Cross JOIN src_store 

结果:

Mysql的存储引擎

1.InnoDB

innoDB是mysql默认的事务安全存储引擎,它支持事务,行级锁,外键约束和高并发操作。InnoDB就是为了大量数据操作的

2.MyISAM

MyISAN是mysql早期的引擎,它不支持事务,不支持行级锁,但是简单且速度快,所以它适合读密集型应用,比如日志,数据仓库,归档等等

3.Memory (Heap)

memory是将表存储在内存中,数据在数据库重启的时候会丢失,他适合临时表,高速缓存和数据集合操作等

4.Archive

Archive是存储和检索大量的归档数据,以节省磁盘空间。它支持高压缩,但不支持索引,只能进行insert和select操作

5.CSV

CSV存储引擎以文件格式存储数据,他适合导入导出数据,它支持事务,索引,和锁定,但不支持大规模数据的操作

等等还有其他的存储引擎,感兴趣可以去自行学习这里就介绍这五种常见的引擎。

Mysql的事务

mysql默认是隐式事务提交,他的事务开启,回滚,关闭都是由mysql数据库自己完成,我们并没有去手动开启事务回滚和关闭。什么是事务呢?这里复习一下什么是事务,事务就是一个逻辑工作单元的一系列操作要么都成功要么都失败。以保证数据的一致性和完整性。

事务的四大特性

事务有四大特性分别是:

原子性:

事务中的所有操作要么全都成功要么全都失败回滚,不可能出现停在中间的状态,执行一半成功一半失败的情况

一致性:

事务从一个一致性状态转变到另外一个一致性的状态,事务开始前和事务执行后数据的完整性约束不会遭到破坏

隔离性:

并发执行事务每个事务对于其他事务来说应该都是不可见的,相互隔离的,防止多个事务同时执行由于交叉影响而产生数据不一致的问题

持久性:

事务一旦提交,其对数据库的修改就是永久性的,修改的数据会被永远保存在数据库中,即使系统发生故障数据也不应该丢失

事物的隔离级别

根据上述隔离性来说,有四个隔离级别,由低到高就是

读未提交

读未提交就是说允许一个事务可以读取到其他事务未提交的数据,那么这就会造成脏读的问题。而且这个隔离级别不只会造成脏读,还会造成不可重复读和幻读

读已提交

解决了脏读的问题但是依旧会造成不可重复读和幻读的问题。即允许一个事务只能读取到已经提交的数据,意思就是第一次读取的数据和第二次读取到的数据不一致,因为在两次读取之间其他事务对该数据进行提交事务

可重复读

解决了不可重复读的问题,但是依旧会幻读。它确保了一个事务在执行期间多次读取同一行数据时,始终能看到同样的数据。在该级别下,读取的数据是事务一开始的一个快照,因此可避免脏读和不可重复读

串行化(序列化)

最高的隔离级别,通过强制事务串行执行来解决所有问题,在这种级别下,事务会完全的串行化执行,性能可能会造成影响,因为大量的锁会被用来保证串行执行

Mysql的MVCC

mysql的mvcc即多版本并发控制,mvcc是一种并发控制的方法,一般在数据库管理中实现对数据库的并发访问,在innoDB中实现主要是为了提高数据库并发性能,为事务分配单向增长的时间戳,为每个修改都保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库快照这样就能更好的去处理读-写冲突,做到即使有读有写冲突时,也能做到不加锁,非阻塞并发读。他主要是依赖记录中的三个隐式字段,undo日志,ReadView来实现的

今天就到这,明天继续!,还有什么知识点没提到欢迎评论区留言

  • 10
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值