⾯试⼋股⽂-MySQL数据库MySQL数据库
MySQL常⽤数据类型
char: 存放定长⽂本,如 ⾝份证号
varchar: 存放⼩型变长⽂本,如 家庭住址
text: 存放⼤型变长⽂本,如 新闻内容
tinyint: 存放较⼩的整数,bool值
int: 存放较⼤的整数,如记录项的id
datetime: 存放⽇期时间,如⽤户注册时间
enum: 存放枚举值,如男,⼥
char和varchar的区别?
char是定长的,不⾜的位数会⽤空格补全
varchar是变长的,存取速度⽐char慢⼀些
varchar和text的区别?
text只能建⽴前缀索引,text不能有默认值,指定text的长度是没有作⽤的
⼀条SQL语句是如何执⾏的?
SQL查询语句的执⾏过程:
⾸先通过 连接器 管理客户端连接,验证客户端权限
之后 分析器 进⾏语法分析,判断查询的SQL字段是否存在
然后 优化器 计算 不同索引⽅案的成本,选择成本最低的⽅案作为执⾏计划
最后执⾏器操作存储引擎提供的读写接⼝,返回结果给客户端
如果是SQL更新语句,还要再把修改记录到 redo log 和 binlog
什么是MVCC?
MVCC,多版本并发控制,只适⽤于 读提交 和 可重复读 两种隔离级别,
每⼀条记录都有⾃⼰的版本链,不同的事务 可以并发访问 相同记录
采⽤MVCC,读的时候不会加锁,所以读写不冲突,极⼤地提升了系统的并发性能
什么是ReadView?
⼀致性视图,它可以⽤来读取 记录的MVCC版本链 中的历史版本
在 读提交 下, 每⼀次select都会⽣成⼀个ReadView, 可以读到已提交事务修改的数据
在 可重复读 下, 只在第⼀次select时⽣成⼀个ReadView, 所以能保证重复读
快照读和当前读
快照读: 读到的是记录的历史版本,不⽤加锁
普通的select语句就是快照读
当前读: 读到的是记录的最新版本,会加锁
select … lock in share mode (加S锁)
select … for update (加X锁)
insert,update,delete (加X锁)
什么是事务?
事务是⼀种机制,它要保证⼀组数据库操作要么全部成功,要么全部失败
事务的四⼤特性(ACID)
原⼦性(Atomicity): 事务是⼀个不可分割的整体,所包含的操作要么全做,要么⼀个也不做
⼀致性(Consistency): 事务 开始前 和 结束后,数据的总量是不变的
隔离性(Isolation): 多个事务并发执⾏时,彼此之间互不⼲扰
持久性(Durability): 事务⼀旦提交,所有的修改都会在磁盘中保存下来.
特效软件:photofunia四⼤特性中,有了原⼦性,隔离性 才能 保证⼀致性
MySQL怎么保证原⼦性?
利⽤Innodb引擎的undo log(回滚⽇志),它记录了回滚⼀个操作必需的内容
⽐如,当你update⼀条数据的时候,就需要这条记录的原始值,回滚的时候,把这条记录再update为原始值
MySQL怎么保证持久性?
保证持久性,其实很简单,只⽤把该事务在内存中修改的全部页⾯刷新到磁盘就可以了,但是,这些页⾯可能并不相邻,需要进⾏很多随机IO,对于传统的机械硬盘就会特别慢,所以,为了提升效率,设计MySQL的⼤叔就引⼊了redo log,它只⽤来保存事务对数据页所做的修改,redo log⽂件是追加写,顺序IO速度很快. 在系统空闲时, MySQL会⾃动根据redo log的内容更新磁盘上的数据页
MySQL怎么保证隔离性?
MySQL提供了四种隔离级别,隔离级别越⾼的,并发度越低,
这四种隔离级别在修改时都会对记录⾏加X锁,不会发⽣脏写现象,都保证了最基本的隔离性
读未提交 会读取到未提交事务修改的最新记录,隔离性最差,并发性最好
读提交 和 可重复读 读取记录时会⽣成ReadView,在记录的MVCC版本链中到未被 其它事务修改的原始记录,隔离性和并发性都不错
pgsql和mysql的关系串⾏化,每次select读取记录都会上S锁,会读取最新的记录,隔离性最好
我们可以根据需要选择不同的隔离级别
事务的并发可能导致哪些问题?
脏写: ⼀个事务 修改了 另⼀个未提交事务 修改的数据
脏读: ⼀个事务 读到了 另⼀个未提交事务 修改的数据
不可重复读: ⼀个事务多次⽤相同语句读取记录时, 后读取的值 与 之前的值 不⼀样
幻读: ⼀个事务多次⽤相同语句读取记录时, 后读取时读到了之前没有读到的记录
四种事务隔离级别
读未提交 (read uncommitted): 隔离级别最低,⼀个事务还未提交时,它做的变更就能被别的事务看到.
读提交 (read committed): ⼀个事务提交后,它做的变更才能被别的事务看到. 解决了脏读
怎么解决脏读的呢? 每次读都会⽣成⼀个ReadView,会顺着记录的MVCC版本链去读第⼀个已提交事务的历史版本可重复读 (repeatable read): ⼀个事务执⾏过程中读取的数据,总是和这个事务第⼀次读取的数据相同. 解决了不可重复读怎么解决不可重复读的呢? 只有第⼀次读才会⽣成⼀个ReadView,这样就算后续有事务提交也不会影响查询结果
如果第⼆次读之前执⾏过⼀条范围写命令,⽽这个范围刚好包含了另⼀事务插⼊的新记录,幻读仍然可能发⽣,因为写命令是当前读,可以在当前读的范围内加S锁来避免插⼊数据,从⽽避免幻读
串⾏化 (serializable): 隔离级别最⾼,使⽤普通的select语句会对整个搜索范围加S锁,这样就阻⽌了其它事务对此范围进⾏写操作,解决了幻读
⽆论是哪种隔离级别,写同⼀⾏记录时都会加X锁,所以都能解决脏写问题,
设置四种事务隔离级别是“舍弃 ⼀部分隔离性 换取 更好的并发性能”,所以严格地说,只有串⾏化才满⾜绝对的隔离性
InnoDB和MyISAM的区别
InnoDB⽀持事务,外键,⾏锁和表锁
MyISAM不⽀持事务,外键和⾏锁,只⽀持表锁,不适⽤于并发量⼤的业务,但是它查询速度⽐InnoDB快
哪些数据结构可以⽤于查询?
哈希表: 可以精确查询,但不⽀持范围查询
⼆叉查树(BST): 存在时间复杂度退化为O(n)的情况
平衡⼆叉查树(AVL): 解决了BST时间复杂度退化问题,但由于树⾼,查询的IO次数多,也不适合存⼤规模数据
多路平衡查树(B树): ⼀个结点可存储多个元素,减少了IO次数,但范围查询需要中序遍历,效率低
B树的变体(B+树): ⾮叶⼦结点不存储数据,因此能存放更多的⽬录项记录,需要的IO次数更少,且⽀持范围查询
什么是索引?
索引是⼀种能在数据表中完成⾼效搜索的数据结构,⼀般基于B+树实现,
索引的优点是可以加快查询速度,缺点是更新数据时效率低,因为要同时更新索引
MySQL的索引类型
聚簇索引: 以主键值的⼤⼩作为记录的排序规则,在叶⼦结点中存储的记录包含表中所有的列
⼆级索引: 以索引列的⼤⼩作为记录的排序规则,在叶⼦结点中存储的记录是 索引列+主键列
聚簇索引查询的过程
每个索引都对应⼀棵B+树,所有的⽤户数据都存在B+树的叶⼦结点,通过索引查记录时,从B+树的根结点开始⼀层层向下搜索,直到到该记录所在的数据页,
然后在页⽬录中通过⼆分法查中间槽对应的主键值,快速定位到记录所在的组,再在组内依次遍历直到到主键值等于搜索值的记录
为什么索引要⽤B+树?
B+树⽀持范围查询,因为它⽤双向链表连接所有叶结点,顺序遍历即可
人力资源和社会保障部
B+树IO次数更少,因为它的⾮叶结点不存放数据,所以能存放更多⽬录项记录,结构更加矮胖,可以
很快定位到数据页
B+树查询效率稳定,因为它所有数据都在叶结点,每个数据的查询效率基本相同
索引越多越好吗?
不,索引要尽可能少
⽐如我们向表中插⼊⼀个记录,实际上是先将记录插⼊到聚簇索引对应的B+树,再插⼊到每个⼆级索引对应的B+树,
索引越多的话B+树越多,插⼊时要进⾏的IO操作就越多,会严重影响性能
另⼀⽅⾯,MySQL优化器会耗费更多的时间计算不同索引⽅案成本
什么样的字段适合创建索引?
经常需要⽤作条件查询,分组,排序的字段
经常⽤作表连接的字段
⾮空,没有⼤量的重复值 (否则可能要执⾏多次回表操作)
索引什么情况下会失效?
以%开头的like语句
查询语句的条件类型与数据表字段的类型不匹配
使⽤联合索引时,不满⾜最左匹配原则
MySQL慢查询怎么解决?
慢查询通常是缺少索引,或者 索引不合理 导致的
在mysql的配置⽂件中,开启慢查询⽇志,查⼀下是哪些语句执⾏的这么慢,
适当加⼀些必要的,合理的索引, 删除冗余的索引
为什么主键要使⽤⾃增的整数?
因为MySQL会⾃动为主键添加索引,⽽索引要实现⾼效检索和范围查询,需要保证索引的有序性
如果不使⽤⾃增的整数,每次插⼊数据还要把它放到合适的位置上,还有可能造成页分裂,
shart
⽽主键采⽤⾃增的整数时,插⼊记录时往后追加即可,效率更⾼
什么是内连接,外连接?
内连接: 只会把驱动表和被驱动表中都有的记录添加到结果集
外连接: 在被驱动表中没有到驱动表中的记录,也仍然以NULL值添加到结果集
驱动表和被驱动表
当连接查询没有where条件时,左连接查询时,前⾯的表是驱动表,后⾯的表是被驱动表,右连接查询时相反,内连接查询时,哪张表的数据较少,哪张表就是驱动表
当连接查询有where条件时,带where条件的表是驱动表,否则是被驱动表
on 和 where的区别?
它们都是⽤于添加过滤条件
on⼦句⼀般只⽤于内外连接的条件,其它情况下都应该使⽤where
having 和 where的区别?
where语句指定⾏的条件,having语句指定组的条件
where语句在GROUP BY语句之前;having语句在GROUP BY语句之后
where语句不能使⽤聚合函数,⽽having可以
表级锁⾏级锁
从 锁的粒度 来分,主要有 表级锁 和 ⾏级锁
表级锁: ⼀般是存储引擎不⽀持⾏锁时才使⽤
⾏级锁: 当SQL语句对记录进⾏读写操作时,可以选择对记录加⾏锁
正经记录锁: 最常⽤的⾏级锁,仅仅把⼀条记录锁上
gap锁: 会锁住 该记录与上⼀记录的间隙
next-key锁: 会锁住 该记录 和 该记录与上⼀记录的间隙
加S型next-key锁: select * from table where id>1 and id<=6 lock in share mode;mysql怎么读英语
加X型next-key锁: select * from table where id>1 and id<=6 lock for update;
插⼊意向锁: 表明有事务想在某个间隙插⼊新记录,但现在处于等待状态
共享锁独占锁意向锁
从 锁的模式 来分,主要有 共享锁,独占锁,意向锁
共享锁 (Share): 简称S锁,⾏级或表级,其它事务只能读,不能写
哪些语句会⾃动加S锁: ⽆
怎么⼿动加S锁:
对读取的记录⾏加S锁: select … lock in share mode;
对整张表加S锁: lock tables t read;
独占锁 (Exclusive): 简称X锁,⾏级或表级,其它事务既不能读,也不能写
哪些语句会⾃动加X锁: update,delete,insert
怎么⼿动加X锁:
对读取的记录⾏加X锁: select … for update;
对整张表加X锁: lock tables t write;
共享意向锁: 简称IS锁,是表级锁,仅⽤来判断表中是否有记录上了S锁
独占意向锁: 简称IX锁,是表级锁,仅⽤来判断表中是否有记录上了X锁
⾃增锁: ⽤于给auto_increment字段递增赋值,只作⽤于单个插⼊语句,插⼊完成后⽴刻释放
注: 普通的select语句不加任何锁,根据 隔离级别的不同,会读取记录的最新版本 或 MVCC版本链记录悲观锁乐观锁
stringbuilder去重
从 锁的风格 来分,分为 悲观锁 和 乐观锁

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。