Meie PostgreSQL andmebaasi struktuur on edukalt projekteeritud suhtluse salvestamiseks. Aasta on möödunud, ja kasutajad tÀidavad seda aktiivselt, seal on juba miljoneid kirjeid, ja⊠midagi on hakanud veidi aeglaselt töötama.
- Osa 2: sektsioneerime «elus»

Asi on selles, et koos tabeli mahu suurenemisega suureneb ka indeksite «sĂŒgavus» â kuigi logaritmiliselt. Kuid aja jooksul nĂ”uab see serverilt sama lugemise/kirjutamise ĂŒlesande tĂ€itmiseks oluliselt rohkem andmelehti, kui alguses.
Siinkohal tuleb appi sektsioneerimine.
Tahan mÀrkida, et teema ei ole sharding, see tÀhendab andmete jaotamine erinevate andmebaaside vÔi serverite vahel. Sest isegi kui jagate andmed mitu serverite vahel, ei pÀÀse te probleemi «indeksite paisumise» eest aja jooksul. Selge on, et kui saate endale lubada iga pÀev uue serveri kasutusele vÔtta, siis on teie probleemid juba hoopis teised kui konkreetse andmebaasi tasandil.
Keskendume mitte konkreetsetele skriptidele sektsioneerimise rakendamiseks «rauda», vaid lĂ€henemisele â mida ja kuidas tuleks «tĂŒkeldada», ja milleni selline soov viib.
Kontseptsioon
MÀÀratleme meie eesmÀrgi uuesti: tahame tagada, et nii tÀna, homme kui ka aasta pÀrast jÀÀb PostgreSQL andmete loetavus igasuguste lugemise/kirjutamise operatsioonide puhul enam-vÀhem samaks.
Igasuguste ajalooliselt kogutud andmete (teated, dokumendid, logid, arhiivid, âŠ) loomulikuks sektsioonivĂ”tme valikuks on sĂŒndmuse kuupĂ€ev/aeg. Meie puhul on selliseks sĂŒndmuseks teate saatmise hetk.
Tuleb mĂ€rkida, et kasutajad töötavad peaaegu alati ainult âviimastegaâ sellistest andmetest â nad lugesid viimaseid teateid, analĂŒĂŒsivad viimaseid logisid,⊠Loomulikult vĂ”ivad nad kerida ka kauem tagasi, kuid nad teevad seda vĂ€ga harva. selliste andmetega â loetakse viimaseid sĂ”numeid, analĂŒĂŒsitakse viimaseid logisid,⊠Ei, loomulikult saavad nad ka ajas tagasi kerida, kuid nad teevad seda vĂ€ga harva.
Nendest piirangutest on ilmselge, et teate puhul on optimaalseks lahenduseks âpĂ€evasedâ sektsioonid â kuna meie kasutaja loeb peaaegu alati seda, mis on talle tulnud âtĂ€naâ vĂ”i âeileâ.
Kui me kirjutame ja loeme pĂ€eva jooksul praktiliselt ainult ĂŒhes sektsioonis, siis annab see meile ka efektiivsema mĂ€lu ja ketta kasutuse. â kuna kĂ”ik sektsiooni indeksid mahuvad hĂ”lpsasti operaatorisse, erinevalt 'suurtest ja paksudest' kogu tabelis.
samm-sammult
Ăldiselt kĂ”lab kĂ”ik eelnev kui ĂŒks pidev kasum. Ja see on saavutatav, kuid selle nimel peame korralikult pingutama â sest lahenduse sektsioneerimine ĂŒhe olendi jaoks toob kaasa vajaduse 'lĂ”hkuda' seotud.
Teade, selle omadused ja projektsioonid
Kuna otsustasime jagada sÔnumeid kuupÀevade jÀrgi, on mÔistlik jagada ka nendega seotud olendi omadusi (lisatud failid, adressaatide loetelu), ja ka sÔnumi kuupÀeva jÀrgi..
Kuna ĂŒks meie tĂŒĂŒpiline ĂŒlesanne on sĂ”numite registrite vaatamine (lugemata, sissetulevad, kĂ”ik), on loogiline, et tĂ”mmata need ka sĂ”numite kuupĂ€evade jĂ€rgi sektsioneerimise alla.

Lisame sektsioneerimise vÔtme (sÔnumi kuupÀeva) kÔikidesse tabelitesse: adressaadid, fail, registrid. SÔnumisse ei ole vaja lisada, vaid kasutada olemasolevat DateTime.
Teemad
Kuna teema on mitu sĂ”numit, siis ei ole seda samas mudelis vĂ”imalik 'lĂ”hkuda', tuleb tugineda millelegi muule. Meie puhul sobib ideaalselt esimese sĂ”numi kuupĂ€ev vestluses â see on teema loomise hetk.

Lisame sektsioneerimise vÔtme (teema kuupÀeva) kÔigisse tabelitesse: teema, osaleja.
Kuid nĂŒĂŒd seisame silmitsi kahe probleemiga:
- millises sektsioonis otsida teema sÔnumeid?
- millises sektsioonis otsida sÔnumi teemat?
Muidugi, vÔiksime jÀtkata otsimist kÔigis sektsioonides, kuid see oleks vÀga kurb ja kaotaks kÔik meie saavutused. SeetÔttu, et teada, kus konkreetselt otsida, loome loogilised lingid/viidatud sektsioonidesse:
- lisame sÔnumisse teema kuupÀeva vÀlja
- lisame teemale sÔnumite kuupÀevade komplekti selle vestluse (saab eraldi tabelina vÔi kuupÀevade massiivina)

Kuna iga konkreetse vestluse sĂ”numite kuupĂ€evade nimekirja modifikatsioonid jÀÀvad vĂ€heseks (peaaegu kĂ”ik sĂ”numid satuvad 1-2 kĂŒlgnevale pĂ€evale), eelistan just sellist varianti.
KokkuvÔtteks, meie andmebaasi struktuur omandas jÀrgmise ilme sektsioneerimise arvesse vÔttes:
Tabelid: RU, kui viha on kirillitsa tabelite/valdkondade nimedes, siis parem mitte vaadata.
-- sektsioonid, mis pÔhinevad sÔnumi kuupÀeval
CREATE TABLE "SÔnum_YYYYMMDD"(
"SÔnum"
uuid
PRIMARY KEY
, "Teema"
uuid
, "TeemaKuupÀev"
date
, "Autor"
uuid
, "KuupÀevAeg" -- kasutame kuupÀeva
timestamp
, "Tekst"
text
);
CREATE TABLE "Adressaat_YYYYMMDD"(
"SÔnumiKuupÀev"
date
, "SÔnum"
uuid
, "Isik"
uuid
, PRIMARY KEY("SÔnum", "Isik")
);
CREATE TABLE "Fail_YYYYMMDD"(
"SÔnumiKuupÀev"
date
, "Fail"
uuid
PRIMARY KEY
, "SÔnum"
uuid
, "BLOB"
uuid
, "Nimi"
text
);
CREATE TABLE "SÔnumiteRegistr_YYYYMMDD"(
"SÔnumiKuupÀev"
date
, "Omandaja"
uuid
, "RegistriTĂŒĂŒp"
smallint
, "KuupÀevAeg"
timestamp
, "SÔnum"
uuid
, PRIMARY KEY("Omandaja", "RegistriTĂŒĂŒp", "SĂ”num")
);
CREATE INDEX ON "SĂ”numiteRegistr_YYYYMMDD"("Omandaja", "RegistriTĂŒĂŒp", "KuupĂ€evAeg" DESC);
-- sektsioonid, mis pÔhinevad teema kuupÀeval
CREATE TABLE "Teema_YYYYMMDD"(
"TeemaKuupÀev"
date
, "Teema"
uuid
PRIMARY KEY
, "Dokument"
uuid
, "Pealkiri"
text
);
CREATE TABLE "TeemaOsaleja_YYYYMMDD"(
"TeemaKuupÀev"
date
, "Teema"
uuid
, "Isik"
uuid
, PRIMARY KEY("Teema", "Isik")
);
CREATE TABLE "SÔnumiteTeemaKuupÀevad_YYYYMMDD"(
"TeemaKuupÀev"
date
, "Teema"
uuid
PRIMARY KEY
, "KuupÀev"
date
);
Kasutame kokkuhoiuks
Aga kui me ei kasuta vÀÀrtuste jaotuse alusel (triggereid ja pÀrimise vÔi PARTITION BY kaudu), ning "kÀsitsi" rakenduse tasemel, vÔib mÀrgata, et jaotusklausi vÀÀrtus on juba salvestatud tabeli enda nime.
Seega, kui te olete nii murelik salvestatud andmete mahu pĂ€rast, siis neist "ĂŒlemÀÀrastest" vĂ€li on vĂ”imalik loobuda ja pöörduda konkreetsete tabelite poole. TĂ”si, kĂ”ik valikud mitmest sektsioonist tuleb sel juhul rakenduse kĂŒljele viia.
Allikas: habr.com
