一、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:
方式二、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;