efcore根据多个条件更新_收藏级:EFCore.Sharding(EFCore开源分表框架)

EFCore.Sharding是一个为EF Core提供读写分离和分库分表支持的框架,简化了数据库分表操作。它支持按时间自动分表,能根据业务需求设置扩容模式。此外,框架还提供了性能测试,显示了分表后的显著性能提升。源码和详细教程可在作者的GitHub和博客园找到。
摘要由CSDN通过智能技术生成
  • 简介

  • 引言

  • 开始

    • 准备

    • 配置

    • 使用

    • 按时间自动分表

    • 性能测试

    • 其它简单操作(非Sharing)

  • 总结

简介

本框架旨在为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.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<string> { "UserName", "Age" });//更新多条数据指定属性
_db.UpdateAny(_insertList, new List<string> { "UserName", "Age" });//更新指定条件数据
_db.UpdateWhere(x => x.UserId == "Admin", x =>
{
x.UserId = "Admin2";
});//GetList获取表的所有数据
var list=_db.GetList();//GetIQPagination获取分页后的数据
var list=_db.GetIShardingQueryable().GetPagination(pagination);//Max
var max=_db.GetIShardingQueryable().Max(x => x.Age);//Min
var min=_db.GetIShardingQueryable().Min(x => x.Age);//Average
var min=_db.GetIShardingQueryable().Average(x => x.Age);//Count
var 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参数,常用按天、按月分表

自动分表效果

d198618501aaf65c1dc1b914d990b961.png

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

性能测试

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三张表总合数据一致)

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

52010f8a087388cb32e2750f34365290.png

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

其它简单操作(非Sharing)

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

总结

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

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

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

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

出处:https://www.cnblogs.com/coldairarrow/

版权申明:本文来源于网友收集或网友提供,如果有侵权,请转告版主或者留言,本公众号立即删除。

5eba9ca999932562260abbf52aa4de28.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如何做数据分析 如何做数据分析全文共50页,当前为第1页。 目录 一、数据分析那些事儿 二、数据处理 三、数据分析 四、数据展现 五、报告撰写 2/50 如何做数据分析全文共50页,当前为第2页。 目录 二、数据处理 三、数据分析 四、数据展现 五、报告撰写 一、数据分析那些事儿 3/50 如何做数据分析全文共50页,当前为第3页。 一. 数据分析那些事儿 数据分析六部曲 2 常用指标或术语 3 3 数据分析是"神马" 3 1 4/50 如何做数据分析全文共50页,当前为第4页。 1、数据分析是"神马" 一. 数据分析那些事儿 5/50 数据分析是指用适当的统计分析方法对收集来的大量数据进行分析,将它们加以汇总、理解并消化,以求最大化地开发数据的功能,发挥数据的作用。 数据分析是为了提取有用信息和形成结论而对数据加以详细研究和概括总结的过程。 如何做数据分析全文共50页,当前为第5页。 1、数据分析是"神马" 一. 数据分析那些事儿 菜鸟与数据分析师的区别 菜鸟会想 分析师会想 这张曲线图真好看,怎么做的? 数据变化的背后真相是什么? 这些数据可以做什么样的分析? 从哪些角度分析数据才系统? 高级分析的方法在这儿能用吗? 用什么分析方法最有效? 要做多少张图表? 图表是否表达出有效的观点? 除了为数据添加文字说明还需说什么? 数据分析的目的达到了吗? 数据分析报告要写多少页? 数据分析报告有说服力吗? …… …… 他们主要的 区别就在于 目的是否明确 6/50 如何做数据分析全文共50页,当前为第6页。 1、数据分析是"神马" 一. 数据分析那些事儿 数据分析师的基本素质 不论说话还是写文章,都要有条理,有目的,不可眉毛胡子一把抓,不分主次。 模仿主要是参考他人优秀的分析思路和方法。但不能:一直在模仿,从未超越过。 7/50 如何做数据分析全文共50页,当前为第7页。 2、数据分析六部曲 一. 数据分析那些事儿 一般数据分析用Excel可以完成。 8/50 如何做数据分析全文共50页,当前为第8页。 3、常用指标或术语 一. 数据分析那些事儿 倍数一般是表示数量的增长或上升幅度,而不适用 9/50 如何做数据分析全文共50页,当前为第9页。 小结:数据分析那些事儿 数据分析是"神马"。 数据分析六部曲。 常用指标或术语。 ——提取信息、形成结论,对数据加以详细研究和概括总结的过程 我们已经初步了解数据分析的过程和执行步骤,接下来就要深入了解具体内容。 下一节:数据处理。 ——明确目的、数据收集、数据处理、数据分析、数据展现、报告撰写 10/50 如何做数据分析全文共50页,当前为第10页。 目录 二、数据处理 三、数据分析 四、数据展现 五、报告撰写 一、数据分析那些事儿 11/50 如何做数据分析全文共50页,当前为第11页。 二. 数据处理 初识EXCEL & 数据准备 数据处理方式和技巧 数据处理原则 数据清洗 常用数据处理公式 目录 12/50 如何做数据分析全文共50页,当前为第12页。 1、初识EXCEL&数据准备 二. 数据处理 做数据分析讲究的是原则、思考方法和解决方案,任何软件都只是一工具,我们只要掌握并精通一工具就足够了。这比什么软件都只懂但都只是略懂皮毛要好很多。 13/50 如何做数据分析全文共50页,当前为第13页。 1、初识EXCEL&数据准备 二. 数据处理 序号 要求 1 数据表由标明行和数据部分组成 2 第一行是表的列标题(字段名),列标题不能重复 3 第二行起是数据部分,数据部分的每一行数据称为一个记录,并且数据部分不允许出现空白行和空白列 4 数据表中不能有合并单元桥存在 5 数据表与其他数据之间应该留出至少一个空白行和一个空白列 6 数据表需要以一维的形式存储,但是在实际操作中接触的数据往往是以二维表格的形式存在的,此时应将二维表转化为一维表的形式储存数据。 7 数据部分每一列的数据项,内容、格式统一。 14/50 如何做数据分析全文共50页,当前为第14页。 2、数据处理方式和技巧 二. 数据处理 函数 函数是指定的数据按照一定的规则转化为需要的结果,规则也就是我们所用到的公式。 图表 图表的主要目的是为了表现数据、传递信息。 宏 宏是一个指令集,用来告诉Excel完成用户指定的动作。宏类似于计算机程序,但它是完全运行于Excel中的。 15/50 如何做数据分析全文共50页,当前为第15页。 2、数据处理方式和技巧 二. 数据处理 F2编辑单元格 填充柄 Ctrl+D Ctrl+R '+007,变成007的有效输入。 快速设置单元格格式:Ctrl+1 1/3的输入,0+空格+1/3 16/50 如何做数据分析全文共50页,当前为第16页。 2、数据处理方式和技巧 二. 数据处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值