Messenger-tietokanta (osa 2): osiointi "voittoa varten"

Olemme suunnitelleet onnistuneesti PostgreSQL-tietokantamme rakenteen kirjeenvaihtoa varten, vuosi on kulunut, käyttäjät täyttävät sitä aktiivisesti ja nyt se sisältää miljoonia levyjä, ja... jokin alkoi hidastua.

Messenger-tietokanta (osa 2): osiointi "voittoa varten"
Tosiasia on, että Taulukon koon kasvaessa indeksien "syvyys" kasvaa. - tosin logaritmisesti. Mutta ajan myötä tämä pakottaa palvelimen suorittamaan samat luku-/kirjoitustehtävät käsittelee monta kertaa enemmän datasivujakuin alussa.

Tässä se tulee apuun leikkaus.

Haluan huomauttaa, että emme puhu shardingista, eli tietojen jakamisesta eri tietokantojen tai palvelimien välillä. Koska jopa tietojen jakaminen useat palvelimia, et pääse eroon indeksien "turpoamisesta" ajan myötä. On selvää, että jos sinulla on varaa ottaa uusi palvelin käyttöön joka päivä, ongelmasi eivät ole enää lainkaan tietyn tietokannan tasolla.

Emme harkitse erityisiä skriptejä osioinnin toteuttamiseksi "laitteistossa", vaan itse lähestymistapaa - mitä ja miten tulisi "leikata viipaleiksi", ja mihin tällainen halu johtaa.

käsite

Määrittelemme tavoitteemme vielä kerran: haluamme varmistaa, että tänään, huomenna ja vuoden kuluttua PostgreSQL:n lukema datamäärä pysyy suunnilleen samana luku-/kirjoitusoperaatioiden aikana.

Mille tahansa kronologisesti kertyneet tiedot (viestit, asiakirjat, lokit, arkistot, ...) luonnollinen valinta osiointiavaimeksi on tapahtuman päivämäärä/aika. Meidän tapauksessamme tällainen tapahtuma on viestin lähettämisen hetki.

Huomaa, että käyttäjät melkein aina työskentele vain "uusimpien" kanssa sellaisia ​​tietoja - he lukevat uusimmat viestit, analysoivat uusimmat lokit,... Ei, tietenkään, he voivat vierittää ajassa taaksepäin, mutta he tekevät tämän hyvin harvoin.

Näistä rajoituksista on selvää, että optimaalinen viestiratkaisu olisi "päivittäiset" osiot - loppujen lopuksi käyttäjämme lukee melkein aina, mitä hänelle tuli "tänään" tai "eilen".

Jos kirjoitamme ja luemme melkein vain yhdessä osiossa päivän aikana, tämä myös antaa meille muistin ja levyn tehokkaampi käyttö - koska kaikki osioindeksit mahtuvat helposti RAM-muistiin, toisin kuin "isot ja lihavat" koko taulukossa.

askel-askeleelta

Yleisesti ottaen kaikki edellä sanottu kuulostaa yhdeltä jatkuvalta voitolta. Ja se on saavutettavissa, mutta tätä varten meidän on yritettävä kovasti - koska päätös osioida yksi kokonaisuudesta johtaa tarpeeseen "nähdä" siihen liittyvä.

Viesti, sen ominaisuudet ja projektiot

Koska päätimme leikata viestejä päivämäärien mukaan, on järkevää jakaa myös niistä riippuvat entiteetit-ominaisuudet (liitetiedostot, vastaanottajaluettelo) ja myös viestin päivämäärän mukaan.

Koska yksi tyypillisistä tehtävistämme on juuri viestirekisterien tarkastelu (lukemattomat, saapuvat, kaikki), on myös loogista "vetää ne sisään" osiointiin viestipäivämäärän mukaan.

Messenger-tietokanta (osa 2): osiointi "voittoa varten"

Lisäämme osiointiavaimen (viestin päivämäärä) kaikkiin taulukoihin: vastaanottajat, tiedosto, rekisterit. Sinun ei tarvitse lisätä sitä itse viestiin, vaan käytä olemassa olevaa DateTimea.

Aiheet

Koska useille viesteille on vain yksi aihe, sitä ei voi "leikata" samaan malliin, vaan täytyy luottaa johonkin muuhun. Meidän tapauksessamme se on ihanteellinen ensimmäisen kirjeenvaihtoviestin päivämäärä - eli itse asiassa aiheen luomisen hetki.

Messenger-tietokanta (osa 2): osiointi "voittoa varten"

Lisää osiointiavain (aiheen päivämäärä) kaikkiin taulukoihin: aihe, osallistuja.

Mutta nyt meillä on kaksi ongelmaa kerralla:

  • Mistä osiosta minun pitäisi etsiä aiheeseen liittyviä viestejä?
  • Mistä osiosta minun pitäisi etsiä aihetta viestistä?

Voimme tietysti jatkaa hakua kaikissa osissa, mutta tämä on erittäin surullista ja mitätöi kaikki voittomme. Siksi, jotta tiedämme, mistä tarkalleen etsiä, teemme loogisia linkkejä/osoittimia osioihin:

  • lisäämme viestiin aiheen päivämäärä -kenttä
  • lisätään aiheeseen viestin päivämäärä asetettu tämä kirjeenvaihto (voi olla erillinen taulukko tai joukko päivämääriä)

Messenger-tietokanta (osa 2): osiointi "voittoa varten"

Koska jokaisen yksittäisen kirjeenvaihdon viestipäivämääräluetteloon tulee vähän muutoksia (lähes kaikki viestit osuvat 1-2 vierekkäiselle päivälle), keskityn tähän vaihtoehtoon.

Kaiken kaikkiaan tietokantamme rakenne oli seuraavanlainen ottaen huomioon osiointi:

Taulukot: RU, jos suhtaudut vastenmielisyyteen kyrillisiä aakkosia kohtaan taulukoiden/kenttien nimissä, on parempi olla katsomatta

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

Säästä kaunis penni

Entä jos emme käytä klassinen leikkausvaihtoehto kenttäarvojen jakautumisen perusteella (triggerien ja periytymisen tai PARTITION BY:n kautta) ja "manuaalisesti" sovellustasolla, huomaat, että osiointiavaimen arvo on jo tallennettu itse taulukon nimeen.

Joten jos olet niin Oletko erittäin huolissasi tallennetun datan määrästä?, voit päästä eroon näistä "ylimääräisistä" kentistä ja osoittaa tiettyjä taulukoita. Totta, kaikki valinnat useista osioista on tässä tapauksessa siirrettävä sovelluspuolelle.

Lähde: will.com

Lisää kommentti