Messenger-database (diel 2): ​​partitionearje "foar winst"

Wy hawwe de struktuer fan ús PostgreSQL-database mei súkses ûntworpen foar it opslaan fan korrespondinsje, in jier is ferrûn, brûkers folje it aktyf yn, en no befettet it miljoenen records, en ... wat begûn te fertrage.

Messenger-database (diel 2): ​​partitionearje "foar winst"
Punt is dat As de tabelgrutte groeit, groeit ek de "djipte" fan 'e yndeksen. - al is it logaritmysk. Mar oer de tiid twingt dit de tsjinner om deselde lês-/skriuwtaken út te fieren ferwurkje in protte kearen mear siden mei gegevensas oan it begjin.

Dit is wêr't it oan 'e rêding komt seksje.

Lit my opmerke dat wy net prate oer sharding, dat is it fersprieden fan gegevens tusken ferskate databases of servers. Want sels it dielen fan de gegevens yn ferskate tsjinners, jo sille net kwyt it probleem fan yndeksen "swollen" oer de tiid. It is dúdlik dat as jo it betelje kinne om elke dei in nije server yn wurking te setten, dan sille jo problemen hielendal net mear lizze yn it fleantúch fan in spesifike databank.

Wy sille net spesifyk skripts beskôgje foar it ymplementearjen fan partitionering "yn hardware", mar de oanpak sels - wat en hoe moatte wurde "snien yn plakjes", en wat sa'n winsk liedt ta.

Konsept

Litte wy ús doel nochris definiearje: wy wolle derfoar soargje dat hjoed, moarn en oer in jier de hoemannichte gegevens lêzen troch PostgreSQL by elke lês-/skriuwoperaasje sawat itselde bliuwt.

Foar eltse gronologysk sammele gegevens (berjochten, dokuminten, logboeken, argiven, ...) de natuerlike kar as partitioneringskaai is evenemint datum / tiid. Yn ús gefal is sa'n evenemint momint fan it ferstjoeren fan it berjocht.

Tink derom dat brûkers hast altyd wurkje allinnich mei de "lêste" ones sokke gegevens - se lêze de lêste berjochten, analysearje de lêste logs, ... Nee, fansels kinne se fierder werom rôlje yn 'e tiid, mar se dogge dit heul selden.

Ut dizze beheiningen is it dúdlik dat de optimale berjochtoplossing wêze soe "deistige" seksjes - ommers, ús brûker sil hast altyd lêze wat him "hjoed" of "juster" kaam.

As wy oerdei hast mar ien rubryk skriuwe en lêze, dan jout dat ús ek effisjinter gebrûk fan ûnthâld en skiif - om't alle seksje-yndeksen maklik passe yn 'e RAM, yn tsjinstelling ta de "grutte en fet" yn 'e tabel.

stap foar stap

Yn it algemien, alles sein hjirboppe klinkt as ien trochgeande winst. En it is te berikken, mar hjirfoar sille wy hurd moatte besykje - om't it beslút om te dielen ien fan 'e entiteiten liedt ta de needsaak om "seagen" de assosjearre.

Berjocht, syn eigenskippen en projeksjes

Om't wy besletten hawwe om berjochten troch datums te snijen, is it logysk om ek de entiteiten-eigenskippen te dielen dy't derfan ôfhingje (taheakke bestannen, list mei ûntfangers), en ek troch datum fan berjocht.

Sûnt ien fan ús typyske taken is it krekt besjen fan berjochtregisters (net-lêzen, ynkommende, allegear), is it ek logysk om se "yn te tekenjen" yn partitionearjen troch berjochtdatums.

Messenger-database (diel 2): ​​partitionearje "foar winst"

Wy foegje de partitioning-kaai (berjochtdatum) ta oan alle tabellen: ûntfangers, triem, registers. Jo hoege it net ta te foegjen oan it berjocht sels, mar brûk de besteande DateTime.

Underwerpen

Om't d'r mar ien ûnderwerp is foar ferskate berjochten, is d'r gjin manier om it yn itselde model te "knipjen"; jo moatte op wat oars fertrouwe. Yn ús gefal is it ideaal datum fan earste berjocht yn korrespondinsje - dat is, it momint fan skepping, yn feite, fan it ûnderwerp.

Messenger-database (diel 2): ​​partitionearje "foar winst"

Foegje de partitioneringskaai (ûnderwerpdatum) ta oan alle tabellen: ûnderwerp, dielnimmer.

Mar no hawwe wy twa problemen tagelyk:

  • Yn hokker seksje moat ik sykje nei berjochten oer it ûnderwerp?
  • Yn hokker seksje moat ik sykje nei it ûnderwerp út it berjocht?

Wy kinne, fansels, fierder te sykjen yn alle seksjes, mar dit sil wêze hiel tryst en sil negate al ús winst. Dêrom, om te witten wêr't wy krekt moatte sykje, sille wy logyske keppelings / oanwizers meitsje nei seksjes:

  • wy sille tafoegje yn it berjocht ûnderwerp date fjild
  • lit ús tafoegje oan it ûnderwerp berjocht datum set dizze korrespondinsje (kin in aparte tabel wêze, as in array fan datums)

Messenger-database (diel 2): ​​partitionearje "foar winst"

Om't d'r in pear wizigingen sille wêze oan 'e list mei berjochtdatums foar elke yndividuele korrespondinsje (nei alle gedachten falle hast alle berjochten op 1-2 neistlizzende dagen), sil ik my rjochtsje op dizze opsje.

Yn totaal naam de struktuer fan ús databank de folgjende foarm, rekken hâldend mei partitionering:

Tabellen: RU, as jo in ôfkear hawwe fan it Syrillyske alfabet yn 'e nammen fan tabellen / fjilden, is it better net te sjen

-- секции по дате сообщения
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
);

Besparje in moaie penny

No, wat as wy net brûke klassike seksje opsje basearre op de ferdieling fan fjildwearden (fia triggers en erfskip as PARTITION BY), en "hânmjittich" op it tapassingsnivo, sille jo merke dat de wearde fan 'e partitioning-kaai al is opslein yn' e namme fan 'e tabel sels.

Dus as jo sa binne Binne jo tige soargen oer de hoemannichte gegevens opslein?, dan kinne jo dizze "ekstra" fjilden kwytreitsje en spesifike tabellen adressearje. Wier, alle seleksjes út ferskate seksjes yn dit gefal sille moatte wurde oerbrocht nei de applikaasje kant.

Boarne: www.habr.com

Add a comment