参考
以下是对上面两篇文章的小结:
常见的数据库分库方法:
水平切分
以某个字段为依据(例如uid),按照一定规则(例如取模),将一个库(表)上的数据拆分到多个库(表)上,以降低单库(表)大小,达到提升性能的目的的方法。
各库(表)的特点:
- 每个库(表)的结构都一样;
- 每个库(表)的数据都不一样,没有交集;
- 所有库(表)的并集是全量数据;
业务场景:
用户中心,数据量大,通过uid分库后,通过uname路由不到库?
解决方案:
1. 扫全库法:遍历所有库
* 对所有的库进行搜索,匹配查询的uname,效率低;
2. 索引表法:数据库中记录uname->uid的映射关系
* 先创建一个索引表,存储uname->uid的对应关系;
* 在每次通过uname查询时,先在索引表里查询到uname对应的uid;
* 拿到uid后再进行查询;(多个一步查询,效率线性下降)
3. 缓存映射法:缓存中记录uname->uid的映射关系
* 在缓存中存储uname->uid的关系;
* 在每次通过uname查询时,先在缓存里查询到uname对应的uid;
* 如果缓存中没有对应的uid,则遍历所有的库(表),获取到对应的数据,并将uname->uid对应关系存储进缓存中;(多了一次缓存查询)
4. uname生成uid
* 通过uname生成uid;(算法设计困难,存在uid重复的问题)
5. uname基因融入uid
* 根据分库的多少,决定基因的位数;
* 将全局唯一id和基因位数拼接成一个完整的uid;
* 通过uname生成的基因,直接取模定位到库;
垂直拆分
垂直拆分是指,将一个属性较多,一行数据较大的表,将不同的属性拆分到不同的表中,以降低单库(表)大小,达到提升性能的目的的方法。
各库(表)的特点:
- 每个库(表)的结构都不一样;
- 一般来说,每个库(表)的属性至少有一列交集,一般是主键;
- 所有库(表)的并集是全量数据;
垂直拆分的依据:
- 将长度较短,访问频率较高的属性尽量放在一个表里,这个表暂且称为主表 ;
- 将字段较长,访问频率较低的属性尽量放在一个表里,这个表暂且称为扩展表 ;
为什么要这么这么拆?
- 数据库有自己的内存buffer,会将磁盘上的数据load到内存buffer里;
- 内存buffer缓存数据是以row为单位的;
- 在内存有限的情况下,在数据库内存buffer里缓存短row,就能缓存更多的数据;
- 在数据库内存buffer里缓存访问频率高的row,就能提升缓存命中率,减少磁盘的访问;