任意数据长度的 bitset,以及按位读
526 2023-04-03 04:24:42
比较常见的包括:cobar、TDDL、sharding-jdbc、atlas、mycat
cobar:阿里b2b团队开发和开源的,属于proxy层方案。不支持读写分离、存储过程、跨库join和分页等操作。
TDDL:淘宝团队开发的,属于client层方案。不支持join、多表查询等语法,就是基本的crud语法是ok,但是支持读写分离。使用不多,需要依赖淘宝的diamond配置管理系统。
atals:360开源的,属于proxy层方案,以前是有一些公司在用的,但是确实有一个很大的问题就是社区不维护。
sharding-jdbc:当当开源,属于client层方案。支持分库分表、读写分离、分布式id生成、柔性事务(最大努力送达型事务、TCC事务)。社区比较活跃
mycat:基于cobar改造,属于proxy层方案,支持的功能非常完善,社区活跃。
优劣分析:sharding-jdbc和mycat
sharding-jdbc这种client层方案的优点在于不用部署,运维成本低,但是如果遇到升级啥的需要各个系统都需要升级再发布
mycat这种proxy层方案的方案对于各个项目是透明的,属于一个中间件,但是运维成本高。
我可以对id取模3 分3个库,然后取模4 分四个表。
11%3 = 2
11%4 = 3
第二个数据库第三个表。
按时间
2022年一个数据库 2023年一个数据库
hash方法:可以平均分担请求压力。扩容比较难
按时间扩容比较方便,缺点是大部分的请求都访问最新的数据库。
可以从一开始就考虑到扩容,搞4个数据库,每个库4个表,实际上数据库服务器就一个,里面放4个数据库。
对于DBA来说,扩容的时候直接开新的数据库服务器,然后把数据库导入过去就好了。我们修改一下数据库连接配置就好,原来的数据库hash规则不需要修改。
系统修改数据对原来的表和分库分表中间件一起操作,同时增加一个服务负责把原来的表数据迁移到分库分表上去。一般表规范是有updatetime的,迁移的时候比较一下这个updatetime,免得旧数据覆盖新数据。迁移完成后去比较原来库和新的分库分表数据是否一样,程序跑个几天。
我们知道redis主从复制的时候,后台生成一个rdb快照。然后这个时刻之后的操作都是对数据的副本进行的。rdb完成之后副本数据覆盖原始数据。
我们也可以这样,不过代码实现起来有点复杂。
创建一张零时表,查询的时候操作原来的表的临时表去查询。零时表会多一个isdelete 字段,如果本来就是逻辑删除的,那不管。
插入数据的时候插入进临时表。
修改数据的时候,查出原来数据,然后修改要修改的字段,然后插入临时表。
删除数据的时候,如果是逻辑删除,和修改其实一样,如果是真删除,那把数据查出来,并且在isdelete上打个标签表示这个数据删除了。
查询的时候从原来表查了之后,要判断是否在临时表被删除。而且要把零时表的数据也一起处理,相同id的数据使用临时表的数据,如果分页查询可能出现一点问题。
原来表数据全部拷贝到分库分表数据后,停机把零时表数据更新到分库分表上。
如果插入数据,直接在新库上插入
如果修改数据,把数据从旧数据删除,插入新数据库。
如果删除数据,对新库和旧库一起删
查询数据,从旧库查询,查询不到从新库查询。旧库有的话,插入新库,然后返回。
分页查询:我要查第5页数据,旧数据库前5页,新数据库每个表前5页,数据到内存后合在一起再找第5页
方案2,方案3不可取,原来的增删改查代码是大量的,修改逻辑工作量极大。
1.数据库主键自增
弄一张表,主键自增,负责生成主键。麻烦,性能低。
2.时间戳
用时间做主键,可能会重复。A数据库和B数据库时间一样的时候生成的ID一样。
3.uuid
id虽然唯一,可是没有顺序。
4.snowflake雪花算法
64位二进制,第一位0 ,41位表示时间,5位机房id,5位机器id,12位表示当前这一毫秒生成了第几个id。
把64位二进制转10进制就是雪花算法id了。只能32个机房 32个机器。不然会报错。或者可以对机器码取模,这样的话就会有重复的id。