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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

EFCore.Sharding(EFCore开源分表框架)

發(fā)布時間:2023/12/4 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 EFCore.Sharding(EFCore开源分表框架) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

簡介

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

源碼地址:EFCore.SHarding

引言

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

開始

準(zhǔn)備

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

包名說明
EFCore.Sharding必裝包,3.x版本對應(yīng)EF Core3.x,2.x版本對應(yīng)EF Core2.x
EFCore.Sharding.MySqlMySql支持
EFCore.Sharding.PostgreSqlPostgreSql支持
EFCore.Sharding.SQLiteSQLite支持
EFCore.Sharding.SqlServerSqlServer支持
EFCore.Sharding.OracleOracle支持(暫不支持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是指添加抽象數(shù)據(jù)庫,抽象數(shù)據(jù)庫就是將多個分庫看成同一個數(shù)據(jù)庫來進(jìn)行操作

  • AddPhysicDbGroup是指添加物理數(shù)據(jù)庫組,在同一組物理數(shù)據(jù)庫中,它們數(shù)據(jù)庫類型相同,擁有的表相同,每個數(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ī)則,上述代碼中采用的是哈希取模的分表方式

使用

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

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

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

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

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

按時間自動分表

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

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>/// 表都在同一個數(shù)據(jù)庫中/// </summary>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<Base_UnitTest>(//設(shè)置為按時間自動分表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($"當(dāng)前數(shù)據(jù)量:{count}");Thread.Sleep(50);}}/// <summary>/// 表分布在兩個數(shù)據(jù)庫測試/// </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)//添加抽象數(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<Base_UnitTest>(//設(shè)置為按時間自動分表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($"當(dāng)前數(shù)據(jù)量:{count}");Thread.Sleep(50);}}));}Console.ReadLine();}static void Main(string[] args){OneGroup();Console.ReadLine();}} }

上面Demo都在源碼中

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

自動分表效果

全程無需人工干預(yù),系統(tǒng)會自動定時創(chuàng)建分表,十分簡單好用

性能測試

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萬數(shù)據(jù),然后將這三張表的數(shù)據(jù)導(dǎo)入Base_UnitTest中(即Base_UnitTest表的數(shù)據(jù)與Base_UnitTest_0-2三張表總合數(shù)據(jù)一致)

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

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

其它簡單操作(非Sharing)

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

總結(jié)

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

歡迎使用本框架,若覺得不錯,請比心

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

博客園歡迎點贊:https://www.cnblogs.com/coldairarrow/

QQ群3:940069478
個人QQ:862520575(歡迎技術(shù)支持及商務(wù)合作,提供.NET Core + Linux + Nginx+ jenkins + git整套持續(xù)集成快速開發(fā)平臺

總結(jié)

以上是生活随笔為你收集整理的EFCore.Sharding(EFCore开源分表框架)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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