简介

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

源码地址:EFCore.SHarding

引言

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

开始

准备

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

包名说明EFCore.Sharding必装包,3.x版本对应EF Core3.x,2.x版本对应EF Core2.xEFCore.Sharding.MySqlMySql支持EFCore.Sharding.PostgreSqlPostgreSql支持EFCore.Sharding.SQLiteSQLite支持EFCore.Sharding.SqlServerSqlServer支持EFCore.Sharding.OracleOracle支持(暂不支持3.x)

配置

class Base_UnitTestShardingRule : ModShardingRule{    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_0")        .AddPhysicTable("Base_UnitTest_1")        .AddPhysicTable("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 _insertList = new List{    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();//删除单条数据_db.Delete(_newData);//删除多条数据_db.Delete(_insertList);//删除指定数据_db.Delete(x => x.UserId == "Admin2");//更新单条数据_db.Update(_newData);//更新多条数据_db.Update(_insertList);//更新单条数据指定属性_db.UpdateAny(_newData, new List { "UserName", "Age" });//更新多条数据指定属性_db.UpdateAny(_insertList, new List { "UserName", "Age" });//更新指定条件数据_db.UpdateWhere(x => x.UserId == "Admin", x =>{    x.UserId = "Admin2";});//GetList获取表的所有数据var list=_db.GetList();//GetIQPagination获取分页后的数据var list=_db.GetIShardingQueryable().GetPagination(pagination);//Maxvar max=_db.GetIShardingQueryable().Max(x => x.Age);//Minvar min=_db.GetIShardingQueryable().Min(x => x.Age);//Averagevar min=_db.GetIShardingQueryable().Average(x => x.Age);//Countvar min=_db.GetIShardingQueryable().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    {        public override DateTime BuildDate(Base_UnitTest obj)        {            return obj.CreateTime;        }    }    class Program    {        ///         /// 表都在同一个数据库中        ///         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(//设置为按时间自动分表                        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().Count();                Console.WriteLine($"当前数据量:{count}");                Thread.Sleep(50);            }        }        ///         /// 表分布在两个数据库测试        ///         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(//设置为按时间自动分表                        ExpandByDateMode.PerMinute,                        (startTime1, endTime1, group1),                        (startTime2, endTime2, group2)                        );            });            List tasks = new List();            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().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    {        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_0")                    .AddPhysicTable("Base_UnitTest_1")                    .AddPhysicTable("Base_UnitTest_2")                    .SetShardingRule(new Base_UnitTestShardingRule());            });            var db = DbFactory.GetRepository(Config.ConString1, DatabaseType.SqlServer);            Stopwatch watch = new Stopwatch();            var q = db.GetIQueryable()                .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/

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

  1. 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. mysql 分表 条件查询,面试过关斩将:分库分表-sharding-jdbc分页,排序,条件查询优化...

    之前讲了利用sharding-jdbc 3.1进行分表的情况,也讲了利用一致性hash去做分表的高可用.今天讲下分表后的分页,排序,条件查询优化. 其实本身sharding-jdbc是提供了分页功能的 ...

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

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

  7. efcore根据多个条件更新_EF Core 基础知识

    数据库连接字符串 数据库连接字符串 在 ASP.NET Core 添加配置片段: {"ConnectionStrings": {"BloggingDatabase&quo ...

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

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

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

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

最新文章

  1. 【机器学习】基于人工鱼群算法的非线性函数寻优
  2. 保证计算机网络的稳定运行,厦门大学校园网管理保证网络稳定运行
  3. varnish安装及简单配置
  4. js实现撤销恢复_电脑硬盘丢失的资料怎么恢复?选对方法是关键
  5. 读书日记 莫雨 《一个程序员的奋斗史》Java 面试 感悟 程序员
  6. vue全家桶+Koa2开发笔记(3)--mongodb
  7. 《运营之光》-- 学习笔记(四)
  8. python卷积函数_Convolution卷积算法python以numpy,Matplotlib实现
  9. 摄像头bug查找工作总结
  10. RealSense D435i深度相机介绍
  11. poj2112,最大流,最优挤奶方案
  12. 神工鬼斧惟肖惟妙,M1 mac系统深度学习框架Pytorch的二次元动漫动画风格迁移滤镜AnimeGANv2+Ffmpeg(图片+视频)快速实践
  13. 浅谈数字后端工程师的工作
  14. echart x轴 倾斜,Echarts x轴字体倾斜
  15. BK3432和BK3431Q芯片开发问题
  16. UTF-8的繁体与简体转换
  17. 易岸公考:最全版本!公务员报考条件
  18. ValueError: Format specifier missing precision
  19. 情感充沛,去体悟生活
  20. 《深入理解计算机系统》:Cache Lab

热门文章

  1. maven的日志在哪里看_日志管理领域研究现状(2)
  2. Java 集合时间复杂度
  3. JUC锁-Condition(三)
  4. 顺序表的所有基本操作
  5. linux 扫描i2c端口,s3c2440用I2C接口访问EEPROM
  6. 中职计算机专业英语说课稿,高职高专英语说课稿
  7. 微软系统封装工具ImageX使用方法及实例介绍
  8. numpy pytorch 接口对应_拆书分享篇深度学习框架PyTorch入门与实践
  9. w3c的html4.0规范,W3C HTML4.0学习
  10. 笔记本电脑有蓝牙连接功能吗_百元蓝牙无线键盘推荐——罗技K380