【架构实战】数据库分库分表实战
一、为什么需要分库分表当数据量超过单机数据库的承载能力时分库分表成为必然选择单库数据量过亿查询性能急剧下降单表数据量过大索引效率降低DML操作变慢连接数耗尽数据库连接成为稀缺资源存储空间不足单机的磁盘容量有上限二、分库分表策略1. 垂直拆分按业务将表或库拆分开原来用户库用户表、订单表、支付表 拆分后 用户库用户表 订单库订单表 支付库支付表2. 水平拆分按数据规则将表拆分-- 按用户ID取模分表users_0:WHEREuser_id%40users_1:WHEREuser_id%41users_2:WHEREuser_id%42users_3:WHEREuser_id%433. 常见的分片键选择分片键适用场景注意事项用户ID电商、社交查询需带用户ID时间日志、订单冷数据归档方便地区区域性业务跨区查询困难哈希均衡分布查询复杂度高三、分库分表中间件ShardingSphere# application.ymlspring:shardingsphere:datasource:ds0:url:jdbc:mysql://localhost:3306/db0driver-class-name:com.mysql.cj.jdbc.Driverds1:url:jdbc:mysql://localhost:3306/db1driver-class-name:com.mysql.cj.jdbc.Driverrules:sharding:tables:t_order:actual-data-nodes:ds$-{0..1}.t_order_$-{0..1}table-strategy:standard:sharding-column:order_idsharding-algorithm-name:order_inlineMyCat四、实战代码Java SDK 使用示例// ShardingSphere JDBCConfigurationpublicclassDataSourceConfig{BeanpublicDataSourcedataSource(){MapdataSourceMapnewHashMap();dataSourceMap.put(ds0,createDataSource(db0));dataSourceMap.put(ds1,createDataSource(db1));ShardingRuleConfigurationconfignewShardingRuleConfiguration();config.getTables().add(createTableRule());returnDataSourceFactory.createDataSource(dataSourceMap,config);}}// 分片键获取publicLonggetShardingKey(Orderorder){returnorder.getUserId()%4;}五、跨库查询解决方案1. 禁止跨库JOIN// 业务层面解决先查用户再查订单UseruseruserMapper.selectById(userId);ListordersorderMapper.selectByUserId(userId);2. 异构表-- 在订单库冗余用户信息CREATETABLEt_order(order_idBIGINT,user_idBIGINT,user_nameVARCHAR(50),-- 冗余字段amountDECIMAL(10,2),created_atDATETIME);3. ES搜索引擎MySQL(分库分表) → 数据同步 → Elasticsearch ↓ 复杂查询由ES处理六、分布式ID生成分库分表后需要分布式ID// Snowflake算法publicclassSnowflakeIdGenerator{privatefinallongtwepoch1288834974657L;privatefinallongworkerIdBits5L;privatefinallongdatacenterIdBits5L;publicsynchronizedlongnextId(){longtimestamptimeGen();longid((timestamp-twepoch)22)|(datacenterId17)|(workerId12)|sequence;returnid;}}// 使用SnowflakeIdGeneratoridGeneratornewSnowflakeIdGenerator(1,1);longorderIdidGenerator.nextId();七、常见问题与解决方案Q1扩容时如何迁移数据方案1双写新老库同时写方案2定时任务迁移方案3使用一致性哈希减少迁移量Q2如何保证分页查询-- 反例深分页问题SELECT*FROMt_orderORDERBYidLIMIT1000000,10-- 正例游标分页SELECT*FROMt_orderWHEREid1000000ORDERBYidLIMIT10Q3分布式事务如何处理使用 Seata AT 模式或 TCC 模式八、总结分库分表是系统扩展的必经之路但增加了系统复杂度✅ 突破单机性能瓶颈✅ 提高系统可用性❌ 跨库查询困难❌ 运维复杂度增加思考题你的系统中数据量最大的是哪张表有没有考虑过分库分表个人观点仅供参考
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2450194.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!