1.数据库id自增解决方案
数据库集群的情况下,如果自动增长id产生重复的话,如何解决?
1.采用UUID形式设置为id。
缺点:无规则,没有顺序。如果是Oracle数据库,推荐使用。
2.设置步长。缺点:不利于后期服务器的扩容。
在数据库集群环境下,默认自增方式存在问题,因为都是从1开始自增,可能会存在重复,应该设置每台节点自增步长不同。
查询自增的步长
SHOW VARIABLES LIKE 'auto_increment%'
修改自增的步长
SET @@auto_increment_increment=10;
修改起始值
SET @@auto_increment_offset=5;
假设有两台mysql数据库服务器
节点①自增 1 3 5 7 9 11 ….
节点②自增 2 4 6 8 10 12 ….
缺点:在最开始设置好了每台节点自增方式步长后,确定好了mysql集群数量后,无法扩展新的mysql,不然生成步长的规则可能会发生变化。
假设有三台MySql服务器集群,三台服务器分别的起始值和步长为多少?
起始值为 1 2 3.,步长为3.
其它方案:使用Redis、雪花算法。
使用Redis:是单线程,如果是多线程的情况下,会产生线程阻塞,不推荐。如果是量小,不是特别多的情况下,可以使用redis和雪花算法。
2. 数据库分表分库策略
1. 在数据库分表分库原则中,遵循二个设计理论 垂直拆分、水平拆分。垂直拆分是把不同的表拆到不同的数据库中,而水平拆分是把同一个表拆到不同的数据库中。
垂直拆分:就是根据不同的业务进行拆分的,拆分成不同的数据库,比如会员数据库、订单数据库、支付数据库、消息数据库等,垂直拆分在大型电商项目中使用比较常见。
优点:拆分后业务清晰,拆分规则明确,系统之间整合或扩展更加容易。
缺点:部分业务表无法join,跨数据库查询比较繁琐(必须通过接口形式通讯(http+json))、会产生分布式事务的问题,提高了系统的复杂度。举栗子:不可能出现,在订单服务中,订单服务直接连接会员服务的数据库这种情况。
水平拆分:把同一张表中的数据拆分到不同的数据库中进行存储、或者把一张表拆分成 n 多张小表。
相对于垂直拆分,水平拆分不是将表的数据做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中 的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中,主要有分表,分库两种模式 该方式提高了系统的稳定性跟负载能力,但是跨库join性能较差。
使用MyCat实现水平分片策略
MyCat支持10种分片策略
1、求模算法
2、分片枚举
3、范围约定
4、日期指定
5、固定分片hash算法
6、通配取模
7、ASCII码求模通配
8、编程指定
9、字符串拆分hash解析
详细:http://www.mycat.io/document/mycat-definitive-guide.pdf
使用MyCat实现水平分片策略
分片枚举算法就是根据不同的枚举(常量),进行分类存储的。举栗子:有些业务需要按照省份或区县来做保存,而全国的省份区县固定的,这类业务使用这一规则。
环境搭建:
1.案例步骤: 创建数据库userdb_1 、 userdb_2、userdb_3
2.修改partition-hash-int.txt 规则 sahgnhai=0、beijing=1、shenzhen=2,定义枚举(地区) 每个地区指定的数据库存放位置。
根据地区进行分库 上海数据库、北京数据库 、深圳数据库。
数据库集群产生的问题
1.数据库关联查询的问题(水平拆分导致的)
2.数据同步的问题
3.id自增的问题