1.常见的关系型数据库和非关系型数据库?
关系型数据库(需要表结构):sqllite、db2、oracle、access、SQLserver、MySQL
非关系型数据库(key-value结构存储,没有表结构):mongodb、redis、memcache
2.常见的数据库引擎比较?
1>.InnoDB支持事物,而MyISAM不支持事物 2>.InnoDB支持行级锁,而MyISAM支持表级锁 3>.InnoDB支持MVCC, 而MyISAM不支持 4>.InnoDB支持外键,而MyISAM不支持 5>.InnoDB不支持全文索引,而MyISAM支持。
3.数据库设计三大范式
第一范式:1NF是对属性的原子性约束,要求属性具有原子性,不可再分解;
第二范式:2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性;
第三范式:3NF是对字段冗余性的约束,即任何字段不能由其他字段派生出来,它要求字段没有冗余
范式化设计优缺点:
优点:可以尽量得减少数据冗余,使得更新快,体积小
缺点:对于查询需要多个表进行关联,减少写得效率增加读得效率,更难进行索引优化
4.事务,以及mysql如何支持事务?
'什么是事务' 事务由一个或多个sql语句组成一个整体; 在事务中的操作,要么都执行修改,要么都不执行, 只有在该事务中所有的语句都执行成功才会将修改加入到数据库中,否则回滚到上一步。 'Mysql实现事务' InnoDB支持事务,MyISAM不支持 # 启动事务: # start transaction; # update from account set money=money-100 where name='a'; # update from account set money=money+100 where name='b'; # commit; 'start transaction 手动开启事务,commit 手动关闭事务'
5.数据库五大约束
主键约束 primary key 默认值约束 default 唯一约束 unique 非空约束 not null 外键约束 foreign key
6.mysql索引种类
'主键索引(单列)': primary key 加速查找+约束:不能重复、不能为空 '普通索引(单列)': 加速查找 '唯一索引(单列)': unique 加速查找+约束:不能重复 '联合索引(多列)': 查询时根据多列进行查询(最左前缀) '联合唯一索引(多列)': 遵循最左前缀规则(命中索引) # 其他词语 1、索引合并:利用多个单列索引查询 2、覆盖索引:在索引表中就能将想要的数据查询到
7.索引什么情况下遵循最左前缀原则
联合索引A,B,C,D
只要出现A,不管顺序如何都会使用索引;只要没有A,就不会使用索引;
具体用法参考博客:链接1
8.创建索引但是无法命中索引的8种情况
#使用'like ‘%xx’' select * from tb1 where name like '%cn'; #使用'函数' select * from tb1 where reverse(name)='zgc'; #使用'or' select * from tb1 where nid=1 or email='zgc@gmial.com'; 特别的:当or条件中有未建立索引的列才失效,一下会走索引 # select * from tb1 where nid=1 or name='zgc'; # select * from tb1 where nid=1 or email='zgc@gmial.com' and name='zgc'; #'类型不一致' 如果列是字符串类型,传入条件是必须用引号引起来,不然则可能会无法命中 select * from tb1 where name=666; #含有'!= ' select * from tb1 where name != 'zgc'; 特别的:如果是主键,还是会走索引 # select * from tb1 where nid != 123; #含有'>' select * from tb1 where name > 'zgc'; 特别的:如果是主键或者索引是整数类型,则还是会走索引 # select * from tb1 where nid > 123; # select * from tb1 where name > 123; #含有'order by' select email from tb1 order by name desc; 当根据索引排序时,选择的映射如果不是索引,则不走索引 特别的:如果对主键排序,则还是走索引: # select * from tb1 order by nid desc; #组合索引最左前缀 如果组合索引为:(name,email) name and email #使用索引 name #使用索引 email #不使用索引
9.开启慢日志查询
'可以通过修改配置文件开启' slow_query_log=ON #是否开启慢日志记录 long_query_time=2 #时间限制,超过此时间,则记录 slow_query_log_file=/usr/slow.log #日志文件 long_queries_not_using_indexes=ON #是否记录使用索引的搜索
1、创建数据表时把固定长度的放在前面 2、将固定数据放入内存:choice字段(django中用到,1,2,3对应相应内容) 3、char不可变,varchar可变 4、联合索引遵循最左前缀(从最左侧开始检索) 5、避免使用 select * 6、读写分离: #利用数据库的主从分离:主,用于删除、修改、更新;从,用于查 #实现:两台服务器同步数据 原生SQL:select * from db.tb ORM:model.User.object.all().using('default') 路由:d b router 7、分库 # 当数据库中的表太多,将某些表分到不同数据库,例如:1W张表时 # 代价:连表查询跨数据库,代码变多 8、分表 # 水平分表:将某些列拆分到另一张表,例如:博客+博客详情 # 垂直分表:将某些历史信息,分到另外一张表中,例如:支付宝账单 9、加缓存 # 利用redis、memcache(常用数据放到缓存里,提高取数据速度) # 缓存不够可能会造成雪崩现象 10、如果只想获取一条数据 select * from tb where name = 'zgc' limit 1;
11.1000w条数据,使用limit offset 分页时,为什么越往后翻越慢?如何解决?
# 例如: #limit 100000,20; 从第十万条开始往后取二十条, #limit 20 offset 100000; limit后面是取20条数据,offset后面是从第10W条数据开始读 因为当一个数据库表过于庞大,LIMIT offset, length中的offset值过大,则SQL查询语句会非常缓慢 -------------------------------------------------------------------------- '优化一' 先查看主键,再分页: select * from tb where id in (select id from tb where limit 10 offset 30) -------------------------------------------------------------------------- '优化二' 记录当前页,数据、ID、最大值和最小值(用于where查询) 在翻页时,根据条件进行筛选,筛选完毕后,再根据 limit offset 查询 select * from(select * from tb where id > 2222) as B limit 10 offset 0; 如果用户自己修改页码,也可能导致变慢,此时可以对 url 页码进行加密,例如rest framework -------------------------------------------------------------------------- '优化三' 可以按照当前业务需求,看是否可以设置只允许看前200页; 一般情况下,没人会咔咔看个几十上百页的;
12.什么是索引合并?
索引合并,让一条sql可以使用多个索引。对这些索引取交集,并集,或者先取交集再取并集。从而减少从数据表中取数据的次数,提高查询效率。
13.数据库读写分离?
利用数据库主从分离,主用来进行数据库的增添,修改,和删除操作(INSERT、UPDATE、DELETE)。从用来进行查找操作(SELECT)
两台数据库来同步数据,从而减轻服务器压力
14.数据路分库分表操作?
# 1、分库 当数据库中的表太多,将某些表分到不同数据库,例如:1W张表时 代价:连表查询跨数据库,代码变多 # 2、分表 水平分表:将某些列拆分到另一张表,例如:博客+博客详情 垂直分表:将某些历史信息,分到另外一张表中,例如:支付宝账单
15.如何设计一个高并发的系统?
数据库优化,sql语句优化,索引优化
使用缓存,减少数据库IO操作
分布式数据库,分布式缓存(减轻服务器的压力)
服务器的负载均衡
16.锁的优化策略?
① 读写分离
② 分段加锁
③ 减少锁持有的时间
④ 多个线程尽量以相同的顺序去获取资源
等等,这些都不是绝对原则,都要根据情况,比如不能将锁的粒度过于细化,不然可能会出现线程的加锁和释放次数过多,反而效率不如一次加一把大锁。
17.索引的底层实现和原理?
B+树。在所有的叶子结点中增加了指向下一个叶子节点的指针
18.实践中如何优化mysql?
sql语句及索引的优化
表结构优化
系统配置优化
硬件优化
19. 简单描述mysql中,索引,主键,唯一索引,联合索引的区别,对数据库的性能有什么影响
(1)索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。
(2)普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。
(3)普通索引允许被索引的数据列包含重复的值,如果能确定某个数据列只包含彼此各不相同的值,在为这个数据索引创建索引的时候就应该用关键字UNIQE把它定义为一个唯一所以,唯一索引可以保证数据记录的唯一性。
(4)主键,一种特殊的唯一索引,在一张表中只能定义一个主键索引,逐渐用于唯一标识一条记录,是用关键字PRIMARY KEY来创建。
(5)索引可以覆盖多个数据列,如像INDEX索引,这就是联合索引。
(6)索引可以极大的提高数据的查询速度,但是会降低插入删除更新表的速度,因为在执行这些写操作时,还要操作索引文件。
20.什么是锁?
数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。
加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。
基本锁类型:锁包括行级锁和表级锁