面试基础-数据库篇
1.sql分页查询
mysql分页查询最简单,它使用的是limit关键字。关键字之后需要两个参数m,n,最终mysql语句的样式:
select * from table_name
where
…
group by
…
having
…
order by
…
limit -m -n;
--m的含义表示从数据的第m条开始查询(mysql中第一条数据m=0)
--n的含义是从第m条数据开始往后查询n条数据
2.主键和索引的区别
1)数据库设计器中创建三种索引:唯一索引、主键索引和聚集索引。而,主键只是其中的一种;
2)一个表中可以有多个唯一性索引,但只能有一个主键。
3)主键列不允许空值,而唯一性索引列允许空值。
4)当创建或更改表时可通过定义 PRIMARY KEY 约束来创建主键。
3.聚集索引和非聚集索引
聚集索引,也叫聚簇索引。在MYsql中等价于主键索引,数据行的物理顺序与列值的顺序相同,如果我们查询id比较靠后的数据,那么这行数据的地址在磁盘中的物理地址也会比较靠后。而且由于物理排列方式与聚集索引的顺序相同,所以也就只能建立一个聚集索引了。
非聚集索引:除了聚集索引以外的索引都是非聚集索引,只是人们想细分一下非聚集索引,分成普通索引,唯一索引,全文索引。如果非要把非聚集索引类比成现实生活中的东西,那么非聚集索引就像新华字典的偏旁字典,他结构顺序与实际存放顺序不一定一致。
联合索引:复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持a|a,b|a,b,c3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效。
4.b树和b+树区别,二者的适用场景
B 树(平衡多路查找树),找数据(先读取到内存、后查找)的过程中,可以减少磁盘 IO 的次数,从而提升查找速度。
B+树索引是B+树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引。有时候需要查询某个范围内的数据,由于 B+ 树的叶子节点是一个有序链表,只需在叶子节点上遍历即可。
5.什么是外键,外键的优点
外键 ( foreign key ) 是用于建立和加强两个表数据之间的链接的一列或多列。通过将保存表中主键值的一列或多列添加到另一个表中,可创建两个表之间的链接。这个列就成为第二个表的外键。
例如:档案表中会有学号,姓名。(学号为主键)
成绩单有(这里尽量简化):学期号,学号,平均分数(学期号,学号两个同时为主键,学号同时为外键)
为了保证成绩单上的数据有效,所以要求录入学号时,必需保证档案中有这个学号,否则就不能录入。 从而保证了成绩单上的成绩数据的引用完整,否则将会是垃圾数据。
6.怎么优化sql查询
1、升级硬件;
2、根据查询条件,建立索引,优引、优化访问方式,限制结果集的数据量;
3、扩大服务器的内存;
4、增加服务器CPU个数
避免全局扫描,避免在 where 子句中对字段进行 null 值判断,in 和 not in 也要慎用,SELECT子句中避免使用‘*’:
尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。
7.事务的ACID性质
事务:可以理解为Mysql的操作语句
原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)
原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
8.事务的持久性是怎么实现的
当数据修改时,InnoDB除了修改Buffer Pool中的数据,还会在redo log 记录这次操作。
redo log是物理日志,记录的是数据库中物理页的情况 。
redo log包括两部分:一是内存中的日志缓冲(redo log buffer),该部分日志是易失性的;二是磁盘上的重做日志文件(redo log file),该部分日志是持久的。
日志预写:对数据的变更,先写操作日志,然后再更新数据,需要保证在数据更新前,你的操作日志一定要先写到磁盘上。
9.数据库写入数据的具体过程
1)在buffer cache中找到需要的数据块,如果没有找到,则从数据文件中载入buffer cache中;
2)事务修改buffer cache的数据块,该数据被标识为“脏数据”,并被写入log buffer中;
3)事务提交,LGWR进程将log buffer中的“脏数据”写入redo log file中;
4)当发生checkpoint,CKPT进程更新所有数据文件的文件头中的信息,DBWn进程则负责将Buffer Cache中的脏数据写入到数据文件中。
10.对锁的了解 乐观锁 悲观锁
锁的作用:在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。
悲观并发控制:如果一个事务执行的操作都某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。
乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。使用版本号时,可以在数据初始化时指定一个版本号,每次对数据的更新操作都对版本号执行+1操作。
11.解释行锁、表锁、页锁
表级:引擎 MyISAM , 理解为锁住整个表,可以同时读,写不行
行级:引擎 INNODB , 单独的一行记录加锁
不同的存储引擎支持不同的锁机制。
- 表锁:开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低
- 行锁:开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高
- 表锁更适用于以查询为主,只有少量按索引条件更新数据的应用;行锁更适用于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用
12.死锁的原因及解决办法
是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁。例如:如果线程A锁住了记录1并等待记录2,而线程B锁住了记录2并等待记录1,这样两个线程就发生了死锁现象。
产生死锁的四个必要条件:
- 互斥条件:一个资源每次只能被一个进程使用。
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
- 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
- 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
下列方法有助于最大限度地降低死锁:
- 如果所有并发事务按同一顺序访问对象,则发生死锁的可能性会降低。
- 避免编写包含用户交互的事务;
- 保持事务在一个批处理中,可以最小化事务的网络通信往返量,减少完成事务可能的延迟并释放锁;
- 确定事务是否能在更低的隔离级别上运行。执行提交读允许事务读取另一个事务已读取(未修改)的数据,而不必等待第一个事务完成。
13.脏读和幻读的本质区别
1)脏读:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问 这个数据,然后使用了这个数据。读脏数据是读到的数据是已经被撤销修改的数据,所以是脏数据。
2)不可重复读:一个事务范围内多次查询,却返回了不同的数据值。这是由于在查询间隔中,数据被另一个事务修改并提交了。
3)幻读:幻读是指当事务不是独立执行时发生的一种现象
例如,目前公司员工工资为1000的有10人
- 事务1读取所有的员工工资为1000的员工。
- 这时事务2向employee表插入了一条员工纪录,工资也为1000
- 事务1再次读取所有工资为1000的员工,共读取了11条记录。
解决方法:如果在操作事务完成数据处理之前,任何其它事务都不可以添加新数据。
14.四个隔离级别
- 设置隔离级别:set tx_isolation = 'READ-UNCOMMITTED'
- 查看隔离级别:select @@tx_isolation
Read Uncommitted -- 读未提交
Read Committed -- 读已提交
Repeatable Read -- 可重读
Serializable -- 可串行化