Kemi projektuar me sukses strukturën e bazës sonë të PostgreSQL për ruajtjen e bisedave, ka kaluar një vit, përdoruesit e mbushin atë aktivisht, këtu ka tashmë miliona regjistrime, dhe⊠diçka ka filluar të ngadalësohet.
- Pjesa 2: sekcionimi "në kohë reale"

ĂĂ«shtja Ă«shtĂ« se me rritjen e volumit tĂ« tryezĂ«s rritet edhe "thellĂ«sia" e indekseve â ndonĂ«se nĂ« mĂ«nyrĂ« logarithmike. Por me kalimin e kohĂ«s kjo e detyron serverin tĂ« pĂ«rpunojĂ« pĂ«r tĂ« njĂ«jtat detyra tĂ« leximit/shkrimit shumĂ« mĂ« tepĂ«r faqe tĂ« dhĂ«nash, se sa nĂ« fillim.
Këtu është në ndihmë sekcionimi.
VĂ«rej se nuk po flas pĂ«r sharding, pra shpĂ«rndarjen e tĂ« dhĂ«nave midis bazave tĂ« ndryshme ose serverĂ«ve. Sepse, edhe nĂ«se ndan tĂ« dhĂ«nat nĂ« disa serverĂ«t, nuk do tĂ« eleminosh dot problemin e "zmadhojnĂ«" indekseve me kalimin e kohĂ«s. ĂshtĂ« e qartĂ« se nĂ«se mund tĂ« lejojmĂ« çdo ditĂ« tĂ« fusim nĂ« funksion njĂ« server tĂ« ri, atĂ«herĂ« problemet tona do tĂ« kalonin nĂ« njĂ« nivel krejt tjetĂ«r, jashtĂ« asaj tĂ« veçantĂ«s sĂ« BDs.
Ne do tĂ« shqyrtojmĂ« jo skenarĂ«t e veçantĂ« pĂ«r implementimin e sekcionimit "nĂ« harduer", por qasjen vetĂ« â se çfarĂ« dhe si duhet "prerĂ« nĂ« copa", dhe çfarĂ« tĂ« tilla dĂ«shira sjell.
Koncepti
Një herë tjetër le të përcaktojmë qëllimin tonë: ne dëshirojmë që dhe sot, dhe nesër, dhe pas një viti numri i të dhënave PostgreSQL të lexueshme gjatë çdo operacioni leximi/shkrimi të mbetet përafërsisht i njëjtë.
PĂ«r çdo lloj tĂ« dhĂ«nash qĂ« akumulohet nĂ« mĂ«nyrĂ« kronologjike (mesazhe, dokumente, loge, arkiva, âŠ) zgjedhja natyrale si çelĂ«si pĂ«r ndarjen Ă«shtĂ« data/koha e ngjarjes. NĂ« rastin tonĂ«, kjo ngjarje Ă«shtĂ« momentin e dĂ«rgimit tĂ« mesazhit.
VĂ«rej se pĂ«rdoruesit zakonisht punojnĂ« vetĂ«m me "tĂ« fundit" tĂ« dhĂ«na tĂ« tilla â lexojnĂ« mesazhet mĂ« tĂ« fundit, analizojnĂ« loget mĂ« tĂ« fundit,⊠Jo, natyrisht, ata mund tĂ« shfletojnĂ« edhe mĂ« ngadalĂ« prapa nĂ« kohĂ«, por e bĂ«jnĂ« atĂ« shumĂ« rrallĂ«.
Nga kĂ«to kufizime bĂ«het e qartĂ« se zgjidhja mĂ« optimale pĂ«r mesazhet do tĂ« jenĂ« "seksionet pĂ«r ditĂ«" â sepse pothuajse gjithmonĂ« pĂ«rdoruesi ynĂ« do tĂ« lexojĂ« atĂ« qĂ« i ka ardhur "sot" ose "dje".
NĂ«se gjatĂ« ditĂ«s shkruajmĂ« dhe lexojmĂ« nĂ« mĂ«nyrĂ« praktike vetĂ«m nĂ« njĂ« seksion, atĂ«herĂ« kjo na japin gjithashtu pĂ«rdorim mĂ« efektiv tĂ« memories dhe diskut â sepse tĂ« gjithĂ« indeksat e seksionit lehtĂ« mund tĂ« mbahen nĂ« RAM, nĂ« krahasim me "tĂ« mĂ«dhenjtĂ« dhe tĂ« rĂ«ndĂ«" nĂ« tĂ« gjithĂ« tryezĂ«n.
hapi-pas-hapi
Dhe pra, gjithĂ« çka u tha mĂ« lart tingĂ«llon si njĂ« fitim i pashembullt. Dhe ai Ă«shtĂ« i arritshĂ«m, por pĂ«r kĂ«tĂ« duhet tĂ« punojmĂ« mirĂ« â sepse zgjidhja pĂ«r tĂ« sekcionuar njĂ« nga entitetet e krijon nevojĂ«n pĂ«r "prerjen" e entiteteve tĂ« lidhura me tĂ«.
Mesazhi, vetitë e tij dhe projekcionet
Përderisa vendosëm të presim mesazhet sipas datave, ka sens të ndajmë gjithashtu edhe entitetet e varura prej tyre (skedarë të bashkangjitur, lista e marrësve), dhe po ashtu sipas datës së mesazhit.
Duke qenë se një nga detyrat tona tipike është pikërisht shikimi i regjistrave të mesazheve (të pa lexuara, të ardhshme, të gjitha), është logjike që ato gjithashtu të "përfshihen" në sekcionimin sipas datave të mesazheve.

Shtojmë çelësin e sekcionimit (datën e mesazhit) në të gjitha tryezat: marrësit, skedari, regjistrat. Në mesazh vetë nuk mund të shtojmë, por të përdorim Datën e Koha ekzistuese.
Temat
Duke qenĂ« se tema Ă«shtĂ« njĂ« pĂ«r disa mesazhe, e "prerĂ«" nĂ« modelin e njĂ«jtĂ« nuk do tĂ« jetĂ« e mundur, duhet tĂ« mbĂ«shtetemi nĂ« diçka tjetĂ«r. NĂ« rastin tonĂ«, pĂ«rkryer pĂ«r kĂ«tĂ« Ă«shtĂ« data e mesazhit tĂ« parĂ« nĂ« bisedĂ« â pra momenti i krijimit, vetĂ« tema.

Shtojmë çelësin e sekcionimit (datën e temës) në të gjitha tryezat: tema, pjesëmarrësi.
Por tani kemi shfaqur menjëherë dy probleme:
- në cilin seksion të kërkojmë mesazhet sipas temës?
- në cilin seksion të kërkojmë temën nga mesazhi?
Mund ta vazhdojmë të kërkojmë në të gjitha seksionet, por kjo do të ishte shumë e trishtueshme dhe do të anulonte të gjitha përfitimet tona. Prandaj, për të ditur se ku saktësisht të kërkojmë, do të bëjmë lidhje logjike/indikatore për seksionet:
- në mesazh do të shtojmë një fushë me datën e temës
- temës do t'i shtojmë një set datash të mesazheve të këtij bisedimi (mund të jetë një tryezë e veçantë, ose një masë e datave)

Duke qenë se modifikimet e listës së datave të mesazheve për çdo bisedë do të jenë të pakta (sepse shumica e mesazheve bien në 1-2 ditët përkatëse), unë do të ndalëm pikërisht në një variant të tillë.
Pra, struktura e bazës sonë mori pamjen e mëposhtme me marrë parasysh sekcionimin:
Tabelat: RU, nëse keni një reagim të keq ndaj cirilikës në emrat e tabelave/fushave, është më mirë të mos shikoni
-- seksionet sipas datës së mesazhit
CREATE TABLE "Mesazhi_YYYYMMDD"(
"Mesazhi"
uuid
PRIMARY KEY
, "Tema"
uuid
, "DataTema"
date
, "Autori"
uuid
, "DataKoha" -- përdorim si datë
timestamp
, "Teksti"
text
);
CREATE TABLE "Adresati_YYYYMMDD"(
"DataMesazhit"
date
, "Mesazhi"
uuid
, "Personi"
uuid
, PRIMARY KEY("Mesazhi", "Personi")
);
CREATE TABLE "Skedari_YYYYMMDD"(
"DataMesazhit"
date
, "Skedari"
uuid
PRIMARY KEY
, "Mesazhi"
uuid
, "BLOB"
uuid
, "Emri"
text
);
CREATE TABLE "RegjistriMesazheve_YYYYMMDD"(
"DataMesazhit"
date
, "Pronari"
uuid
, "TipiRegjistrit"
smallint
, "DataKoha"
timestamp
, "Mesazhi"
uuid
, PRIMARY KEY("Pronari", "TipiRegjistrit", "Mesazhi")
);
CREATE INDEX ON "RegjistriMesazheve_YYYYMMDD"("Pronari", "TipiRegjistrit", "DataKoha" DESC);
-- seksionet sipas datës së temës
CREATE TABLE "Tema_YYYYMMDD"(
"DataTema"
date
, "Tema"
uuid
PRIMARY KEY
, "Dokumenti"
uuid
, "Emri"
text
);
CREATE TABLE "PjesëmarrësiTemës_YYYYMMDD"(
"DataTema"
date
, "Tema"
uuid
, "Personi"
uuid
, PRIMARY KEY("Tema", "Personi")
);
CREATE TABLE "DatatMesazheveTemës_YYYYMMDD"(
"DataTema"
date
, "Tema"
uuid
PRIMARY KEY
, "Data"
date
);
Kënësojme pak
Por, nĂ«se nuk pĂ«rdorim nĂ« bazĂ« tĂ« shpĂ«rndarjes sĂ« vlerave tĂ« fushĂ«s (nĂ«pĂ«rmjet triggers dhe trashĂ«gimisĂ« ose PARTITION BY), por âduke e bĂ«rĂ«â manualisht nĂ« nivelin e aplikacionit, mund tĂ« vĂ«rejmĂ« se vlera e çelĂ«sit tĂ« sekcionimit tashmĂ« ruhet nĂ« emrin e vetĂ« tabelĂ«s.
Prandaj, nĂ«se shqetĂ«soheni aq shumĂ« pĂ«r volumet e tĂ« dhĂ«nave tĂ« ruajtura, atĂ«herĂ« mund tĂ« heqim kĂ«to âtĂ« tepĂ«rtaâ fusha dhe tĂ« drejtohemi direkt nĂ« tabelat specifike. MegjithatĂ«, tĂ« gjitha zgjedhjet nga disa seksione nĂ« kĂ«tĂ« rast do tĂ« duhet tĂ« kalohen nĂ« anĂ«n e aplikacionit.
Burimi: habr.com
