一、分库分表方式
1. 单库单表
最常见的设计,一个表user_t放在数据库中,所有用户信息都存储在这个表,所有用户信息都能再user_t中查到;
2. 单库多表
业务数据的增加,user_t中的用户信息会越来越多,当达到一定量的时候,数据库查询会变慢,影响性能。mysql数据库还有另一个重要的问题,就是当给表增加一列时,会出现锁表,所有的读写都将等待。此时,就可以根据某种规则将user_t水平拆分成多张表(user_01、user_02.....),这些拆分的表数据合起来刚好是一份完整的数据。
3. 多库多表
时间增加,业务数据的再增加,单个数据库的存储空间有限,服务器已经无法支撑大量的查询服务。此时,可以将数据库进行水平拆分。
分库分表原则:设计表时确立好规则,此表时按什么规则进行分库分表。例如,用户注册,需要往用户表中添加一条记录时,要确定此条信息是保存在哪个表(如user_01),那么,在查询用户信息时,也要去对应的user_01表中查询。这就需要按照某一规则进行。
二、分库分表产生的问题以及注意事项
1.分库分表的维度问题
例如:某一用户购买一些商品,需要将购买的商品记录记录下来,如果按照用户的维度分,同一用户的购买信息记在同一表中,查询起来比较容易,但是商品购买记录信息则分布在不同表中,按商品查则比价麻烦;反之,按商品把同一商品购买记录记在同一表中,但用户信息则分布在不用表中,查购买人的交易记录就比较麻烦。
常见解决方式:
a. 通过扫描表的方式解决,基本不可能,效率太低;
b. 记录两份数据,一份按用户维度记,一份按商品维度记;
c. 通过搜索引擎解决,但如果实时性很高,要解决实时性问题。
2.联合查询的问题
基本不可能,因为关联的表可能不在同一数据库中。
3.避免跨库事物
避免在同一事物中更新不同数据库的表数据,操作复杂,效率受影响。
4.尽量把同一组数据放在同一个数据库
尽量把同一用户的交易记录放在同一库中,避免有关联的数据库挂了,影响用户数据的查询,其实就是避免一个数据库数据对另一个数据库数据的依赖;
5.一主多备
在实际应用中,大多都是读大于写,mysql也提供了读写分离机制,所有的写操作都必须对应到master机器上,读操作可以在master和slave机器上,master和slave结构完全一样,一个master可以对应多个slave,一个slave下还可以挂多个slave,通过此种方式可以有效的提高数据库集群的QPS;
所有的写操作都是现在master上进行,然后再同步到slave上,所以,从master同步到slave时会有延迟,当系统繁忙时,这种情况会出现的更严重,slave数量的增加也会是这个问题更加严重。
由此可以看出,master是集群的瓶颈,当写操作过多,会严重影响到master的稳定性,如果master挂掉,整个集群都将不能工作。所以,1.当读压力大的时候,就可以考虑增加slave的分式解决,当slave的机器达到一定数量时,就要考虑分库了;
2.当写压力大的时候,就必须进行分库操作了。
三、使用mysql为什么要分库分表
可以说,用mysql的地方,只要数据量大,就会遇到分库分表的问题。很多人要问,mysql处理不了大表吗?不是的,mysql可以处理大表,数据量大了对于文件系统也会产生很多问题;另外数据量大了调整表结构基本不可能。所以大项目使用mysql都会面临分库分表。
那么,分库分表多少合适呢?
经测试,在单表1000万条记录的情况下,读写性能都是比较好的,再留点buffer,如果是number类型的数据保持在800万,如果是varchar型的保持在500万。