Podatkovna baza Messenger (1. del): oblikovanje osnovnega ogrodja

Kako lahko prevedete poslovne zahteve v posebne podatkovne strukture z uporabo primera oblikovanja baze podatkov messenger iz nič.

Podatkovna baza Messenger (1. del): oblikovanje osnovnega ogrodja
Naša baza ne bo tako velika in razpršena, kot VKontakte ali Badoo, ampak "tako, da je bilo", vendar je bilo dobro - funkcionalno, hitro in prilegajo enemu strežniku PostgreSQL - tako da lahko na primer namestite ločen primerek storitve nekje ob strani.

Zato se ne bomo dotikali vprašanj šardinga, replikacije in geo-distribuiranih sistemov, ampak se bomo osredotočili na rešitve vezij znotraj baze podatkov.

1. korak: Nekaj ​​poslovnih posebnosti

Svojih sporočil ne bomo oblikovali abstraktno, ampak jih bomo integrirali v okolje družbeno omrežje podjetja. Se pravi, naši ljudje si ne »samo dopisujejo«, ampak komunicirajo med seboj v okviru reševanja določenih poslovnih problemov.

In kakšne so naloge podjetja?.. Poglejmo primer Vasilija, vodje razvojnega oddelka.

  • "Nikolai, za to nalogo danes potrebujemo popravek!"
    To pomeni, da se dopisovanje lahko izvaja v okviru nekaterih dokument.
  • "Kolja, ali greš nocoj na Doto?"
    To pomeni, da lahko hkrati komunicira celo en par sogovornikov o različnih temah.
  • "Peter, Nikolay, poglejte v priponki cenik za nov strežnik."
    Torej, eno sporočilo lahko ima več prejemnikov. V tem primeru lahko sporočilo vsebuje Priložene datoteke.
  • "Semyon, poglej tudi ti."
    In morala bi obstajati možnost vstopa v obstoječo korespondenco povabite novega člana.

Za zdaj se osredotočimo na ta seznam »očitnih« potreb.

Brez razumevanja uporabnih posebnosti problema in omejitev, ki so mu dane, oblikovanje učinkovito sheme baze podatkov za rešitev je skoraj nemogoče.

2. korak: Minimalno logično vezje

Zaenkrat vse deluje zelo podobno kot e-poštna korespondenca - tradicionalno poslovno orodje. Da, »algoritmično« so si številni poslovni problemi podobni, zato bodo orodja za njihovo reševanje strukturno podobna.

Popravimo že dobljeni logični diagram odnosov entitet. Za lažje razumevanje našega modela bomo uporabili najbolj primitivno možnost prikaza ER modeli brez zapletov zapisov UML ali IDEF:

Podatkovna baza Messenger (1. del): oblikovanje osnovnega ogrodja

V našem primeru so oseba, dokument in binarno »telo« datoteke »zunanje« entitete, ki obstajajo neodvisno brez naše storitve. Zato jih bomo v prihodnosti preprosto dojemali kot neke povezave »nekje« po UUID.

Žrebanje čim preprostejši diagrami - večina ljudi, ki jim jih boste pokazali, ni strokovnjakov za branje UML/IDEF. Vendar ne pozabite narisati.

3. korak: Skiciranje strukture tabele

O imenih tabel in polj"Ruska" imena polj in tabel je mogoče obravnavati drugače, vendar je to stvar okusa. Zaradi tukaj pri Tensorju tujih razvijalcev ni, PostgreSQL pa nam omogoča, da dajemo imena tudi v hieroglifih, če jih v narekovajih, potem predmete raje poimenujmo nedvoumno in jasno, da ne prihaja do neskladij.
Ker nam veliko ljudi piše sporočila naenkrat, nekateri morda celo to storijo brez povezave, potem je najenostavnejša možnost uporabite UUID kot identifikatorje ne le za zunanje subjekte, ampak tudi za vse objekte znotraj naše storitve. Poleg tega jih je mogoče ustvariti tudi na strani odjemalca - to nam bo pomagalo pri pošiljanju sporočil, ko baza podatkov začasno ni na voljo in je verjetnost kolizije izjemno majhna.

Osnutek strukture tabele v naši bazi podatkov bo videti takole:
Tabele : 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
);

Tabele: 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
);

Najpreprostejša stvar pri opisovanju formata je, da začnete "odvijati" povezovalni graf iz tabel, ki niso navedene sebe nikomur.

4. korak: Ugotovite neočitne potrebe

To je to, zasnovali smo bazo podatkov, v katero lahko pišete odlično in nekako brati.

Postavimo se v kožo uporabnika naše storitve – kaj želimo s tem narediti?

  • Zadnja sporočila
    To kronološko razvrščeni register »mojih« sporočil na podlagi različnih kriterijev. Kje sem eden od prejemnikov, kje sem avtor, kje so mi pisali pa se nisem oglasil, kje mi niso odgovorili, ...
  • Udeleženci dopisovanja
    Kdo sploh sodeluje v tem dolgem, dolgem klepetu?

Naša struktura nam omogoča, da oba problema rešimo "na splošno", vendar ne hitro. Težava je v tem, da za razvrščanje znotraj prve naloge ni mogoče ustvariti indeksa, primeren za vsakega od udeležencev (in izvleči boste morali vse zapise), za rešitev drugega pa potrebujete ekstrahiraj vsa sporočila na to temo.

Nenamerna uporabniška opravila so lahko označena s krepkim tiskom križ na produktivnosti.

5. korak: Pametna denormalizacija

Oba naša problema bodo rešile dodatne tabele, v katerih bomo podvojeni del podatkov, potrebne za oblikovanje indeksov, primernih za naše naloge.
Podatkovna baza Messenger (1. del): oblikovanje osnovnega ogrodja

Tabele : RU

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

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

Tabele: 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)
);

Tukaj smo uporabili dva tipična pristopa, uporabljena pri ustvarjanju pomožnih tabel:

  • Množenje zapisov
    Z enim začetnim zapisom sporočila ustvarimo več nadaljnjih zapisov v različnih vrstah registrov za različne lastnike - tako za pošiljatelja kot za prejemnika. Toda vsak od registrov zdaj pade na indeks - navsezadnje bomo v tipičnem primeru želeli videti samo prvo stran.
  • Edinstveni zapisi
    Vsakič, ko pošljete sporočilo znotraj določene teme, je dovolj, da preverite, ali tak vnos že obstaja. Če ne, ga dodajte v naš »slovar«.

V naslednjem delu članka bomo govorili o izvedba particioniranja v strukturo naše baze podatkov.

Vir: www.habr.com

Dodaj komentar