1. 使用mysql索引都有哪些原则?索引什么数据结构? B+tree 和 B tree 什么区别?
1、 对于查询频率高的字段创建索引;
2、 对排序、分组、联合查询频率高的字段创建索引;
3、 索引的数目不宜太多
原因: a、每创建一个索引都会占用相应的物理控件;
b、过多的索引会导致insert、update、delete语句的执行效率降低; 4、若在实际中,需要将多个列设置索引时,可以采用多列索引
如:某个表(假设表名为Student),存在多个字段(StudentNo, StudentName, Sex, Address, Phone,BirthDate),其中需要对StudentNo,StudentName字段进行查询,对Sex字段进行分组,对BirthDate 字段进行排序,此时可以创建多列索引index index_name (StudentNo, StudentName, Sex, BirthDate);#index_name为索
创建多列索引,需要遵循BTree类型,即第一列使用时,才启用索引。
在上面的创建语句中,只有mysql语句在使用到StudentNo字段时,索引才会被启用。
如: select * from Student where StudentNo = 1000; #使用到了StudentNo字段,索引被启用。以使用explain检测索引是否被启用如:explain select * from Student where StudentNo = 1000;
5、选择唯一性索引
唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。例如,学生表中学号是具有唯 一性的字
而降低查询速度。
6、尽量使用数据量少的索引
如果索引的值很长,那么查询的速度会受到影响。例如,对一个CHAR(100)类型的字段进行全文检索 需要的时间肯定要比对CHAR(10)类型的字段需要的时间要多。
7、尽量使用前缀来索引
如果索引字段的值很长,最好使用值的前缀来索引。例如,TEXT和BLOG类型的字段,进行全文检 索会很浪费时间。如果只检索字段的前面的若干个字符,这样可以提高检索速度。
8、删除不再使用或者很少使用的索引.
表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再需要。数据库管理 员应当定期找出这些索引,将它们删除,从而减少索引对更新操作的影响B+ tree树索引, B tree,散列
2. Mysql有哪些存储引擎?请详细列举其区别?
InnoDB: 事务型存储引擎, 并且有较高的并发读取频率 MEMORY: 存储引擎,存放在内存中,数据量小, 速度快Merge:
ARCHIVE: 归档, 有很好的压缩机制
3. 设计高并发系统数据库层面该如何设计? 数据库锁有哪些类型?如何实现?
1. 分库分表: 同样量的数据平均存储在不同数据库相同表(或不同表)中,减轻单表压力,如果还是很大,就可以每个库在分多张表,根据hash取值或者其他逻辑判断将数据存储在哪张表中
2. 读写分离: 数据库原本就有主从数据库之分,查询在从服务器,增删改在主服务器,
3. 归档和操作表区分: 建一张归档表,将历史数据放入,需要操作的表数据单独存储
4. 索引啊之类的创建,对于数据量很大,百万级别以上的单表,如果增删改操作不频繁的话, 可以创建bitMap索
1. 共享锁:要等第一个人操作完,释放锁,才能操作
2. 更新锁:解决死锁,别人可以读,但不能操作
3. 排他锁:读写都被禁用
4. 意向锁(xlock): 对表中部分数据加锁,查询时,可以跳过
5. 计划锁: 操作时,别的表连接不了这张表
各个大厂面试合集需要的+关注后台私信“1”获取
4. 数据库事务有哪些?
原子性: 所有操作要么全部成功,要么全部失败
一致性: 例如转账,一个事务执行前和执行后必须一致隔离性: 防止脏读, 重复读问题
持久性: 永久性提交数据库
5. Oracle常用函数有哪些? Concat: 字符串拼接, 或者 || MConcat: 字符串拼接, 或者 || Instr: 指定字符串位置Length: 长度
Trim: 去空格 Lower: 小写 Upper:大写 Nvl: 判断空 Replace: 替换 Substr: 截取 Floor: 向下取整 To_number:
To_char:
To_date:
Decode: 判断函数等等
6. Sql中哪些情况可能不会走索引?
1. 查询谓词没有使用索引的主要边界,换句话说就是select *,可能会导致不走索引
2. 单键值的b树索引列上存在null值,导致COUNT(*)不能走索引。索引列存在空值
3. 索引列上有函数运算,导致不走索引
4. 隐式类型转换导致不走索引。
5. 表的数据库小或者需要选择大部分数据,不走索引
6. !=或者<>(不等于),可能导致不走索引
7. 表字段的属性导致不走索引,字符型的索引列会导致优化器认为需要扫描索引大部分数据且聚簇因子很大,最 终导致弃用索引扫描而改用全表扫描方式,
8. 使用like, in 等, 可能导致不走索引
7. 讲讲分布式唯一ID?
确定ID存储用64位,1个64位二进制1是这样的00000000.....1100 ........... 0101,切割64位,某段二进制表示成1个约
束条件,前41位为毫秒时间,后紧接9位为IP,IP之后为自增的二进制,记录当前面位数相同情况下是第几个id,如现在有10台机器,这个id生成器生成id极限是同台机器1ms内生成2的14次方个ID。
分布式唯一ID = 时间戳 << 41位, int类型服务器编号 << 10,序列自增sequence。每个时间戳内只能生成固定数量如(10万)个自增号,达到最大值则同步等待下个时间戳,自增从0开始。将毫秒数放在最高位,保证生成的ID是趋势递增的,每个业务线、每个机房、每个机器生成的ID都是不同的。如39bit毫秒数|4bit业务线|2bit机房|预
务线标识。
64bit分布式ID(42bit毫秒+5bit机器ID+12位自增)等
8. NIO和IO的区别?
第一点,NIO少了1次从内核空间到用户空间的拷贝。
ByteBuffer.allocateDirect()分配的内存使用的是本机内存而不是Java堆上的内存,和网络或者磁盘交互都在操作系统的内核空间中发生。allocateDirect()的区别在于这块内存不由java堆管理, 但仍然在同一用户进程内。
第二点,NIO以块处理数据,IO以流处理数据
第三点,非阻塞,NIO1个线程可以管理多个输入输出通道
9. Redis内存数据上升到一定大小会执行数据淘汰策略,Redis提供了哪6种数据淘汰策略?
LRU:从已设置过期时间的数据集合中挑选最近最少使用的数据淘汰random:从已设置过期时间的数据中挑选任意数据淘汰
ttl:从已设置过期时间的数据集合中挑选将要过期的数据淘汰。notenvision:禁止驱逐数据
如mysql中有2千万数据,redis只存储20万的热门数据。LRU或者TTL都满足热点数据读取较多,不太可能超时特点。
据,策略为每秒1次,为了主从复制速度及稳定,MS主从在同一局域网内;主从复制不要用图状结构,用单向链表更为稳定 M-S-S-S-S。。。。;redis过期采用懒汉+定期,懒汉即get/set时候检查key是否过期,过期则删除key,定期遍历每个DB,检查制定个数个key;结合服务器性能调节并发情况。
一致时,才会认为redis为有效的,不过仍然每次都要访问DB,只需要查询version版本字段即可。