Databáza Messenger (časť 1): návrh základného rámca

Ako môžete preložiť obchodné požiadavky do špecifických dátových štruktúr pomocou príkladu návrhu databázy messenger od začiatku.

Databáza Messenger (časť 1): návrh základného rámca
Naša základňa nebude taká veľká a rozmiestnená, ako VKontakte alebo Badoo, ale "aby to bolo", ale bolo to dobré - funkčné, rýchle a zmestí sa na jeden server PostgreSQL – aby ste mohli niekde bokom nasadiť samostatnú inštanciu služby napr.

Preto sa nebudeme dotýkať problematiky shardingu, replikácie a geodistribuovaných systémov, ale zameriame sa na obvodové riešenia vnútri databázy.

Krok 1: Niektoré obchodné špecifiká

Naše správy nebudeme navrhovať abstraktne, ale integrujeme ich do prostredia firemná sociálna sieť. To znamená, že naši ľudia si „len nekorešpondujú“, ale komunikujú medzi sebou v rámci riešenia určitých obchodných problémov.

A aké sú úlohy podniku?... Pozrime sa na príklad Vasilija, vedúceho oddelenia vývoja.

  • "Nikolai, na túto úlohu dnes potrebujeme záplatu!"
    To znamená, že korešpondenciu možno viesť v kontexte niektorých dokument.
  • "Kolya, ideš dnes večer do Doty?"
    To znamená, že aj jeden pár účastníkov môže komunikovať súčasne na rôzne témy.
  • "Peter, Nikolay, pozrite sa v prílohe na cenník nového servera."
    Takže jedna správa môže mať viacerých príjemcov. V tomto prípade môže správa obsahovať Priložené súbory.
  • "Semyon, pozri sa tiež."
    A mala by existovať možnosť vstúpiť do existujúcej korešpondencie pozvať nového člena.

Zastavme sa teraz na tomto zozname „zrejmých“ potrieb.

Bez pochopenia aplikovaných špecifík problému a obmedzení, ktoré sú mu dané, dizajn efektívne databázová schéma vyriešiť to je takmer nemožné.

Krok 2: Minimálny logický obvod

Zatiaľ všetko funguje veľmi podobne ako e-mailová korešpondencia – tradičný obchodný nástroj. Áno, „algoritmicky“ je veľa obchodných problémov navzájom podobných, takže nástroje na ich riešenie budú štrukturálne podobné.

Opravme už získaný logický diagram vzťahov entít. Aby bol náš model zrozumiteľnejší, použijeme najprimitívnejšiu možnosť zobrazenia ER modely bez komplikácií zápisov UML alebo IDEF:

Databáza Messenger (časť 1): návrh základného rámca

V našom príklade sú osoba, dokument a binárne „telo“ súboru „externé“ entity, ktoré existujú nezávisle bez našej služby. Preto ich v budúcnosti budeme jednoducho vnímať ako nejaké odkazy „niekde“ podľa UUID.

Kresliť diagramy čo najjednoduchšie - väčšina ľudí, ktorým ich ukážete, nie sú odborníci na čítanie UML/IDEF. Ale určite kreslite.

Krok 3: Načrtnite štruktúru tabuľky

O názvoch tabuliek a políS „ruskými“ názvami polí a tabuliek možno zaobchádzať odlišne, ale je to vec vkusu. Pretože tu v Tensor neexistujú zahraniční vývojári a PostgreSQL nám umožňuje dávať mená aj v hieroglyfoch, ak áno v úvodzovkách, potom predmety radšej pomenúvame jednoznačne a zrozumiteľne, aby nevznikli nezrovnalosti.
Keďže nám veľa ľudí píše správy naraz, niektorí z nich to možno aj urobia offline, potom je najjednoduchšia možnosť používať UUID ako identifikátory nielen pre externé subjekty, ale aj pre všetky objekty v rámci našej služby. Navyše sa dajú generovať aj na strane klienta – to nám pomôže podporovať odosielanie správ, keď je databáza dočasne nedostupná a pravdepodobnosť kolízie je extrémne nízka.

Návrh štruktúry tabuľky v našej databáze bude vyzerať takto:
Tabuľky : RU

CREATE TABLE "Тема"(
  "Тема"
    uuid
      PRIMARY KEY
, "Документ"
    uuid
, "Название"
    text
);

CREATE TABLE "Сообщение"(
  "Сообщение"
    uuid
      PRIMARY KEY
, "Тема"
    uuid
, "Автор"
    uuid
, "ДатаВремя"
    timestamp
, "Текст"
    text
);

CREATE TABLE "Адресат"(
  "Сообщение"
    uuid
, "Персона"
    uuid
, PRIMARY KEY("Сообщение", "Персона")
);

CREATE TABLE "Файл"(
  "Файл"
    uuid
      PRIMARY KEY
, "Сообщение"
    uuid
, "BLOB"
    uuid
, "Имя"
    text
);

Tabuľky: EN

CREATE TABLE theme(
  theme
    uuid
      PRIMARY KEY
, document
    uuid
, title
    text
);

CREATE TABLE message(
  message
    uuid
      PRIMARY KEY
, theme
    uuid
, author
    uuid
, dt
    timestamp
, body
    text
);

CREATE TABLE message_addressee(
  message
    uuid
, person
    uuid
, PRIMARY KEY(message, person)
);

CREATE TABLE message_file(
  file
    uuid
      PRIMARY KEY
, message
    uuid
, content
    uuid
, filename
    text
);

Najjednoduchšia vec pri popise formátu je začať „rozvíjať“ graf pripojenia z tabuliek, na ktoré sa neodkazuje samých sebe nikomu.

Krok 4: Zistite neočividné potreby

To je všetko, navrhli sme databázu, do ktorej sa dá perfektne písať a nejako čítať.

Vžite sa do kože používateľa našej služby – čo s tým chceme robiť?

  • Posledné správy
    To chronologicky zoradené register „mojich“ správ na základe rôznych kritérií. Kde som jedným z príjemcov, kde som autorom, kde mi napísali a ja som neodpovedal, kde mi neodpovedali, ...
  • Účastníci korešpondencie
    Kto sa vôbec zúčastňuje tohto dlhého, dlhého chatu?

Naša štruktúra nám umožňuje vyriešiť oba tieto problémy „všeobecne“, ale nie rýchlo. Problém je v tom, že pre triedenie v rámci prvej úlohy nie je možné vytvoriť index, vhodné pre každého z účastníkov (a budete musieť extrahovať všetky záznamy) a na vyriešenie druhého potrebujete extrahovať všetky správy na túto tému.

Neúmyselné úlohy používateľa môžu byť označené tučným písmom kríž na produktivitu.

Krok 5: Inteligentná denormalizácia

Oba naše problémy vyriešia doplnkové tabuľky, v ktorých budeme duplicitná časť údajov, potrebné na to, aby sme na nich vytvorili indexy vhodné pre naše úlohy.
Databáza Messenger (časť 1): návrh základného rámca

Tabuľky : RU

CREATE TABLE "РеестрСообщений"(
  "Владелец"
    uuid
, "ТипРеестра"
    smallint
, "ДатаВремя"
    timestamp
, "Сообщение"
    uuid
, PRIMARY KEY("Владелец", "ТипРеестра", "Сообщение")
);
CREATE INDEX ON "РеестрСообщений"("Владелец", "ТипРеестра", "ДатаВремя" DESC);

CREATE TABLE "УчастникТемы"(
  "Тема"
    uuid
, "Персона"
    uuid
, PRIMARY KEY("Тема", "Персона")
);

Tabuľky: EN

CREATE TABLE message_registry(
  owner
    uuid
, registry
    smallint
, dt
    timestamp
, message
    uuid
, PRIMARY KEY(owner, registry, message)
);
CREATE INDEX ON message_registry(owner, registry, dt DESC);

CREATE TABLE theme_participant(
  theme
    uuid
, person
    uuid
, PRIMARY KEY(theme, person)
);

Tu sme použili dva typické prístupy používané pri vytváraní pomocných tabuliek:

  • Násobenie záznamov
    Pomocou jedného prvotného záznamu správy vytvoríme niekoľko nadväzujúcich záznamov v rôznych typoch registrov pre rôznych vlastníkov – pre odosielateľa aj pre príjemcu. Ale každý z registrov teraz spadá do indexu - koniec koncov, v typickom prípade budeme chcieť vidieť iba prvú stránku.
  • Jedinečné rekordy
    Zakaždým, keď posielate správu v rámci konkrétnej témy, stačí skontrolovať, či takýto záznam už neexistuje. Ak nie, pridajte ho do nášho „slovníka“.

V ďalšej časti článku si povieme implementácia delenia do štruktúry našej databázy.

Zdroj: hab.com

Pridať komentár