亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C#中efcore-ShardingCore呈現(xiàn)“完美”分表

 更新時間:2021年08月23日 17:24:34   作者:薛家明  
本文簡單的介紹了efcore的分表,著重介紹了efcore下最完美的分表組件ShardingCore,可以幫助大家更好的學(xué)習(xí),感興趣的小伙伴可以參考一下

如果您對分表有以下痛點那么不妨試試我這邊開源的框架sharding-core ,是否需要無感知使用分表組件,是否需要支持abp,是否需要支持自定義分表規(guī)則,是否需要支持自定義分表鍵,是否需要支持特定的efcore版本,是否希望框架不帶任何三方框架干凈,是否需要支持讀寫分離,是否需要動態(tài)添加表,是否需要支持join,group等操作,是否需要支持追蹤特性,是否想在不修改原先代碼的基礎(chǔ)上擴展分表功能,如果一起上幾個條件任意組合且你在市面上沒辦法找到可替代的框架可以試試本框架。如何使用代碼具體可以參考github 將代碼下載下來如果本地裝了sqlserver直接運行單元測試或者Sample.SqlServer程序會自動在本地新建數(shù)據(jù)庫新建數(shù)據(jù)庫表結(jié)構(gòu),目前初始化數(shù)據(jù)為用戶信息和用戶對應(yīng)的月薪信息表,用戶表以用戶id取模,用戶月薪表以月份分表。

首先需要了解本框架的一個版本號不然將對您的使用產(chǎn)生一定的分期,目前框架分為3個版本分別是2.x,3.x,5.x3個版本,分別對應(yīng)efcore 2.x efcore 3.x efcore 5.x,有人要問為什么不支持6.x呢(小弟剛剛在上周完成對本框架的開發(fā)重構(gòu),目前還未對efcore 6.x進行著手不過將在不遠(yuǎn)的將來即將支持(目測1-2個星期內(nèi)))。

目前efcore生態(tài)下有著許許多多的分表、分庫的解決方案,但是目前來講都有其不足點,比如需要手動設(shè)置分表后綴、需要大量替換現(xiàn)有代碼、不支持事務(wù)等等一系列問題,所以在這個大前提下我之前開源了sharding-core 分表組件,這個分表組件是目前來說個人認(rèn)為比較“完美”的分表組件,這個分表組件目前是參考了sharding-jdbc來實現(xiàn)的,但是比sharding-jdbc更加強大(因為C#的表達式)。首先我們來看下目前市面上有的分表組件的缺點我們來針對其缺點進行痛點解決。

efcore支持情況

efcore版本 是否支持
2.x 支持
3.x 支持
5.x 支持
6.x 即將支持

數(shù)據(jù)庫支持情況

數(shù)據(jù)庫 理論是否支持
SqlServer 支持
MySql 支持
PostgreSql 支持
SQLite 支持
Oracle 支持
其他 支持(只要efcore支持)

理論上只要是efcore對應(yīng)版本支持的數(shù)據(jù)庫,sharding-core都將支持。

如何開始使用

1.創(chuàng)建一個數(shù)據(jù)庫對象繼承IShardingTable并且在對應(yīng)的分表字段上進行[ShardingTableKey]特性的標(biāo)注

 /// <summary>
    /// 用戶表
    /// </summary>
    public class SysUserMod : IShardingTable
    {
        /// <summary>
        /// 用戶Id用于分表
        /// </summary>
        [ShardingTableKey(TailPrefix = "_")]
        public string Id { get; set; }
        /// <summary>
        /// 用戶名稱
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 用戶姓名
        /// </summary>
        public int Age { get; set; }
    }

2.創(chuàng)建對應(yīng)的實體表對應(yīng)配置 推薦 fluent api

   public class SysTestMap:IEntityTypeConfiguration<SysTest>
    {
        public void Configure(EntityTypeBuilder<SysTest> builder)
        {
            builder.HasKey(o => o.Id);
            builder.Property(o => o.Id).IsRequired().HasMaxLength(128);
            builder.Property(o => o.UserId).IsRequired().HasMaxLength(128);
            builder.ToTable(nameof(SysTest));
        }
    }

3.創(chuàng)建對應(yīng)的分表規(guī)則 取模分表,參數(shù)2代表后綴2位就是00-99最多100張表,3表示模3== key.hashcode() %3

    public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute<SysUserMod>
    {
        public SysUserModVirtualTableRoute() : base(2,3)
        {
        }
    }

4.創(chuàng)建對應(yīng)執(zhí)行的dbcontext 這一步除了繼承IShardingTableDbContext外其他和普通dbcontext一樣

    public class DefaultTableDbContext: DbContext,IShardingTableDbContext
    {
        public DefaultTableDbContext(DbContextOptions<DefaultTableDbContext> options) :base(options)
        {
            
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.ApplyConfiguration(new SysUserModMap());
        }

        public IRouteTail RouteTail { get; set; }
    }

5.添加分表dbcontext

    public class DefaultShardingDbContext:AbstractShardingDbContext<DefaultTableDbContext>
    {
        public DefaultShardingDbContext(DbContextOptions<DefaultShardingDbContext> options) : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.ApplyConfiguration(new SysUserModMap());
        }

        public override Type ShardingDbContextType => this.GetType();
    }

6.添加配置

       public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
   //原先的dbcontext可以用也可以不用如果原先的dbcontext還在用就繼續(xù)
            //services.AddDbContext<DefaultTableDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx3;Integrated Security=True"));
            services.AddShardingDbContext<DefaultShardingDbContext, DefaultTableDbContext>(
                o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx2;Integrated Security=True;")
                , op =>
                 {
                     op.EnsureCreatedWithOutShardingTable = true;
                     op.CreateShardingTableOnStart = true;
                     op.UseShardingOptionsBuilder(
                         (connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger),//使用dbconnection創(chuàng)建dbcontext支持事務(wù)
                         (conStr,builder) => builder.UseSqlServer(conStr).UseLoggerFactory(efLogger));//使用鏈接字符串創(chuàng)建dbcontext
                     op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
                 });
        }
  
  
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
   ...
   //添加啟動項
            app.UseShardingCore();
   ...
        }
  
  public static class ShardingCoreExtension{

   public static IApplicationBuilder UseShardingCore(this IApplicationBuilder app)
   {
    var shardingBootstrapper = app.ApplicationServices.GetRequiredService<IShardingBootstrapper>();
    shardingBootstrapper.Start();
    return app;
   }
  }

7.控制器使用

        private readonly DefaultShardingDbContext _defaultTableDbContext;

        public ValuesController(DefaultShardingDbContext defaultTableDbContext)
        {
            _defaultTableDbContext = defaultTableDbContext;
        }

        [HttpGet]
        public async Task<IActionResult> Get()
        {
            var resultx11231 = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Age == 198198).Select(o=>o.Id).ContainsAsync("1981");
            var resultx1121 = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "198").SumAsync(o=>o.Age);
            var resultx111 = await _defaultTableDbContext.Set<SysUserMod>().FirstOrDefaultAsync(o => o.Id == "198");
            var resultx2 = await _defaultTableDbContext.Set<SysUserMod>().CountAsync(o => o.Age<=10);
            var resultx = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "198").FirstOrDefaultAsync();
            var resultx33 = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "198").Select(o=>o.Id).FirstOrDefaultAsync();
            var resulxxt = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "198").ToListAsync();
            var result = await _defaultTableDbContext.Set<SysUserMod>().ToListAsync();

            var sysUserMod98 = result.FirstOrDefault(o => o.Id == "98");
            _defaultTableDbContext.Attach(sysUserMod98);
            sysUserMod98.Name = "name_update"+new Random().Next(1,99)+"_98";
            await _defaultTableDbContext.SaveChangesAsync();
            return Ok(result);
        }

自定義分表鍵,自定義分表規(guī)則

目前市面上有的框架要么對分表字段有限制比如僅支持DateTime類型或者int等,要么對分表規(guī)則有限制:僅支持按天、按月、取模...等等,但是基于分表規(guī)則和分表字段是業(yè)務(wù)規(guī)則所以本框架遵循將其由業(yè)務(wù)系統(tǒng)自己定義,最大化來實現(xiàn)分表庫的適用性,基本上滿足一切分表規(guī)則,且sharding-core目前默認(rèn)提供一些常用的分表規(guī)則可以快速集成。

默認(rèn)路由

抽象abstract 路由規(guī)則 tail 索引
AbstractSimpleShardingModKeyIntVirtualTableRoute 取模 0,1,2... =
AbstractSimpleShardingModKeyStringVirtualTableRoute 取模 0,1,2... =
AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute 按時間 yyyyMMdd >,>=,<,<=,=,contains
AbstractSimpleShardingDayKeyLongVirtualTableRoute 按時間戳 yyyyMMdd >,>=,<,<=,=,contains
AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute 按時間 yyyyMMdd_dd >,>=,<,<=,=,contains
AbstractSimpleShardingWeekKeyLongVirtualTableRoute 按時間戳 yyyyMMdd_dd >,>=,<,<=,=,contains
AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute 按時間 yyyyMM >,>=,<,<=,=,contains
AbstractSimpleShardingMonthKeyLongVirtualTableRoute 按時間戳 yyyyMM >,>=,<,<=,=,contains
AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute 按時間 yyyy >,>=,<,<=,=,contains
AbstractSimpleShardingYearKeyLongVirtualTableRoute 按時間戳 yyyy >,>=,<,<=,=,contains

所謂的索引就是通過改對應(yīng)的條件操作符可以縮小減少指定表的范圍,加快程序的執(zhí)行
如果以上默認(rèn)分表無法滿足您的需求您還可以自定義分表,如何分表可以通過繼承 AbstractShardingOperatorVirtualTableRoute<TEntity,TKey>來實現(xiàn)自定義分表規(guī)則(近乎90%的規(guī)則都可以實現(xiàn))

動態(tài)添加分表信息

很多分表組件默認(rèn)不帶動態(tài)分表信息導(dǎo)致很多分表沒辦法根據(jù)業(yè)務(wù)系統(tǒng)來進行動態(tài)創(chuàng)建,sharding-core默認(rèn)提供動態(tài)建表接口可以支持動態(tài)按時間,按租戶等不需要數(shù)據(jù)做遷移的動態(tài)分表信息,
如果需要請參考Samples.AutoByDate.SqlServer

支持select,join,group by等連表聚合函數(shù)

目前sharding-core支持select按需查詢,join分表連表查詢,group by聚合查詢,雖然本框架支持但是出于性能原因本框架還是不建議使用join操作符來操作,因為過多的表路由會導(dǎo)致笛卡爾積,會導(dǎo)致需要查詢的表集合增長對數(shù)據(jù)庫連接比較考驗。
以下代碼來自github的單元測試中,SysUserMod表示用戶表,SysUserSalary表示用戶月薪表用戶表按id取模,用戶月薪表按月分表

//join查詢
var list = await (from u in _virtualDbContext.Set<SysUserMod>()
                              join salary in _virtualDbContext.Set<SysUserSalary>()
                                  on u.Id equals salary.UserId
                              select new
                              {
                                  u.Id,
                                  u.Age,
                                  Salary = salary.Salary,
                                  DateOfMonth = salary.DateOfMonth,
                                  Name = u.Name
                              }).ToListAsync();

//group聚合查詢
var ids = new[] {"200", "300"};
            var dateOfMonths = new[] {202111, 202110};
            var group = await (from u in _virtualDbContext.Set<SysUserSalary>()
                    .Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth))
                group u by new
                {
                    UId = u.UserId
                }
                into g
                select new
                {
                    GroupUserId = g.Key.UId,
                    Count = g.Count(),
                    TotalSalary = g.Sum(o => o.Salary),
                    AvgSalary = g.Average(o => o.Salary),
                    AvgSalaryDecimal = g.Average(o => o.SalaryDecimal),
                    MinSalary = g.Min(o => o.Salary),
                    MaxSalary = g.Max(o => o.Salary)
                }).ToListAsync();

分頁

我們常說的分頁是分表的難點也是最考驗分表組件的
1我們首先來看普通的分表組件如何分頁
首先我們定義一組組數(shù)據(jù)比如是1-100的連續(xù)數(shù)字,然后分成兩張表按奇偶分表

表名 數(shù)據(jù)
table1 1,3,5,7,9...
table2 2,4,6,8,10...

select * from table limit 2,2理論上結(jié)果3,4
如果本次查詢會做落到table1 和table2那么會改寫成 2句sql
第一句 select * from table1 limit 4 ---> 1,3,5,7
第二句 select * from table2 limit 4 ---> 2,4,6,8
將8條數(shù)據(jù)放入內(nèi)存然后排序
1,2,3,4,5,6,7,8
獲取第3到4條數(shù)據(jù) 結(jié)果[3,4]

這個情況是我們常見的也是最簡單的分頁,但是這個情況僅僅適用于數(shù)據(jù)量小的時候,如果用戶不小心點到了分頁的最后一頁那么結(jié)果將是災(zāi)難性的這是毋庸置疑的
那么sharding-core是如何處理的呢

select * from table limit 2,2
首先還是一樣對數(shù)據(jù)庫語句進行改性并且生成對應(yīng)的sql
第一句 select * from table1 limit 4
第二句 select * from table2 limit 4
因為ado.net默認(rèn)DataReader是流式獲取,只要連接不關(guān)閉那么可以一直實現(xiàn)next獲取到內(nèi)存
創(chuàng)建一個優(yōu)先級隊列一個可以具有排序功能的隊列
因為DataReader的特性我們分別對sql1和sql2進行一次next獲取到2個數(shù)組一個是[1,.....] A和數(shù)組[2......] B
獲取到兩個數(shù)組我們只知道頭部第一個對象因為沒有進行后續(xù)的next所以無法知曉剩下的數(shù)據(jù)但是有一點可以知道后面的數(shù)據(jù)都是按sql的指定順序的所以都不會比當(dāng)前頭大或者小
先將1和2放入優(yōu)先級隊列可以知道如果asc那么數(shù)組A放在隊列頭 數(shù)組B放在隊列尾部,然后對優(yōu)先級隊列進行poll彈出,并且對A進行next這個時候A變成了[3,....]再將A放入優(yōu)先級隊列
這時候優(yōu)先級隊列就是B在前A在后依次操作,然后對分頁的進行過濾因為要跳過2個對象所以只需要空執(zhí)行2次那么指針就會指向A數(shù)組的3和B數(shù)組的4,剩下的只要獲取2個數(shù)據(jù)就可以了,
這樣做可以保證內(nèi)存最小化,然后分頁不會成為程序的災(zāi)難。

無感知使用

目前的分表框架很少有做到無感知使用的,你在使用的時候好一點的框架不依賴三方,一般一點的不但要依賴很多三方框架并且在使用的時候還有一大堆限制,必須使用他的東西還沒辦法做到和dbcontext原生的使用方法。
sharding-core目前使用的是一種類似dbcontext的wrap模式,用一個新的dbcontext來包裝真實的dbcontext,這個包裝的dbcontext我們成為shardingdbcontext,shardingDbContext因為本身也是集成于DbContext所以它的使用方法和原生dbcontext沒有差別。并且僅需少量改動即可支持abp和abp.next

讀寫分離的支持

目前sharding-core已經(jīng)支持單node節(jié)點的讀寫分離操作,將在不久的未來(1-2)天內(nèi)支持多節(jié)點的讀寫分離

            services.AddShardingDbContext<ShardingDefaultDbContext, DefaultDbContext>(o => o.UseSqlServer(hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"])
                ,op =>
                {
                    op.EnsureCreatedWithOutShardingTable = true;
                    op.CreateShardingTableOnStart = true;
                    op.UseShardingOptionsBuilder((connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger),
                        (conStr,builder)=> builder.UseSqlServer("read db connection string").UseLoggerFactory(efLogger));
                    op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
                    op.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
                });

未來計劃將支持分庫,支持強制路由,顯示路由等...

最后具體如何使用且使用方式可以參考github(https://github.com/xuejmnet/sharding-core)

到此這篇關(guān)于efcore-ShardingCore呈現(xiàn)“完美”分表的文章就介紹到這了,更多相關(guān)ShardingCore“完美”分表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • LINQ教程之LINQ簡介

    LINQ教程之LINQ簡介

    這篇文章介紹了語言集成查詢LINQ,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • asp.net實現(xiàn)識別客戶端瀏覽器或操作系統(tǒng)

    asp.net實現(xiàn)識別客戶端瀏覽器或操作系統(tǒng)

    這里給大家匯總了使用asp.net實現(xiàn)識別客戶端瀏覽器或操作系統(tǒng)的方法和示例代碼,有需要的小伙伴可以參考下。
    2015-10-10
  • asp.net后臺注冊js的四種方法分享

    asp.net后臺注冊js的四種方法分享

    這篇文章主要介紹了asp.net后臺注冊js的四種方法,有需要的朋友可以參考一下
    2014-01-01
  • .NET Core類庫System.Reflection.DispatchProxy實現(xiàn)簡易Aop的方法

    .NET Core類庫System.Reflection.DispatchProxy實現(xiàn)簡易Aop的方法

    這篇文章主要給大家介紹了關(guān)于.NET Core類庫System.Reflection.DispatchProxy實現(xiàn)簡易Aop的相關(guān)資料,文中通過示例代碼結(jié)束的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • ASP.NET Core異常和錯誤處理(8)

    ASP.NET Core異常和錯誤處理(8)

    這篇文章主要為大家詳細(xì)介紹了ASP.NET Core異常和錯誤處理的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • asp.net viewstate 回發(fā)機制

    asp.net viewstate 回發(fā)機制

    ASP.NET中,為了模擬Winform中的事件響應(yīng)機制,微軟的工程師真是煞費苦心,發(fā)明了“回發(fā)”機制,使得編寫WEB頁面變得和Winform一樣簡單。
    2010-03-03
  • ASP.NET Core MVC學(xué)習(xí)教程之路由(Routing)

    ASP.NET Core MVC學(xué)習(xí)教程之路由(Routing)

    這篇文章主要給大家介紹了關(guān)于ASP.NET Core MVC學(xué)習(xí)教程之路由(Routing)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用ASP.NET Core MVC具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • ASP.NET?Core項目中調(diào)用WebService的方法

    ASP.NET?Core項目中調(diào)用WebService的方法

    這篇文章介紹了ASP.NET?Core項目中調(diào)用WebService的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • 如何在前臺腳本通過json傳遞數(shù)據(jù)到后臺(使用微軟自帶的ajax)

    如何在前臺腳本通過json傳遞數(shù)據(jù)到后臺(使用微軟自帶的ajax)

    這篇文章主要介紹了如何使用微軟自帶的ajax在前臺腳本通過json傳遞數(shù)據(jù)到后臺的實現(xiàn)方法
    2013-08-08
  • .net頁面訪問次數(shù)統(tǒng)計實現(xiàn)原理與代碼

    .net頁面訪問次數(shù)統(tǒng)計實現(xiàn)原理與代碼

    網(wǎng)站訪問量統(tǒng)計、頁面訪問次數(shù)統(tǒng)計,比較實用的一個功能,很多新手朋友都想實現(xiàn),本文處于此目的整理了一些,感興趣的朋友可以了解下
    2013-01-01

最新評論