数据库读写分离详解( 三 )


垂直拆分策略我们现在知道了我们急需分库分表的操作了,但是,我们该通过什么策略去将我们的数据库进行垂直拆分呢?我这里建议是,我们最好按照我们的系统业务来进行垂直拆分,垂直拆分就是将数据库竖着拆分,根据业务的不同将原有数据库中的那些表分到不同的数据库节点中 。
不同的数据库对应着不同的业务,比如,我们将用户相关的表放在了用户数据库节点里,订单相关的表放在了订单数据库节点上,关注相关的表放在了关注数据库节点里 。这样还有个好处就是,我们的关注数据量庞大到了几亿的量级如果影响到了数据的操作,但是并不影响用户的登录和浏览、搜索下单操作 。起到了很好的数据隔离的作用 。
案例展示以前,我们用户表、关注表、订单表都在同一个库里面,也就是在我们的主库中,后来经过拆分后,它们分别被拆到用户库、关注库、订单库等 。

数据库读写分离详解

文章插图
 
垂直拆分这种方案,其实在我们中等规模的互联网公司里都会首先使用到,但是,随着数据的增加这种单库里面的表还是会面临瓶颈的,看上面我讲的我们关注表数据,虽然拆到了关注库里面,但是关注表数据都已经好几亿了,仍是会影响我们这块业务的 。所以说,垂直拆分只能暂缓我们的问题,但是,像那种单表数据骤增的情况还是需要采取另一种方法的,那就是我们下面要说的水平拆分 。
怎么做数据库水平拆分水平拆分的核心思想是,将单一数据表数据按照我们约定的某种规则进行拆分到多个数据库和数据表中,我们的关注点是在表数据本身上 。
有哪些常用拆分规则
1,按照表中某一字段取哈希值进行拆分,例如我们的用户表,如果将其拆分为16个库,每个库64张表,那么,我们就将UID哈希,为什么哈希大家知道吧,前面文章分析了hashmap,应该都懂吧 。然后将哈希值对16取余,得到哪一个数据库,然后对64取余就知道哪个表 。这种规则比较适用于这种实体类的表 。
数据库读写分离详解

文章插图
 
2,按照某一个表字段的区间做拆分,这里最常使用就是日期字段了,比如我们关注表的创建时间,比如我们要查某个月的关注数据,就可以将月份数据放进对应月份表中,这样我们就可以根据创建时间来定位到我们数据存储在哪张表里面,然后在根据我们的查询条件进行相应的查询 。
数据库读写分离详解

文章插图
 
数据库进行分库分表后,我们代码怎么去访问,也会带来一定的麻烦,之前只用访问一个库就行了,现在数据都被分到其他库里面了,这个和我们前面的读写分离差不多,可以去看看()
现在数据库的分库分表解决了我们数据库瓶颈、并发写入和读取等问题,也解决了我们扩展和数据隔离的问题,但是引入了分库分表,也会给我们带来一些问题:
怎么解决分库分表带来的问题1,分区键
分区键就是我们用来进行分库分表的字段,我们每次查询的时候都必须得带上这个字段,才能找到数据所在的库和表,我们将上面用户数据按照uid进行分库分表的,那如果现在我想按照昵称来查询怎么办呢?
  • 这里我们一般建议,另外建立一张UID和昵称的映射表 。
  • 然后通过昵称查询出UID
  • 在通过UID就可以进行定位到库和表了
2,多表JOIN
我们现在的单表数据都被分到多库多表中了,然后有些程序员之前写的那些连表join 操作怎么办,跨库了,就不能使用JOIN了 。所以这块我们需要将他们放到我们业务代码中进行处理了,其实代码中处理我们会更清晰一些
3,统计类
和上面JOIN类似,类似统计的count()就不能使用了,然后这块我们建议是,通过另外建一张表活着放到redis缓存里面,最后再合并就行了,也很简单 。
最后建议,我们在我们的业务中不要一开始就去分库分表,在没必要的情况下不要去分库分表;如果真的要分库分表,在公司资源充足下,建议一次性分到位,会给你很爽的感觉,比如分16个库64张表,资源紧缺的话,我们就根据业务来分,后续会将一些更过的方案 。
总结,今天我们针对大并发的写入造成的我们数据库的瓶颈以及性能低下问题,我们就引入了分库分表的方案,主要分为数据库垂直拆分和水平拆分,也提到了拆分后给我们带来了哪些挑战并且给出相应的解决方案 。


推荐阅读