简介

本框架旨在为EF Core提供Sharding(即读写分离分库分表)支持,不仅提供了一套强大的普通数据操作接口,并且降低了分表难度,支持按时间自动分表扩容,提供的操作接口简洁统一.

源码地址:EFCore.SHarding

引言

读写分离分库分表一直是数据库领域中的重难点,当数据规模达到单库极限的时候,就不得不考虑分表方案。EF Core作为.NET Core中最为主流的ORM,用起来十分方便快捷,但是官方并没有相应的Sharding支持,鄙人不才,经过一番摸索之后终于完成这个框架.

开始

准备

首先根据需要安装对应的Nuget包

包名 说明
EFCore.Sharding 必装包,3.x版本对应EF Core3.x,2.x版本对应EF Core2.x
EFCore.Sharding.MySql MySql支持
EFCore.Sharding.PostgreSql PostgreSql支持
EFCore.Sharding.SQLite SQLite支持
EFCore.Sharding.SqlServer SqlServer支持
EFCore.Sharding.Oracle Oracle支持(暂不支持3.x)

配置

class Base_UnitTestShardingRule : ModShardingRule<Base_UnitTest>
{protected override string KeyField => "Id";protected override int Mod => 3;
}ShardingConfig.Init(config =>
{config.AddAbsDb(DatabaseType.SQLite).AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, "DataSource=db.db").AddPhysicDbGroup().AddPhysicTable<Base_UnitTest>("Base_UnitTest_0").AddPhysicTable<Base_UnitTest>("Base_UnitTest_1").AddPhysicTable<Base_UnitTest>("Base_UnitTest_2").SetShardingRule(new Base_UnitTestShardingRule());
});

上述代码中完成了Sharding配置

  • AddAbsDb是指添加抽象数据库,抽象数据库就是将多个分库看成同一个数据库来进行操作

  • AddPhysicDbGroup是指添加物理数据库组,在同一组物理数据库中,它们数据库类型相同,拥有的表相同,每个数据库拥有的数据是一致的(之间通过主主复制或主从复制进行数据同步)

  • AddPhysicTable是指添加物理数据表,传入的Base_UnitTest是抽象数据表(即将Base_UnitTest拆分为Base_UnitTest_0~2)

  • Base_UnitTestShardingRule是采用的分表规则,上述代码中采用的是哈希取模的分表方式

使用

配置完成,下面开始使用,使用方式非常简单,与平常使用基本一致
首先获取分片仓储接口IShardingRepository

IShardingRepository _db = DbFactory.GetRepository().ToSharding();

然后即可进行数据操作:

Base_UnitTest _newData  = new Base_UnitTest
{Id = Guid.NewGuid().ToString(),UserId = "Admin",UserName = "超级管理员",Age = 22
};
List<Base_UnitTest> _insertList = new List<Base_UnitTest>
{new Base_UnitTest{Id = Guid.NewGuid().ToString(),UserId = "Admin1",UserName = "超级管理员1",Age = 22},new Base_UnitTest{Id = Guid.NewGuid().ToString(),UserId = "Admin2",UserName = "超级管理员2",Age = 22}
};
//添加单条数据
_db.Insert(_newData);
//添加多条数据
_db.Insert(_insertList);
//清空表
_db.DeleteAll<Base_UnitTest>();
//删除单条数据
_db.Delete(_newData);
//删除多条数据
_db.Delete(_insertList);
//删除指定数据
_db.Delete<Base_UnitTest>(x => x.UserId == "Admin2");
//更新单条数据
_db.Update(_newData);
//更新多条数据
_db.Update(_insertList);
//更新单条数据指定属性
_db.UpdateAny(_newData, new List<string> { "UserName", "Age" });
//更新多条数据指定属性
_db.UpdateAny(_insertList, new List<string> { "UserName", "Age" });
//更新指定条件数据
_db.UpdateWhere<Base_UnitTest>(x => x.UserId == "Admin", x =>
{x.UserId = "Admin2";
});
//GetList获取表的所有数据
var list=_db.GetList<Base_UnitTest>();
//GetIQPagination获取分页后的数据
var list=_db.GetIShardingQueryable<Base_UnitTest>().GetPagination(pagination);
//Max
var max=_db.GetIShardingQueryable<Base_UnitTest>().Max(x => x.Age);
//Min
var min=_db.GetIShardingQueryable<Base_UnitTest>().Min(x => x.Age);
//Average
var min=_db.GetIShardingQueryable<Base_UnitTest>().Average(x => x.Age);
//Count
var min=_db.GetIShardingQueryable<Base_UnitTest>().Count();
//事务,使用方式与普通事务一致
bool succcess = _db.RunTransaction(() =>
{_db.Insert(_newData);var newData2 = _newData.DeepClone();_db.Insert(newData2);
}).Success;
Assert.AreEqual(succcess, false);

上述操作中表面上是操作Base_UnitTest表,实际上却在按照一定规则使用Base_UnitTest_0~2三张表,使分片对业务操作透明,极大提高开发效率
具体使用方式请参考单元测试源码:连接

按时间自动分表

上面的哈希取模的方式虽然简单,但是却十分不实用,因为当3张分表到达瓶颈时,将会面临扩容的问题,这种方式扩容需要进行大量的数据迁移,这无疑是十分麻烦的。因此需要一种方式能够系统自动建表扩容,并且无需人工干预,这就是按时间自动分表.

using Demo.Common;
using EFCore.Sharding;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;namespace Demo.AutoExpandByDate
{class Base_UnitTestShardingRule : AbsShardingRule<Base_UnitTest>{public override DateTime BuildDate(Base_UnitTest obj){return obj.CreateTime;}}class Program{/// <summary>/// 表都在同一个数据库中/// </summary>public static void OneGroup(){DateTime startTime = DateTime.Now.AddMinutes(-5);DateTime endTime = DateTime.MaxValue;//配置初始化ShardingConfig.Init(config =>{config.AddAbsDb(DatabaseType.SqlServer)//添加抽象数据库.AddPhysicDbGroup()//添加物理数据库组.AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, Config.ConString1)//添加物理数据库1.SetShardingRule(new Base_UnitTestShardingRule())//设置分表规则.AutoExpandByDate<Base_UnitTest>(//设置为按时间自动分表ExpandByDateMode.PerMinute,(startTime, endTime, ShardingConfig.DefaultDbGourpName));});var db = DbFactory.GetShardingRepository();while (true){db.Insert(new Base_UnitTest{Id = Guid.NewGuid().ToString(),Age = 1,UserName = Guid.NewGuid().ToString(),CreateTime = DateTime.Now});var count = db.GetIShardingQueryable<Base_UnitTest>().Count();Console.WriteLine($"当前数据量:{count}");Thread.Sleep(50);}}/// <summary>/// 表分布在两个数据库测试/// </summary>public static void TwoGroup(){DateTime startTime1 = DateTime.Now.AddMinutes(-5);DateTime endTime1 = DateTime.Now.AddMinutes(5);DateTime startTime2 = endTime1;DateTime endTime2 = DateTime.MaxValue;string group1 = "group1";string group2 = "group2";//配置初始化ShardingConfig.Init(config =>{config.AddAbsDb(DatabaseType.SqlServer)//添加抽象数据库.AddPhysicDbGroup(group1)//添加物理数据库组1.AddPhysicDbGroup(group2)//添加物理数据库组2.AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, Config.ConString1, group1)//添加物理数据库1.AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, Config.ConString2, group2)//添加物理数据库2.SetShardingRule(new Base_UnitTestShardingRule())//设置分表规则.AutoExpandByDate<Base_UnitTest>(//设置为按时间自动分表ExpandByDateMode.PerMinute,(startTime1, endTime1, group1),(startTime2, endTime2, group2));});List<Task> tasks = new List<Task>();for (int i = 0; i < 4; i++){tasks.Add(Task.Run(() =>{var db = DbFactory.GetShardingRepository();while (true){db.Insert(new Base_UnitTest{Id = Guid.NewGuid().ToString(),Age = 1,UserName = Guid.NewGuid().ToString(),CreateTime = DateTime.Now});var count = db.GetIShardingQueryable<Base_UnitTest>().Count();Console.WriteLine($"当前数据量:{count}");Thread.Sleep(50);}}));}Console.ReadLine();}static void Main(string[] args){OneGroup();Console.ReadLine();}}
}

上面Demo都在源码中

上面的代码实现了将Base_UnitTest表按照时间自动分表,每分钟创建一张表,实际使用中根据业务需求设置ExpandByDateMode参数,常用按天、按月分表

自动分表效果

全程无需人工干预,系统会自动定时创建分表,十分简单好用

性能测试

using Demo.Common;
using EFCore.Sharding;
using System;
using System.Diagnostics;
using System.Linq;namespace Demo.Performance
{class Base_UnitTestShardingRule : ModShardingRule<Base_UnitTest>{protected override string KeyField => "Id";protected override int Mod => 3;}class Program{static void Main(string[] args){ShardingConfig.Init(config =>{config.AddAbsDb(DatabaseType.SqlServer).AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, Config.ConString1).AddPhysicDbGroup().AddPhysicTable<Base_UnitTest>("Base_UnitTest_0").AddPhysicTable<Base_UnitTest>("Base_UnitTest_1").AddPhysicTable<Base_UnitTest>("Base_UnitTest_2").SetShardingRule(new Base_UnitTestShardingRule());});var db = DbFactory.GetRepository(Config.ConString1, DatabaseType.SqlServer);Stopwatch watch = new Stopwatch();var q = db.GetIQueryable<Base_UnitTest>().Where(x => x.UserName.Contains("00001C22-8DD2-4D47-B500-407554B099AB")).OrderByDescending(x => x.Id).Skip(0).Take(30);q.ToList();q.ToSharding().ToList();watch.Restart();var list1 = q.ToList();watch.Stop();Console.WriteLine($"未分表耗时:{watch.ElapsedMilliseconds}ms");watch.Restart();var list2 = q.ToSharding().ToList();watch.Stop();Console.WriteLine($"分表后耗时:{watch.ElapsedMilliseconds}ms");Console.WriteLine("完成");}}
}

分表Base_UnitTest_0-2各有100万数据,然后将这三张表的数据导入Base_UnitTest中(即Base_UnitTest表的数据与Base_UnitTest_0-2三张表总合数据一致)

分表与不分表测试结果如下

这里仅仅分了3张表,其效果立杆见影,若分表几十张,那效果想想就很棒

其它简单操作(非Sharing)

框架不仅支持Sharing,而且封装了常用数据库操作,使用比较简单
详细使用方式参考 链接

总结

这个简单实用强大的框架希望能够帮助到大家,力求为.NET生态贡献一份力,大家一起壮大.NET生态

欢迎使用本框架,若觉得不错,请比心

Github欢迎星星:https://github.com/Coldairarrow

博客园欢迎点赞:https://www.cnblogs.com/coldairarrow/

QQ群3:940069478
个人QQ:862520575(欢迎技术支持及商务合作,提供.NET Core + Linux + Nginx+ jenkins + git整套持续集成快速开发平台

EFCore.Sharding(EFCore开源分表框架)相关推荐

  1. efcore根据多个条件更新_EFCore.Sharding(EFCore开源分表框架)

    简介 本框架旨在为EF Core提供Sharding(即读写分离分库分表)支持,不仅提供了一套强大的普通数据操作接口,并且降低了分表难度,支持按时间自动分表扩容,提供的操作接口简洁统一. 源码地址:E ...

  2. SSM项目引入sharding JDBC进行分表

    SSM项目引入sharding JDBC进行分表 注意点: 本次集成sharing-jdbc 4.1.1,由于各个版本差别比较大,配置方式差别也特别大,请根据官方文档进行配置! 官方配置路径:http ...

  3. mysql sharding 方案_mysql sharding 方案 分库分表(sharding)系列(4)

    图1. Sharding实现层面与相关框架/产品 在DAO层实现 当团队决定自行实现sharding的时候,DAO层可能是嵌入sharding逻辑的首选位置,因为在这个层面上,每一个DAO的方法都明确 ...

  4. Spring boot + Sharding JDBC 分库分表 及 分布式事务处理

    Sharding JDBC 基础概念 Apache ShardingSphere 是一套开源的分布式数据库解决方案组成的生态圈,它由 JDBC.Proxy 和 Sidecar(规划中)这 3 款既能够 ...

  5. 基于代理的数据库分库分表框架 Mycat实践

    192.168.199.75 MySQL . MyCAT master 192.168.199.74 MySQL slave 192.168.199.76 MySQL standby master 如 ...

  6. 使用sharding做分库分表,使用jpa,发生的save不报错,数据库缺插不进去数据的问题

    先讲讲问题的诞生,我们项目起初没有引进 sharding分库,而是在项目上线前,才做的分库分表.也就是之前的业务都写好的,所以知道业务代码没有任何问题. 然后引入 sharding 的相关的依赖以后, ...

  7. SpringBoot + Sharding JDBC,一文搞定分库分表、读写分离

    程序员的成长之路 互联网/程序员/技术/资料共享 关注 阅读本文大概需要 30 分钟. 来自:blog.csdn.net/qq_40378034/article/details/115264837 S ...

  8. SpringBoot + Sharding JDBC 读写分离、分库分表

    Sharding-JDBC 最早是当当网内部使用的一款分库分表框架,到2017年的时候才开始对外开源,这几年在大量社区贡献者的不断迭代下,功能也逐渐完善,现已更名为 ShardingSphere,20 ...

  9. .Net/C#分库分表高性能O(1)瀑布流分页

    框架介绍 依照惯例首先介绍本期主角:ShardingCore 一款ef-core下高性能.轻量级针对分表分库读写分离的解决方案,具有零依赖.零学习成本.零业务代码入侵 dotnet下唯一一款全自动分表 ...

最新文章

  1. Science:“每周工作进展汇报”在博士培养中的作用
  2. 三体人有救了,只要等得够久就会有一个太阳被甩出去
  3. SD-WAN技术三大优势将成为SD-WAN方案成功的关键—Vecloud
  4. [luogu2664]树上游戏
  5. Robot framework 引入 Selenium2Library 类库:
  6. 十分钟搭建自己的私有NuGet服务器-BaGet
  7. 开源ckplayer 网页播放器, 跨平台(html5, mobile),flv, f4v, mp4, rtmp协议. webm, ogg, m3u8 !...
  8. PX4 CMakeLists.txt 文件剖析
  9. 39-java 输入输出总结
  10. cuda和cudnn下载地址
  11. labview混合编程学习
  12. 奇迹私服gs服务器端口未能连接请设置参数,奇迹私服架设之各个快捷方式参数...
  13. Ubuntu联网安装GCC
  14. net user administrator /passwordreq:yes 错误
  15. 一个测试反应速度的小游戏
  16. java单词大全_编程常用英语单词大全
  17. 概率逻辑程序设计学习 一.预备知识
  18. 【算法竞赛学习笔记】KD-Tree
  19. 1主2从基于GKE搭建k8s集群-无需科学上网
  20. PDF Extra Premium v7.0.4622 多合一 PDF 编辑器直装版

热门文章

  1. Codeforces 365C - Matrix(hash + yy)
  2. COM组件与.NET技术对比
  3. CDH集群安装配置(五)- Cloudera Manager Server
  4. (三)Controller接口控制器详解(二)
  5. java多线程编程——锁优化
  6. APP测试流程和测试点
  7. MonoRail学习笔记十一:页面控件的填充和验证
  8. flex容器属性(一)
  9. cacti+nagios 整合遇到的问题
  10. android关于获取摄像头帧数据转成图片