FreeSql 教程 (三十一)分區(qū)分表

FreeSql 以 MIT 開(kāi)源協(xié)議托管于 github:https://github.com/2881099/FreeSql

分區(qū)

分區(qū)就是把一個(gè)數(shù)據(jù)表的文件和索引分散存儲(chǔ)在不同的物理文件中。把一張表的數(shù)據(jù)分成N多個(gè)區(qū)塊,這些區(qū)塊可以在同一個(gè)磁盤(pán)上,也可以在不同的磁盤(pán)上,數(shù)據(jù)庫(kù)不同實(shí)現(xiàn)方式有所不同。

與分表不同,一張大表進(jìn)行分區(qū)后,他還是一張表,不會(huì)變成二張表,但是他存放數(shù)據(jù)的區(qū)塊變多了。分區(qū)的概念,我覺(jué)得就想突破磁盤(pán)I/O瓶頸,想提高磁盤(pán)的讀寫(xiě)能力,來(lái)增加數(shù)據(jù)庫(kù)的性能。

分區(qū)實(shí)現(xiàn)是比較簡(jiǎn)單的,建立分區(qū)表,根建平常的表沒(méi)什么區(qū)別,并且對(duì)開(kāi)發(fā)代碼端來(lái)說(shuō)是透明。

postgresql10以上的自動(dòng)分區(qū)分表功能:

1、首先創(chuàng)建主分區(qū)表:

create table fenbiao(
id int,
year varchar
) partition by list(year)

這里設(shè)置的是根據(jù)year列進(jìn)行數(shù)據(jù)分表;創(chuàng)建后使用navicat是看不到的;

2.創(chuàng)建分表:

create table fenbiao_2017 partition of fenbiao for values in ('2017');
create table fenbiao_2018 partition of fenbiao for values in ('2018');

這樣這兩天數(shù)據(jù)會(huì)依靠規(guī)則插入到不同分表中,如果插入一條不符合規(guī)則的數(shù)據(jù),則會(huì)報(bào)錯(cuò)誤:no partition of relation "fenbiao" found for row.

分表

分表從表面意思上看呢,就是把一張表分成N多個(gè)小表,每一個(gè)小表都是完正的一張表。分表后數(shù)據(jù)都是存放在分表里,總表只是一個(gè)外殼,存取數(shù)據(jù)發(fā)生在一個(gè)一個(gè)的分表里面。

分表后單表的并發(fā)能力提高了,磁盤(pán)I/O性能也提高了。并發(fā)能力為什么提高了呢,因?yàn)椴閷ひ淮嗡ǖ臅r(shí)間變短了,如果出現(xiàn)高并發(fā)的話,總表可以根據(jù)不同 的查詢(xún),將并發(fā)壓力分到不同的小表里面。

分庫(kù)分表

分庫(kù)分表把原本存儲(chǔ)于一個(gè)庫(kù)的數(shù)據(jù)分塊存儲(chǔ)到多個(gè)庫(kù)上,把原本存儲(chǔ)于一個(gè)表的數(shù)據(jù)分塊存儲(chǔ)到多個(gè)表上。

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

FreeSql.Repository 之分表

FreeSql 提供 AsTable 分表的基礎(chǔ)方法,GuidRepository 作為分存式倉(cāng)儲(chǔ)將實(shí)現(xiàn)了分表與分庫(kù)(不支持跨服務(wù)器分庫(kù))的封裝。

var logRepository = fsql.GetGuidRepository<Log>(null, oldname => $"{oldname}_201903");

上面我們得到一個(gè)日志倉(cāng)儲(chǔ)按年月分表,使用它 CURD 最終會(huì)操作 Log_201903 表。

注意事項(xiàng):

  • 不能使用 CodeFirst 遷移分表,開(kāi)發(fā)環(huán)境時(shí)仍然可以遷移 Log 表;
  • 不可在分表分庫(kù)的實(shí)體類(lèi)型中使用《延時(shí)加載》;

跨表查詢(xún)

var sql = fsql.Select<User>()
    .AsTable((type, oldname) => "table_1")
    .AsTable((type, oldname) => "table_2")
    .AsTable((type, oldname) => "table_3")
    .ToSql(a => a.Id);

得到SQL:

select * from (SELECT a."Id" as1 FROM "table_1" a) ftb 
UNION ALL
select * from (SELECT a."Id" as1 FROM "table_2" a) ftb 
UNION ALL
select * from (SELECT a."Id" as1 FROM "table_3" a) ftb

多表查詢(xún):

var sql = fsql.Select<User>().LeftJoin<UserGroup>((a,b) => a.UserGroupId == b.Id)
    .AsTable((type, oldname) => oldname + "_1")
    .AsTable((type, oldname) => oldname + "_2")
    .AsTable((type, oldname) => oldname + "_3")
    .ToSql(a => a.Id);

期待更多發(fā)散。。。

巧用AsTable

var sql = fsql.Select<User>()
    .AsTable((a, b) => "(select * from tb_topic where clicks > 10)")
    .Page(1, 10).ToList()

系列文章導(dǎo)航

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容