<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          .NET ORM 分表分庫【到底】怎么做?

          共 5312字,需瀏覽 11分鐘

           ·

          2020-09-01 16:59

          一、理論知識

          分表 - 從表面意思上看呢,就是把一張表分成N多個小表,每一個小表都是完正的一張表。分表后數(shù)據(jù)都是存放在分表里,總表只是一個外殼,存取數(shù)據(jù)發(fā)生在一個一個的分表里面。分表后單表的并發(fā)能力提高了,磁盤I/O性能也提高了。并發(fā)能力為什么提高了呢,因為查尋一次所花的時間變短了,如果出現(xiàn)高并發(fā)的話,總表可以根據(jù)不同 的查詢,將并發(fā)壓力分到不同的小表里面。

          分庫 - 把原本存儲于一個庫的數(shù)據(jù)分塊存儲到多個庫上,把原本存儲于一個表的數(shù)據(jù)分塊存儲到多個表上。數(shù)據(jù)庫中的數(shù)據(jù)量不一定是可控的,在未進(jìn)行分表分庫的情況下,隨著時間和業(yè)務(wù)的發(fā)展,庫中的表會越來越多,表中的數(shù)據(jù)量也會越來越大,相應(yīng)地,數(shù)據(jù)操作,增刪改查的開銷也會越來越大;另外,一臺服務(wù)器的資源(CPU、磁盤、內(nèi)存、IO等)是有限的,最終數(shù)據(jù)庫所能承載的數(shù)據(jù)量、數(shù)據(jù)處理能力都將遭遇瓶頸

          二、情懷滿滿

          分表、分庫在 .NET 下可謂是老大難題,簡單點可以使用類似 mycat 中間件,但是就 .NET 平臺的自身生態(tài),很缺乏類似 sharding-jdbc 這樣強大的輪子。

          本人就自身有限的技術(shù)水平和經(jīng)驗,對分表、分庫進(jìn)行分析,實現(xiàn)出自成一套的使用方法,雖然不極 sharding-jdbc 強大,但是還算比較通用、簡單。但愿有朝一日出現(xiàn)一批真正 .NET 大神,造出偉大的開源項目,實現(xiàn)你我心中的抱負(fù)。

          這套分表、分庫方法是建立在 .NET ORM FreeSql 之上做的,內(nèi)容可能比較抽象,敬請諒解!后續(xù)會詳解各種租戶設(shè)計方案,除了按字段區(qū)分租戶,還包括分庫、分表的方案,敬請關(guān)注!

          三、入戲準(zhǔn)備

          FreeSql 是 .Net ORM,能支持 .NetFramework4.0+、.NetCore、Xamarin、XAUI、Blazor、以及還有說不出來的運行平臺,因為代碼綠色無依賴,支持新平臺非常簡單。目前單元測試數(shù)量:5000+,Nuget下載數(shù)量:180K+,源碼幾乎每天都有提交。值得高興的是 FreeSql 加入了 ncc 開源社區(qū):https://github.com/dotnetcore/FreeSql,加入組織之后社區(qū)責(zé)任感更大,需要更努力做好品質(zhì),為開源社區(qū)出一份力。

          QQ群:4336577(已滿)、8578575(在線)、52508226(在線)

          為什么要重復(fù)造輪子?

          FreeSql 主要優(yōu)勢在于易用性上,基本是開箱即用,在不同數(shù)據(jù)庫之間切換兼容性比較好。作者花了大量的時間精力在這個項目,肯請您花半小時了解下項目,謝謝。功能特性如下:

          • 支持 CodeFirst 對比結(jié)構(gòu)變化遷移;
          • 支持 DbFirst 從數(shù)據(jù)庫導(dǎo)入實體類;
          • 支持 豐富的表達(dá)式函數(shù),自定義解析;
          • 支持 批量添加、批量更新、BulkCopy;
          • 支持 導(dǎo)航屬性,貪婪加載、延時加載、級聯(lián)保存;
          • 支持 讀寫分離、分表分庫,租戶設(shè)計;
          • 支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/達(dá)夢/神通/人大金倉/MsAccess;FreeSql 使用非常簡單,【單機(jī)數(shù)據(jù)庫】只需要定義一個 IFreeSql 對象即可:
          static IFreeSql fsql = new FreeSql.FreeSqlBuilder()    .UseConnectionString(FreeSql.DataType.MySql, connectionString)    .UseAutoSyncStructure(true) //自動同步實體結(jié)構(gòu)到數(shù)據(jù)庫    .Build(); //請務(wù)必定義成 Singleton 單例模式

          四、分表

          既然是分表,那就大膽認(rèn)為他是操作【單機(jī)數(shù)據(jù)庫】,只需要對實體類進(jìn)行動態(tài)映射表名即可實現(xiàn),F(xiàn)reeSql 原生用法、FreeSql.Repository 倉儲用法 都提供了 AsTable 方法對分表進(jìn)行 CRUD 操作,例如:

          var repo = fsql.GetRepository();repo.AsTable(oldname => $"{oldname}_201903");//對 Log_201903 表 CRUD
          repo.Insert(new Log { ... });repo.Update(...);repo.Delete(...);repo.Select...;

          AsTable 動態(tài)設(shè)置實體映射的表名,達(dá)到對分表的操作目的。除了 CRUD 操作,還提供了創(chuàng)建分表的功能:

          • 如果開啟了自動同步結(jié)構(gòu)功能 UseAutoSyncStructure(true),則 AsTable 會自動創(chuàng)建對應(yīng)分表;
          • 可以使用 fsql.CodeFirst.SyncStructure(typeof(實體類), "分表名") 進(jìn)行手工建表;

          多數(shù)情況,我們都建議提前創(chuàng)建好分表,如果按月分表,手工創(chuàng)建一年的分表。目前這種算是比較簡單入門的方案,遠(yuǎn)不及 mycat、sharding-jdbc 那么智能,比如:

          • 不能利用分表字段自動進(jìn)行分表映射;
          • 不能在查詢時根據(jù) where 條件自動映射分表,甚至跨多個分表的聯(lián)合查詢;

          五、分庫(單機(jī))

          分庫,但是在同一個數(shù)據(jù)庫服務(wù)器實例下。這種情況也可以使用 AsTable 方式進(jìn)行操作,如下:

          var repo = fsql.GetRepository();repo.AsTable(oldname => $"{201903}.dbo.{oldname}");//對 [201903].dbo.Log CRUD

          分庫之后,老大難題是事務(wù),如果使用 SqlServer 可以利用 TransactionScope 做簡單的跨庫事務(wù),如下:

          var repoLog = fsql.GetRepository();var repoComment = fsql.GetRepository();repoLog.AsTable(oldname => $"{201903}.dbo.{oldname}");repoComment.AsTable(oldname => $"{201903}.dbo.{oldname}");
          using (TransactionScope ts = new TransactionScope()){ repoComment.Insert(new Comment { ... }); repoLog.Insert(new Log { ... }); ts.Complete();}

          六、分庫(跨服務(wù)器)

          前面提到:【單機(jī)數(shù)據(jù)庫】只需要定義一個 IFreeSql 對象即可。那分庫是不是要定義很多個 IFreeSql 對象?答案是的。

          一般思路可以定義 static ConcurrentDictionary 存儲所有 IFreeSql 對象(key = ConnectionString),當(dāng)進(jìn)行 CRUD 時獲取到對應(yīng)的 IFreeSql 即可。由于 IFreeSql 是靜態(tài)單例設(shè)計長駐內(nèi)存,分庫數(shù)量太多的時候會浪費資源,因為不是所有分庫都一直一直在訪問。例如租戶分庫 10000 個,定義 10000 個 static IFreeSql?

          更好的辦法可以使用 IdleBus 空閑對象管理容器,有效組織對象重復(fù)利用,自動創(chuàng)建、銷毀,解決【實例】過多且長時間占用的問題。有時候想做一個單例對象重復(fù)使用提升性能,但是定義多了,有的又可能一直空閑著占用資源。專門解決:又想重復(fù)利用,又想少占資源的場景。https://github.com/2881099/IdleBus

          dotnet add package IdleBus

          static IdleBus ib = new IdleBus(TimeSpan.FromMinutes(10));
          ib.Register("db1", () => new FreeSqlBuilder().UseConnectionString(DataType.MySql, "str1").Build());ib.Register("db2", () => new FreeSqlBuilder().UseConnectionString(DataType.MySql, "str2").Build());ib.Register("db3", () => new FreeSqlBuilder().UseConnectionString(DataType.SqlServer, "str3").Build());//...注冊很多個
          ib.Get("db1").Select().Limit(10).ToList();

          IdleBus 也是【單例】設(shè)計!主要的兩個方法,注冊,獲取。idlebus 注冊不是創(chuàng)建 IFreeSql,首次 Get 時才創(chuàng)建,后面會一直用已經(jīng)創(chuàng)建的。還有一個超時機(jī)制,如果 10 分鐘該 IFreeSql 未使用會被 Dispose,然后下一次又會創(chuàng)建新的 IFreeSql,如此反復(fù)。從而解決了 10000 個 IFreeSql 長駐內(nèi)存的問題。

          還利用 AsyncLocal 特性擴(kuò)展使用起來更加方便:

          public static class IdleBusExtesions{    static AsyncLocal asyncDb = new AsyncLocal();    public static IdleBus ChangeDatabase(this IdleBus ib, string db)    {        asyncDb.Value = db;        return ib;    }    public static IFreeSql Get(this IdleBus ib) => ib.Get(asyncDb.Value ?? "db1");    public static IBaseRepository GetRepository(this IdleBus ib) where T : class         => ib.Get().GetRepository();}
          • 使用 ChangeDatabase 切換 db;
          • 使用 Get() 獲取當(dāng)前 IFreeSql,省略每次都傳遞 db 參數(shù);
          • 使用 GetRepository 獲取當(dāng)前 IFreeSql 對應(yīng)的倉儲類;

          注意:使用 IdleBus 需要弱化 IFreeSql 的存在,每次都使用 ib.Get 獲取 IFreeSql 對象;

          IdleBus ib = ...; //單例注入
          var fsql = ib.Get(); //獲取當(dāng)前租戶對應(yīng)的 IFreeSql
          var fsql00102 = ib.ChangeDatabase("db2").Get(); //切換租戶,后面的操作都是針對 db2
          var songRepository = ib.GetRepository();var detailRepository = ib.GetRepository();

          目前這種算是比較簡單入門的方案,遠(yuǎn)不及 mycat、sharding-jdbc 那么智能,比如:沒有實現(xiàn)跨庫事務(wù)。

          七、寫在最后

          .NET 生態(tài)還處于較弱的狀態(tài),呼吁大家支持、踴躍參與開源項目,為下一個 .NET 開源社區(qū)五年計劃做貢獻(xiàn)。

          希望正在使用的、善良的您能動一動小手指,把文章轉(zhuǎn)發(fā)一下,讓更多人知道 .NET 有這樣一個好用的 ORM 存在。謝謝了!!

          FreeSql 開源協(xié)議 MIT https://github.com/dotnetcore/FreeSql,可以商用,文檔齊全。QQ群:4336577(已滿)、8578575(在線)、52508226(在線)

          如果你有好的 ORM 實現(xiàn)想法,歡迎給作者留言討論,謝謝觀看!

          往期精彩回顧




          【推薦】.NET Core開發(fā)實戰(zhàn)視頻課程?★★★

          .NET Core實戰(zhàn)項目之CMS 第一章 入門篇-開篇及總體規(guī)劃

          【.NET Core微服務(wù)實戰(zhàn)-統(tǒng)一身份認(rèn)證】開篇及目錄索引

          Redis基本使用及百億數(shù)據(jù)量中的使用技巧分享(附視頻地址及觀看指南)

          .NET Core中的一個接口多種實現(xiàn)的依賴注入與動態(tài)選擇看這篇就夠了

          10個小技巧助您寫出高性能的ASP.NET Core代碼

          用abp vNext快速開發(fā)Quartz.NET定時任務(wù)管理界面

          在ASP.NET Core中創(chuàng)建基于Quartz.NET托管服務(wù)輕松實現(xiàn)作業(yè)調(diào)度

          現(xiàn)身說法:實際業(yè)務(wù)出發(fā)分析百億數(shù)據(jù)量下的多表查詢優(yōu)化

          關(guān)于C#異步編程你應(yīng)該了解的幾點建議

          C#異步編程看這篇就夠了

          給我好看

          您看此文用

          ??·?

          秒,轉(zhuǎn)發(fā)只需1秒呦~

          好看你就

          點點


          瀏覽 31
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人免费看性爱大片密芽 | 国产黄在线观看 | 国产高清视频在线播放 | 天天做天天爱天天综合网 | 中文黄色毛片 |