目录
1.数据库设计的几个范式
2.mysql索引有哪几种?索引算法有哪些?
3.mysql数据库锁有哪些?
4.数据库连接池的实现原理
5.Mybatis的实现原理
6.Mybatis与Hibernate的区别?
7.#{}和${}区别
8.statement和parparestatement区别
9.mysql的复制原理及流程
10.mysql中myisam和innodb的区别
11.Mysql全库备份的dump文件,如何只恢复一个库或一张表?
12.如何保证redis和mysql的数据双写一致性?
14.超大value打满网卡问题如何规避?
15.Redis缓存集群的监控.
16.Redis缓存集群的扩容.
17.Redis的集群原理和选举机制
18.reids中哨兵节点是什么
19.关系型数据库和非关系型数据库的区别
20.使用Mongodb的好处
21.Mongodb中namespace是什么
1NF:原子性.
2NF:实体属性完全依赖于主关键字.
3NF:传递依赖,防止冗余.
其实在实际开发中有时会为了性能进行反范式化,特地的冗余几个字段,关于范式做到尽量遵守即可.
mysql的索引有Normal(普通索引)和Unique(唯一索引),Full Text(全文索引),主键索引和组合索引.
索引算法有BTree和Hash.
BTree适合在大部分情况下使用,Hash不适合在有过多哈希冲突的情况下使用,Hash算法的索引大部分情况下查询速度都会很快.
hash算法的索引在对范围查询以及使用了Like等字段的查询中无能为力.
表级锁,锁住整张表,开销小,加锁快,并发较低,容易锁冲突.
行级锁,开销大,加锁慢,粒度细,并发高.
页面锁.开销并发粒度等均介于表和行锁之间.
数据库连接池相当于一个缓冲池,不必频繁创建连接和销毁连接,这样就节省了很资源开销.
一次性创建好多个jdbc连接,然后将这些jdbc连接用集合存储起来,用的时候可以直接从集合里取.
Mybatis作为一套优秀的ORM框架,主要为我们做2件事:
①自动创建jdbc连接并执行sql.
②利用反射打通类和sql之间的转换.
Mybatis的主要成员有Configuration,Executor,TypeHandler,ParameterHandler,ResultSetHandler.然后每个成员干嘛的要说得上来
Mybatis需要手动写sql,Hibernate不需要自己写sql
Mybatis如果需要在多种数据库使用,需要编写不同的sql,增加很多工作量,Hibernate跨数据库无需自己写sql.
#{}可以防止sql注入,${}不能.
parparestatement是预执行语句,可以使用占位符,是预编译的.
只执行一次性存取的时候,使用statement.
如果要进行批量存取,使用parparestatement性能更高.
三个线程以及之间的关联.
主:binlog线程,记录下所有改变数据库数据的语句,放入master的binlog中.
从:io线程,在执行了start slave后,io线程负责拉取master上的binlog内容,放进自己的relay log中.
从:sql执行线程,负责执行relay log中的内容.
myisam支持全文索引,但不支持事务,Innodb正好相反.
myisam支持表锁,innodb支持行锁.
两种引擎使用select count(*) myisam更快,因为它内部维护了一个计数器,可以直接调取.
可以使用参数 --one-database 指定恢复哪个库
mysql -uroot -p xxx --one-database < dump.sql
如果要指定恢复哪张表,需要用正则进行过滤抽出对应的表结构,然后再用管道把相应的数据提取出来并导入:
sed -e'/./{H;$!d;}' -e 'x;/CREATE TABLE `t`/!d;q' dump.sql
grep'INSERT INTO `t`' dump.sql
读取数据优先从redis缓存中读,如果没有缓存,则进入数据库去读,读完将缓存写入redis.
写数据时,先将redis中的缓存进行删除,然后数据库执行写操作,然后再次删除redis中的缓存,值得注意的是这次删除缓存前应当先让线程休眠一定的时间,比如500ms,因为数据库的写操作需要时间.
另外缓存需要设置一定的过期时间,以避免缓存更新失败后,缓存中一直是脏数据.
13.热点Key导致服务端缓存的某台机器负载过高怎么办?
当热点key出现时,会有大量请求同时去读取缓存,此时若缓存已失效,这些请求会进入DB,从DB读完后会回来更新缓存,此时会面临大量线程同时更新同个key的情况,导致缓存服务器压力过高,因此在更新缓存的代码块需要加锁,如果是分布式环境则需要加分布式锁,以此来保证更新缓存的操作仅有一个线程可以执行.
除了上面提到的问题外,热点key还会导致单台服务器的读压力过大,可以通过以下两种方案解决:
①在客户端加缓存,读数据优先从客户端的缓存中去读,如果客户端没有该热点key的数据,再去服务端读.
②对热点key进行hash分散,将分散后的子key存放到其他redis上,value与热点key对应value一致,读取的时候可以通过hash运算读取其他redis上的子key,以此来减少单台缓存服务器的压力.
可以将超大value的数据拆分成几个Key-value,用mutiGet取值,降低IO消耗.
可以使用CacheCloud工具进行监控,https://github.com/sohutv/cachecloud
先配置并启动需要扩容的节点,然后通过redis-trib.rb工具把新增的节点加入集群中,然后再通过redis-trib.rb工具来迁移数据.
集群中所有节点彼此互联(Ping-pong机制).
节点fail是通过集群中超过半数的节点检测失效时才生效.
客户端可以与任意一个节点相连,不需要通过proxy层.
redis-cluster把集群中所有节点映射到0~16383个slot上,当需要向集群中插入key-value时,会先对Key进行运算,然后放置到对应的slot上,会几平均的放置到各个节点.
哨兵节点主要是为了解决主从复制模式下节点出现故障时的问题.哨兵节点负责监控节点状态,当主节点挂掉后会自动转移到从节点,主节点挂了后会从从节点中选举出主节点.
关系型数据库存储的数据天然是表格型的,存储在数据库的行和列中,数据库表可以彼此关联协作存储数据.非关系型数据库存储的数据类型不适合用行和列进行存储,而是大块组合在一起.比如存储key-value形式的数据,或者文档等.
关系型数据库在性能上一般不如非关系型数据库.
高性能,高可用,易扩展,可分片,查询功能强大.
在collection中,数据库名+集合名就是namespace,也就是一个集合的完整名.