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)航
(三十一)分區(qū)分表