日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2024/1/23 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 efcore根据多个条件更新_EFCore.Sharding(EFCore开源分表框架) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

簡(jiǎn)介

本框架旨在為EF Core提供Sharding(即讀寫分離分庫分表)支持,不僅提供了一套強(qiáng)大的普通數(shù)據(jù)操作接口,并且降低了分表難度,支持按時(shí)間自動(dòng)分表擴(kuò)容,提供的操作接口簡(jiǎn)潔統(tǒng)一.

源碼地址:EFCore.SHarding

引言

讀寫分離分庫分表一直是數(shù)據(jù)庫領(lǐng)域中的重難點(diǎn),當(dāng)數(shù)據(jù)規(guī)模達(dá)到單庫極限的時(shí)候,就不得不考慮分表方案。EF Core作為.NET Core中最為主流的ORM,用起來十分方便快捷,但是官方并沒有相應(yīng)的Sharding支持,鄙人不才,經(jīng)過一番摸索之后終于完成這個(gè)框架.

開始

準(zhǔn)備

首先根據(jù)需要安裝對(duì)應(yīng)的Nuget包

包名說明EFCore.Sharding必裝包,3.x版本對(duì)應(yīng)EF Core3.x,2.x版本對(duì)應(yīng)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是指添加抽象數(shù)據(jù)庫,抽象數(shù)據(jù)庫就是將多個(gè)分庫看成同一個(gè)數(shù)據(jù)庫來進(jìn)行操作
  • AddPhysicDbGroup是指添加物理數(shù)據(jù)庫組,在同一組物理數(shù)據(jù)庫中,它們數(shù)據(jù)庫類型相同,擁有的表相同,每個(gè)數(shù)據(jù)庫擁有的數(shù)據(jù)是一致的(之間通過主主復(fù)制或主從復(fù)制進(jìn)行數(shù)據(jù)同步)
  • AddPhysicTable是指添加物理數(shù)據(jù)表,傳入的Base_UnitTest是抽象數(shù)據(jù)表(即將Base_UnitTest拆分為Base_UnitTest_0~2)
  • Base_UnitTestShardingRule是采用的分表規(guī)則,上述代碼中采用的是哈希取模的分表方式

使用

配置完成,下面開始使用,使用方式非常簡(jiǎn)單,與平常使用基本一致首先獲取分片倉儲(chǔ)接口IShardingRepository

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

然后即可進(jìn)行數(shù)據(jù)操作:

Base_UnitTest _newData = new Base_UnitTest{ Id = Guid.NewGuid().ToString(), UserId = "Admin", UserName = "超級(jí)管理員", Age = 22};List _insertList = new List{ new Base_UnitTest { Id = Guid.NewGuid().ToString(), UserId = "Admin1", UserName = "超級(jí)管理員1", Age = 22 }, new Base_UnitTest { Id = Guid.NewGuid().ToString(), UserId = "Admin2", UserName = "超級(jí)管理員2", Age = 22 }};//添加單條數(shù)據(jù)_db.Insert(_newData);//添加多條數(shù)據(jù)_db.Insert(_insertList);//清空表_db.DeleteAll();//刪除單條數(shù)據(jù)_db.Delete(_newData);//刪除多條數(shù)據(jù)_db.Delete(_insertList);//刪除指定數(shù)據(jù)_db.Delete(x => x.UserId == "Admin2");//更新單條數(shù)據(jù)_db.Update(_newData);//更新多條數(shù)據(jù)_db.Update(_insertList);//更新單條數(shù)據(jù)指定屬性_db.UpdateAny(_newData, new List { "UserName", "Age" });//更新多條數(shù)據(jù)指定屬性_db.UpdateAny(_insertList, new List { "UserName", "Age" });//更新指定條件數(shù)據(jù)_db.UpdateWhere(x => x.UserId == "Admin", x =>{ x.UserId = "Admin2";});//GetList獲取表的所有數(shù)據(jù)var list=_db.GetList();//GetIQPagination獲取分頁后的數(shù)據(jù)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();//事務(wù),使用方式與普通事務(wù)一致bool succcess = _db.RunTransaction(() =>{ _db.Insert(_newData); var newData2 = _newData.DeepClone(); _db.Insert(newData2);}).Success;Assert.AreEqual(succcess, false);

上述操作中表面上是操作Base_UnitTest表,實(shí)際上卻在按照一定規(guī)則使用Base_UnitTest_0~2三張表,使分片對(duì)業(yè)務(wù)操作透明,極大提高開發(fā)效率具體使用方式請(qǐng)參考單元測(cè)試源碼:連接

按時(shí)間自動(dòng)分表

上面的哈希取模的方式雖然簡(jiǎn)單,但是卻十分不實(shí)用,因?yàn)楫?dāng)3張分表到達(dá)瓶頸時(shí),將會(huì)面臨擴(kuò)容的問題,這種方式擴(kuò)容需要進(jìn)行大量的數(shù)據(jù)遷移,這無疑是十分麻煩的。因此需要一種方式能夠系統(tǒng)自動(dòng)建表擴(kuò)容,并且無需人工干預(yù),這就是按時(shí)間自動(dòng)分表.

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 { /// /// 表都在同一個(gè)數(shù)據(jù)庫中 /// public static void OneGroup() { DateTime startTime = DateTime.Now.AddMinutes(-5); DateTime endTime = DateTime.MaxValue; //配置初始化 ShardingConfig.Init(config => { config.AddAbsDb(DatabaseType.SqlServer)//添加抽象數(shù)據(jù)庫 .AddPhysicDbGroup()//添加物理數(shù)據(jù)庫組 .AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, Config.ConString1)//添加物理數(shù)據(jù)庫1 .SetShardingRule(new Base_UnitTestShardingRule())//設(shè)置分表規(guī)則 .AutoExpandByDate(//設(shè)置為按時(shí)間自動(dòng)分表 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($"當(dāng)前數(shù)據(jù)量:{count}"); Thread.Sleep(50); } } /// /// 表分布在兩個(gè)數(shù)據(jù)庫測(cè)試 /// 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)//添加抽象數(shù)據(jù)庫 .AddPhysicDbGroup(group1)//添加物理數(shù)據(jù)庫組1 .AddPhysicDbGroup(group2)//添加物理數(shù)據(jù)庫組2 .AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, Config.ConString1, group1)//添加物理數(shù)據(jù)庫1 .AddPhysicDb(ReadWriteType.Read | ReadWriteType.Write, Config.ConString2, group2)//添加物理數(shù)據(jù)庫2 .SetShardingRule(new Base_UnitTestShardingRule())//設(shè)置分表規(guī)則 .AutoExpandByDate(//設(shè)置為按時(shí)間自動(dòng)分表 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($"當(dāng)前數(shù)據(jù)量:{count}"); Thread.Sleep(50); } })); } Console.ReadLine(); } static void Main(string[] args) { OneGroup(); Console.ReadLine(); } }}

上面Demo都在源碼中

上面的代碼實(shí)現(xiàn)了將Base_UnitTest表按照時(shí)間自動(dòng)分表,每分鐘創(chuàng)建一張表,實(shí)際使用中根據(jù)業(yè)務(wù)需求設(shè)置ExpandByDateMode參數(shù),常用按天、按月分表

自動(dòng)分表效果

全程無需人工干預(yù),系統(tǒng)會(huì)自動(dòng)定時(shí)創(chuàng)建分表,十分簡(jiǎn)單好用

性能測(cè)試

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($"未分表耗時(shí):{watch.ElapsedMilliseconds}ms"); watch.Restart(); var list2 = q.ToSharding().ToList(); watch.Stop(); Console.WriteLine($"分表后耗時(shí):{watch.ElapsedMilliseconds}ms"); Console.WriteLine("完成"); } }}

分表Base_UnitTest_0-2各有100萬數(shù)據(jù),然后將這三張表的數(shù)據(jù)導(dǎo)入Base_UnitTest中(即Base_UnitTest表的數(shù)據(jù)與Base_UnitTest_0-2三張表總合數(shù)據(jù)一致)

分表與不分表測(cè)試結(jié)果如下

這里僅僅分了3張表,其效果立桿見影,若分表幾十張,那效果想想就很棒

其它簡(jiǎn)單操作(非Sharing)

框架不僅支持Sharing,而且封裝了常用數(shù)據(jù)庫操作,使用比較簡(jiǎn)單詳細(xì)使用方式參考 鏈接

總結(jié)

這個(gè)簡(jiǎn)單實(shí)用強(qiáng)大的框架希望能夠幫助到大家,力求為.NET生態(tài)貢獻(xiàn)一份力,大家一起壯大.NET生態(tài)

歡迎使用本框架,若覺得不錯(cuò),請(qǐng)比心

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

博客園歡迎點(diǎn)贊:https://www.cnblogs.com/coldairarrow/

總結(jié)

以上是生活随笔為你收集整理的efcore根据多个条件更新_EFCore.Sharding(EFCore开源分表框架)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。