1、数据库的三范式是什么
1NF:字段不可分;
2NF:有主键,非主键字段依赖主键;
3NF:非主键字段不能相互依赖;
关于第二范式:当存在多个主键的时候,才会发生不符合第二范式的情况,不存在对主键的部分依赖。
关于第三范式:满足第二范式前提,如果某一属性依赖于其他非主键属性,而其他非主键属性又依赖于主键,那么这个属性就是间接依赖于主键,这被称作传递依赖于主属性。
2、说说InnoDB与MyISAM的区别
- InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提
交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务; - InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败;
- InnoDB是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。
但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该
过大,因为主键太大,其他索引也都会很大。而MyISAM是非聚集索引,数据文件是分离的,
索引保存的是数据文件的指针。主键索引和辅助索引是独立的。 - InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用
一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快; - Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高;
3、数据库的事务
什么是事务?: 多条sql语句,要么全部成功,要么全部失败。
事务的特性:
数据库事务特性:原子性(Atomic)、一致性(Consistency)、隔离性(Isolation)、持久性
(Durabiliy)。简称ACID。
原子性:组成一个事务的多个数据库操作是一个不可分割的原子单元,只有所有操作都成功,
整个事务才会提交。任何一个操作失败,已经执行的任何操作都必须撤销,让数据库返回初始
状态。
一致性:事务操作成功后,数据库所处的状态和它的业务规则是一致的。即数据不会被破坏。
如A转账100元给B,不管操作是否成功,A和B的账户总额是不变的。
隔离性:在并发数据操作时,不同的事务拥有各自的数据空间,它们的操作不会对彼此产生干
扰
持久性:一旦事务提交成功,事务中的所有操作都必须持久化到数据库中。
4、SQL优化手段有哪些
1、查询语句中不要使用select *
2、尽量减少子查询,使用关联查询(left join,right join,inner join)替代
3、减少使用IN或者NOT IN ,使用exists,not exists或者关联查询语句替代
4、or 的查询尽量用 union或者union all 代替(在确认没有重复数据或者不用剔除重复数据时,
union all会更好)
5、应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
6、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表
扫描,如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有
null值,然后这样查询: select id from t where num=0
5、什么是内联接、左外联接、右外联接?
内联接(Inner Join):匹配2张表中相关联的记录。
左外联接(Left Outer Join):除了匹配2张表中相关联的记录外,还会匹配左表中剩余的记
录,右表中未匹配到的字段用NULL表示。
右外联接(Right Outer Join):除了匹配2张表中相关联的记录外,还会匹配右表中剩余的记
录,左表中未匹配到的字段用NULL表示。在判定左表和右表时,要根据表名出现在Outer Join
的左右位置关系。
6、并发事务带来哪些问题?
在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务(多个用户对
同一数据进行操作)。并发虽然是必须的,但可能会导致以下的问题。
脏读(Dirty read): 当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提
交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是
还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可
能是不正确的。
丢失修改(Lost to modify): 指在一个事务读取一个数据时,另外一个事务也访问了该数
据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务
内的修改结果就被丢失,因此称为丢失修改。 例如:事务1读取某表中的数据A=20,事务2也
读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。
不可重复读(Unrepeatableread): 指在一个事务内多次读同一数据。在这个事务还没有结
束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务
的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数
据是不一样的情况,因此称为不可重复读。
幻读(Phantom read): 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数
据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会
发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。
不可重复读和幻读区别
不可重复读的重点是修改比如多次读取一条记录发现其中某些列的值被修改,幻读的重点在于新增
或者删除比如多次读取一条记录发现记录增多或减少了。
7、数据库分片的两种常见方案:
客户端代理: 分片逻辑在应用端,封装在jar包中,通过修改或者封装JDBC层来实现。 当当网
的 Sharding-JDBC 、阿里的TDDL是两种比较常用的实现。
中间件代理: 在应用和数据中间加了一个代理层。分片逻辑统一维护在中间件服务中。 我们现
在谈的 Mycat 、360的Atlas、网易的DDB等等都是这种架构的实现。
详细内容可以参考: MySQL大表优化方案: https://segmentfault.com/a/1190000006158186
666