Messenger datu-basea (2. zatia): "irabazirako" partizioa

Korrespondentzia gordetzeko gure PostgreSQL datu-basearen egitura arrakastaz diseinatu dugu, urtebete igaro da, erabiltzaileak aktiboki betetzen ari dira eta orain dauka. milioika erregistro, eta... zerbait moteltzen hasi zen.

Messenger datu-basea (2. zatia): "irabazirako" partizioa
Izan ere dela Taularen tamaina hazten doan heinean, indizeen "sakonera" ere igotzen da. - logaritmikoki bada ere. Baina denborarekin horrek zerbitzaria irakurketa/idazketa zeregin berberak egitera behartzen du hainbat aldiz datu orrialde gehiago prozesatuhasieran baino.

Hemen da erreskatea sekzioa.

Ohar dezadan ez garela shardingaz ari, hau da, datu-base edo zerbitzari ezberdinen artean datuak banatzeaz. Datuak banatuta ere hainbat zerbitzariak, ez duzu denboran zehar indizeak "hazten" diren arazoa kenduko. Argi dago egunero zerbitzari berri bat martxan jartzea ahalbidetzen baduzu, zure arazoak ez direla gehiago datu-base zehatz baten planoan egongo.

Ez dugu kontuan hartuko partizioak "hardwarean" ezartzeko script zehatzak, baizik eta ikuspegia bera - zer eta nola "xerratan moztu" behar den eta zertara ekartzen duen nahi hori.

Kontzeptua

Definitu dezagun beste behin gure helburua: ziurtatu nahi dugu gaur, bihar eta urtebete barru, edozein irakurketa/idazketa eragiketatan PostgreSQL-k irakurritako datu kopurua gutxi gorabehera berdina izaten jarraituko duela.

Edozeinentzat kronologikoki metatutako datuak (mezuak, dokumentuak, erregistroak, artxiboak, ...) zatiketa-gako gisa aukera naturala da gertaera data/ordua. Gure kasuan, halako gertaera bat da mezua bidaltzeko unea.

Kontuan izan erabiltzaileak ia beti "azken"ekin bakarrik lan egin halako datuak - azken mezuak irakurtzen dituzte, azken erregistroak aztertzen dituzte,... Ez, noski, denboran atzerago korri dezakete, baina oso gutxitan egiten dute hori.

Muga horietatik argi dago mezuen irtenbide egokiena litzatekeela "eguneroko" atalak - azken finean, gure erabiltzaileak ia beti irakurriko du β€œgaur” edo β€œatzo” etorri zaiona.

Egunean zehar ia atal batean bakarrik idazten eta irakurtzen badugu, honek ere ematen digu memoria eta diskoaren erabilera eraginkorragoa - atal indize guztiak erraz sartzen direnez RAM-ra, taulako "handien eta lodien" aldean.

urratsez urrats

Orokorrean, goian esandako guztia etengabeko irabazi baten modukoa da. Eta lorgarria da, baina horretarako gogor saiatu beharko dugu, zeren entitateetako bat banatzeko erabakiak elkartua β€œikusi” beharra dakar.

Mezua, bere propietateak eta proiekzioak

Mezuak dataka moztea erabaki genuenez, zentzuzkoa da horien araberako entitate-propietateak ere banatzea (eranskinak diren fitxategiak, hartzaileen zerrenda), eta mezuaren dataren arabera ere.

Gure ohiko zereginetako bat mezu-erregistroak ikustea denez (irakurri gabekoak, sarrerakoak, guztiak), logikoa da ere "marraztea" mezu-daten arabera banatzea.

Messenger datu-basea (2. zatia): "irabazirako" partizioa

Partizio-gakoa (mezuaren data) gehitzen dugu taula guztietan: hartzaileak, fitxategia, erregistroak. Ez duzu mezuan bertan gehitu beharrik, baina lehendik dagoen DateTime erabili.

Π’Π΅ΠΌΡ‹

Hainbat mezutarako gai bakarra dagoenez, ez dago eredu berean "moztu" modurik; beste zerbaitetan oinarritu behar duzu. Gure kasuan aproposa da korrespondentziako lehen mezuaren data β€” hau da, sortzeko unea, hain zuzen ere, gaia.

Messenger datu-basea (2. zatia): "irabazirako" partizioa

Gehitu zatiketa-gakoa (gaiaren data) taula guztietan: gaia, parte-hartzailea.

Baina orain bi arazo ditugu aldi berean:

  • Zein ataletan bilatu behar ditut gaiari buruzko mezuak?
  • Zein ataletan bilatu behar dut mezuaren gaia?

Atal guztietan bilatzen jarraitu dezakegu, noski, baina hori oso tristea izango da eta gure irabazi guztiak baliogabetuko ditu. Horregatik, zehazki non begiratu behar den jakiteko, ataletarako esteka/erakusle logikoak egingo ditugu:

  • mezuan gehituko dugu gaiaren data eremua
  • gehitu diezaiogun gaiari mezuaren data ezarrita korrespondentzia hau (taula bereizi bat izan daiteke edo data sorta bat)

Messenger datu-basea (2. zatia): "irabazirako" partizioa

Mezu-daten zerrendan aldaketa gutxi izango direnez korrespondentzia bakoitzerako (azken finean, ia mezu guztiak ondoko 1-2 egunetan sartzen dira), aukera honetan zentratuko naiz.

Guztira, gure datu-basearen egiturak honako forma hartu zuen, partizioa kontuan hartuta:

Taulak: RU, taulen/eremuen izenetan alfabeto zirilikoarekiko higuina baduzu, hobe da ez begiratzea.

-- сСкции ΠΏΠΎ Π΄Π°Ρ‚Π΅ сообщСния
CREATE TABLE "Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅_YYYYMMDD"(
  "Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅"
    uuid
      PRIMARY KEY
, "Π’Π΅ΠΌΠ°"
    uuid
, "Π”Π°Ρ‚Π°Π’Π΅ΠΌΡ‹"
    date
, "Автор"
    uuid
, "ДатаВрСмя" -- ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΊΠ°ΠΊ Π΄Π°Ρ‚Ρƒ
    timestamp
, "ВСкст"
    text
);

CREATE TABLE "АдрСсат_YYYYMMDD"(
  "ДатаБообщСния"
    date
, "Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅"
    uuid
, "ΠŸΠ΅Ρ€ΡΠΎΠ½Π°"
    uuid
, PRIMARY KEY("Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅", "ΠŸΠ΅Ρ€ΡΠΎΠ½Π°")
);

CREATE TABLE "Π€Π°ΠΉΠ»_YYYYMMDD"(
  "ДатаБообщСния"
    date
, "Π€Π°ΠΉΠ»"
    uuid
      PRIMARY KEY
, "Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅"
    uuid
, "BLOB"
    uuid
, "Имя"
    text
);

CREATE TABLE "РССстрБообщСний_YYYYMMDD"(
  "ДатаБообщСния"
    date
, "Π’Π»Π°Π΄Π΅Π»Π΅Ρ†"
    uuid
, "ВипРССстра"
    smallint
, "ДатаВрСмя"
    timestamp
, "Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅"
    uuid
, PRIMARY KEY("Π’Π»Π°Π΄Π΅Π»Π΅Ρ†", "ВипРССстра", "Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅")
);
CREATE INDEX ON "РССстрБообщСний_YYYYMMDD"("Π’Π»Π°Π΄Π΅Π»Π΅Ρ†", "ВипРССстра", "ДатаВрСмя" DESC);

-- сСкции ΠΏΠΎ Π΄Π°Ρ‚Π΅ Ρ‚Π΅ΠΌΡ‹
CREATE TABLE "Π’Π΅ΠΌΠ°_YYYYMMDD"(
  "Π”Π°Ρ‚Π°Π’Π΅ΠΌΡ‹"
    date
, "Π’Π΅ΠΌΠ°"
    uuid
      PRIMARY KEY
, "Π”ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚"
    uuid
, "НазваниС"
    text
);

CREATE TABLE "УчастникВСмы_YYYYMMDD"(
  "Π”Π°Ρ‚Π°Π’Π΅ΠΌΡ‹"
    date
, "Π’Π΅ΠΌΠ°"
    uuid
, "ΠŸΠ΅Ρ€ΡΠΎΠ½Π°"
    uuid
, PRIMARY KEY("Π’Π΅ΠΌΠ°", "ΠŸΠ΅Ρ€ΡΠΎΠ½Π°")
);

CREATE TABLE "Π”Π°Ρ‚Ρ‹Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠΉΠ’Π΅ΠΌΡ‹_YYYYMMDD"(
  "Π”Π°Ρ‚Π°Π’Π΅ΠΌΡ‹"
    date
, "Π’Π΅ΠΌΠ°"
    uuid
      PRIMARY KEY
, "Π”Π°Ρ‚Π°"
    date
);

Gorde zentimo polit bat

Tira, zer erabiltzen ez badugu zatiketa aukera klasikoa eremu-balioen banaketan oinarrituta (abiarazleen eta herentziaren edo PARTITION BY) eta aplikazio mailan "eskuz", partizio-gakoaren balioa taularen beraren izenean gordeta dagoela ohartuko zara.

Beraz, hala bazara Oso kezkatuta al zaude gordetako datu kopuruak?, orduan eremu "gehigarri" hauek ken ditzakezu eta taula zehatzak jorratu. Egia da, kasu honetan hainbat ataletako hautapen guztiak aplikazioaren aldean transferitu beharko dira.

Iturria: www.habr.com

Gehitu iruzkin berria