1、数据库三范式
- 第一范式:列不可再分
- 第二范式:行可以唯一区分,主键约束
- 第三范式:表的非主属性不能依赖与其他表的非主属性 外键约束 且三大范式是一级一级依赖的,第二范式建立在第一范式上,第三范式建立第一第二范式上
2、事务的四大特性
- 原子性:要么执行,要么不执行
- 隔离性:所有操作全部执行完以前,其它会话不能看到过程
- 一致性:事务前后,数据总额一致
- 持久性:一旦事务提交,对数据的改变就是永久的
3、什么样的字段适合建索引?
- 唯一
- 不为空
- 经常被查询的字段
4、如何定位并优化你的索引?
- 根据慢日志定位慢查询sql
执行
慢查询配置
show variables like "%query%"
慢查询数量
show status like "%slow_queries%"
打开慢查询日志,设置超时时间为1s,想要永久生效得到配置文件中配置,否则数据库重启后,这些配置失效
set global show_query_log = on;
set global long_query_time = 1;
- 使用explain等工具分析sql
- 修改sql或者尽量让sql走索引
建索引的几大原则
1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
2.=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式。
3.尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录。
4.索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’)。
5.尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。
5、并发及事务的隔离机制
事物并发会导致三种问题:
- 脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
- 不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致
- 幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读
小结:脏读是因为回滚,不可重复读是因为更新,幻读是因为插入。 读未提交会引起脏读,所以用读已提交来解决。可重复读,实际上是锁住对应行的数据,这样就可以解决不可重复读问题。串行化实际上是锁住整个表,以解决幻读。
6、数据库连接池的作用
- 维护一定数量的连接,减少创建连接的时间
- 更快的响应时间
7、MySQL 高并发环境解决方案
MySQL 高并发环境解决方案 分库 分表 分布式 增加二级缓存
需求分析:互联网单位 每天大量数据读取,写入,并发性高。
现有解决方式:
- 水平分库分表,由单点分布到多点数据库中,从而降低单点数据库压力
- 集群方案:解决DB宕机带来的单点DB不能访问问题
- 读写分离策略:极大限度提高了应用中Read数据的速度和并发量。无法解决高写入压力