这些知识点都不知道,别说会Mysql

140 阅读8分钟

一、MySQL中MyISAM和InnoDB的区别有哪些? 

区别:

1,InnoDB支持事务,MyISAM不支持; 对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;

2,InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败; 

3,InnoDB是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。

但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此主键不应该过大,因为主键太大,其他索引也都会很大。 

而MyISAM是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。 

4,InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快; 

5,Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高; 

如何选择: 

1),是否要支持事务,如果要请选择innodb,如果不需要可以考虑MyISAM; 

2),如果表中绝大多数都只是读查询,可以考虑MyISAM,如果既有读写也挺频繁,请使用InnoDB;

3),系统奔溃后,MyISAM恢复起来更困难,能否接受; 

4),MySQL5.5版本开始Innodb已经成为Mysql的默认引擎(之前是MyISAM),说明其优势是有目共睹的,如果你不知道用什么,那就用InnoDB,至少不会差。 

二、mysql事务隔离级别 

2.1 事务的基本要是(ACID) 

1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。 

2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。 

3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。 

4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

2.2 事务的并发问题

1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据 

2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。 

3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。 

小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表 

2.3 mysql事务隔离级别 

事务隔离级别 脏读 不可重复读 幻读 
读未提交(read-uncommitted) 是 是 是 

不可重复读(read-committed) 否 是 是 

可重复读(repeatable-read) 否 否 是 

串行化(serializable) 否 否 否  

2.4 补充 

1、事务隔离级别为读提交时,写数据只会锁住相应的行 

2、事务隔离级别为可重复读时,如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key 锁; 如果检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其他事务是不能在这个间隙插入记录的,这样可以防止幻读。 

3、事务隔离级别为串行化时,读写数据都会锁住整张表 

4、隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。 

三、mysql中的drop,truncate和delete的区别 

delete语句: 

1,delete是DML,执行delete操作时,每次从表中删除一行,并且同时将该行的删除操作记录在redo和undo表空间中以便进行回滚(rollback)和重做操作, 但要注意表空间要足够大,需要手动提交(commit)操作才能生效,可以通过rollback撤销操作。 

2,delete可根据条件删除表中满足条件的数据,如果不指定where子句,则删除表中所有数据 

3,delete操作不会减少表和索引所占的空间。

truncate语句: 

1,truncate是DDL,会隐式提交,所以不能回滚,不会触发触发器。

2,truncate会删除表中所有记录,不会记录日志,所以执行速度很快,但不能通过rollback撤销操作。 3,对于外键(foreignkey)约束引用的表,不能使用truncate table,而应使用不带where子句的delete语句。 

4,truncate不能用于参与了索引视图的表。 

5,truncate操作后,这个表和索引所占空间会恢复到初始大小。 

drop语句:

1,drop是DDL,会隐式提交,所以不能回滚,不会触发触发器。 

2,drop语句删除表结构以及所有数据,并且将表所占空间全部释放。 

3,drop语句将删除表的结构所依赖的约束,触发器,索引,依赖于该表的存储过程/函数将保留,但是变为invalid状态。

总结: 

1,在速度上,一般来说,drop > truncate > delete。 

2,在使用drop和truncate时一定要注意,虽然可以恢复,但很麻烦,需要慎用。 

3,如何和事务有关,或者想触发触发器,要用delete; 如果想保留表结构而删除所有数据,且和事务无关,可以用truncate; 如果想删除表结构和所有数据,是否表所占的所有空间,可以使用drop。

四、mysql数据库为什么用自增列作为主键?

1,写入自增列做主键,写入顺序是自增的,和B+数叶子节点分裂顺序一致

2,表不指定自增列作为主键,同时也没有可以被选为主键的唯一索引,InnoDB就会选择内置的rowid作为主键,写入顺序和rowid增长顺序一致。

3,如果使用非自增长主键,由于每次插入主键的值近似随机,因此每次新记录都要被现有索引页得中间某个索引。

此时mysql不得不为了将新记录插入到合适位置而移动数据,甚至目标页面可能已经被回显到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这就增加了很多开销,同时频繁得移动,分页操作造成了大量得碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。 

五、SQL的执行顺序

一条sql语句的执行顺序为:

1,from

2,join

3,on

4,where

5,group by(开始使用select中的别名, 后面的语句都可以用到)

6,avg,sum等函数...

7,having (主要用来过滤group by之后的数据)

8,select

9,distinct

10,order by

11,limit

六、mysql权限管理

6.1 用户管理

一般工作中访问数据库肯定用的不是root账号,而是用的有一定权限的账号。比如普通用户可能只允许查看,开发用户运行创建和查看等权限。那么创建用户和用户授权有哪些方式呢?

方式一、可视化客户端操作

比如DBeaver:

image.png

方式二、SQL命令

# 当前mysql版本8.0
-- 创建用户,仅可连接没有其他权限,需要授权
CREATE USER xiongbo identified BY '123456'

-- 修改指定用户的密码
ALTER USER 'xiongbo'@'%' IDENTIFIED WITH mysql_native_password BY '111111'; 

-- 重命名用户
RENAME USER xiongbo TO xiongbo2

-- 用户授权 
GRANT ALL PRIVILEGES ON *.* TO xiongbo2

-- 查询权限
SHOW GRANTS FOR xiongbo2

-- 撤销权限
REVOKE ALL PRIVILEGES ON *.* FROM xiongbo2

-- 删除用户
DROP USER xiongbo2

七、MySql备份

1,客户端点击操作

省略。

2,命令行操作

# 导出 整个数据库的数据和结构
./mysqldump -u root -p database_name>sql_name.sql;

# 导出 指定数据库的某个表的数据和结构
./mysqldump -u root -p database_name t_user>sql_name2.sql;


# 导入
# source 文件路径
use database;
source /usr/local/mysql-8.0.26-macos11-arm64/bin/sqlname.sql;