ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

EF Core 分库分表实战:ShardingCore 按月分表与自动建表上手指南

EF Core 分库分表实战:ShardingCore 按月分表与自动建表上手指南 EF Core 分库分表实战ShardingCore 按月分表与自动建表上手指南【免费下载链接】sharding-corehigh performance lightweight solution for efcore sharding table and sharding database support read-write-separation .一款ef-core下高性能、轻量级针对分表分库读写分离的解决方案具有零依赖、零学习成本、零业务代码入侵项目地址: https://gitcode.com/gh_mirrors/sha/sharding-core订单表单表数据上千万之后按创建时间翻页会明显变慢索引也救不回来全表扫描。ShardingCore 是给 EF Core 做的轻量分库分表方案核心思路是把一张逻辑表拆成多张物理表或多套数据源查询时由路由把 SQL 落到正确的表上业务代码几乎不用动。它本身只依赖 EF Core 关系层按 EF Core 版本号分版本发布EF Core 6 到 10 各有一档对应版本。快速定位维度说明一句话定位EF Core 之上的分库分表中间件以 IQueryable 扩展方式接管查询路由最适合谁已用 EF Core、单表或单库扛不住数据量需要水平拆分的 .NET 团队上手成本改一个 DbContext、写一个路由类、加一段启动配置业务层基本不改它支持分表、分库、两者叠加以及读写分离。分表规则完全自定义默认内置按时间、按取模等几套路由可直接继承。概念速览上手只需要分清下面几个词其余都能靠继承默认类省掉。左侧多个库实例对应分库右侧多张月份表对应分表虚拟表 / 物理表虚拟表是程序里的实体类物理表是数据库里真实的表。比如实体Order对应Order_202101、Order_202102。表后缀Tail物理表名里跟在虚拟表名后面的部分例如202101。路由就是靠它算出要查哪张表。虚拟路由IVirtualTableRoute连接虚拟表和物理表的桥梁告诉框架「这个分片值该去哪张表」。它和业务逻辑强相关所以要你自己实现框架提供高级抽象类帮你省掉一半代码。数据源DataSource一次数据库连接的抽象分库场景下按路由把查询分发到不同的库。实战走读给订单表按月分表下面用 SQL Server 演示最小可用配置跑通「按月拆表 启动自动补表」。先装两个包一个是 ShardingCore 本身一个是你的数据库驱动# 基础包版本要和你 EF Core 版本对应 PM Install-Package ShardingCore # SQL Server 驱动 PM Install-Package Microsoft.EntityFrameworkCore.SqlServer把 DbContext 换成继承AbstractShardingDbContext并实现IShardingTableDbContext实体照常ToTable(nameof(Order))这里RouteTail属性留空实现即可。再写路由。按月分表继承AbstractSimpleShardingMonthKeyDateTimeVirtualTableRouteOrder指定分片字段和起始时间开启自动建表public class OrderVirtualTableRoute : AbstractSimpleShardingMonthKeyDateTimeVirtualTableRouteOrder { // 起始时间用固定值别用 DateTime.Now重启会变 public override DateTime GetBeginTime() new DateTime(2021, 1, 1); // 指定分片字段框架据此算出月份表名 public override void Configure(EntityMetadataTableBuilderOrder builder) builder.ShardingProperty(o o.CreationTime); // 开启按时间自动建表 public override bool AutoCreateTableByTime() true; }最后注册。AddDefaultDataSource的第二个参数换成你自己的连接字符串UseShardingQuery和UseShardingTransaction的委托参数不要改services.AddShardingDbContextMyDbContext() .UseRouteConfig(op op.AddShardingTableRouteOrderVirtualTableRoute()) .UseConfig(op { op.UseShardingQuery((connStr, b) b.UseSqlServer(connStr)); op.UseShardingTransaction((conn, b) b.UseSqlServer(conn)); op.AddDefaultDataSource(Guid.NewGuid().ToString(n), Data Sourcelocalhost;Initial CatalogEFCoreShardingTableDB;Integrated SecurityTrue;); }).AddShardingCore();启动管道里加一行app.ApplicationServices.UseAutoTryCompensateTable();它会检查缺失的月份表并补建。之后SetOrder()的查询、增删改都会自动落到对应月份表上返回的仍是完整的IQueryableJoin、GroupBy、Count都能跨表聚合。MySQL 5.7、约 755 万行下的基准对比有索引的查询分表后耗时与单表基本持平性能方面项目里有实测数据。SQL Server 2012、773 万行、走索引的场景分表查询 10 次均值 1.567ms非分表 1.512ms单次开销约 0.005ms损耗占比 3%相当于原生 EF Core 的 97%。开启路由表达式缓存后单个表后缀的路由编译从 0.14ms 降到 0.013ms约 10 倍。进阶能力精选自动建表按月分表最怕跨月那一刻表还没建。把路由的AutoCreateTableByTime返回true再配合启动时的UseAutoTryCompensateTable框架会在启动时补建缺失表要 24 小时无人值守可再挂一个定时任务调用IShardingTableCreator。参考仓库里samples/Samples.AutoByDate.SqlServer/按天自动建表的完整示例。读写分离在注册链上追加.AddReadWriteSeparation(...)用字典把「数据源名」映射到一组只读连接串策略可选ReadStrategyEnum.Loop轮询或随机。由于从库有复制延迟刚写入的数据可能读不到可把某个 DbContext 的ReadWriteSeparation设为false或调用ReadWriteSeparationWriteOnly()强制走写连接。高性能分页跨表分页本质是先查 N 张表再流式聚合Skip越大越慢。实现IPaginationConfigurationT接口声明顺序字段和匹配规则路由里重写CreatePaginationConfiguration返回它就能让带顺序条件的分页只查必要的表再配合ConfigReverseShardingPage把最后几页翻成正向首页。用ToShardingPageAsync(pageIndex, pageSize)调用。避坑与选型建议分片键必须进查询路由靠分片字段的值定位表。查询条件里带上CreationTime的范围框架只查命中的月份表不带的话会扫全部表性能退化成多表之和。事务边界默认只支持单库事务SaveChanges内多表操作在同一库上没问题。跨库写做不到原子提交需要自己在应用层做补偿或最终一致性。小心跨表 Join两张分表 Join 且 Join 条件无法收敛到具体表时会生成笛卡尔积连接数可能爆炸这类查询要改写或加路由提示Hint Route。如果你的业务只是单库单表、数据量还在千万级以内、又强依赖跨库 Join 或分布式事务那分库分表带来的复杂度可能不划算ShardingCore 就不适合先考虑索引和归档。资源导航分表最小示例samples/Sample.SqlServerShardingTable/分库最小示例samples/Sample.SqlServerShardingDataSource/自动建表示例samples/Samples.AutoByDate.SqlServer/性能基准测试benchmarks/ShardingCoreBenchmark/路由抽象与默认路由源码src/ShardingCore/Core/VirtualRoutes/中文 README 与 API 清单README.mdShardingCore 把 EF Core 的分库分表收敛到「改 DbContext 写路由 注册配置」三件事跨表聚合、分页、读写分离都有现成抽象。建议从按月分表的最小示例起步先在测试库跑通自动建表再逐步叠加分页和读写分离。【免费下载链接】sharding-corehigh performance lightweight solution for efcore sharding table and sharding database support read-write-separation .一款ef-core下高性能、轻量级针对分表分库读写分离的解决方案具有零依赖、零学习成本、零业务代码入侵项目地址: https://gitcode.com/gh_mirrors/sha/sharding-core创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进