Database di Messenger (parte 1): cuncepimentu di u quadru di basa

Cumu pudete traduce i bisogni di l'affari in strutture di dati specifiche cù l'esempiu di cuncepimentu di una basa di dati di messageria da zero.

Database di Messenger (parte 1): cuncepimentu di u quadru di basa
A nostra basa ùn serà micca cusì grande è distribuita, cum'è VKontakte o Badoo, ma "cusì chì era", ma era bonu - funziunale, veloce è adatta à un servitore PostgreSQL - in modu chì pudete implementà una istanza separata di u serviziu in qualchì parte di u latu, per esempiu.

Dunque, ùn toccaremu micca i prublemi di sharding, replicazione è sistemi geo-distribuiti, ma ci concentreremu nantu à e soluzioni di circuitu in a basa di dati.

Passu 1: Alcune specifiche di l'affari

Ùn avemu micca disignà a nostra messageria in astrattu, ma l'integraremu in l'ambiente rete suciale corporativa. Questu hè, u nostru populu ùn "solu currisponde", ma cumunicà cù l'altri in u cuntestu di risolve certi prublemi di cummerciale.

E quali sò i travaglii di un affari ?.. Fighjemu l'esempiu di Vasily, u capu di u dipartimentu di sviluppu.

  • "Nikolai, per questu compitu avemu bisognu di un patch oghje!"
    Questu significa chì a currispundenza pò esse realizatu in u cuntestu di certi documentu.
  • "Kolya, andate à Dota sta sera?"
    Questu hè, ancu un paru di interlocutori ponu cumunicà simultaneamente nantu à vari temi.
  • "Petru, Nikolay, cercate in l'allegatu a lista di prezzi per u novu servitore".
    Cusì, un missaghju pò avè parechji destinatari. In questu casu, u missaghju pò cuntene I schedarii attaccati.
  • "Semyon, guarda ancu".
    È ci deve esse l'uppurtunità di entre in a currispundenza esistenti invita un novu membru.

Demu per avà nantu à sta lista di bisogni "evidenti".

Senza capisce i specifichi applicati di u prublema è e limitazioni date à questu, cuncepimentu efficace schema di basa di dati per risolve hè quasi impussibile.

Passu 2: Circuitu logicu minimu

Finu a ora, tuttu funziona assai simile à a currispundenza email - un strumentu cummerciale tradiziunale. Iè, "algoritmicamente" assai prublemi di cummerciale sò simili à l'altri, per quessa, l'arnesi per risolviri seranu strutturalmente simili.

Fixemu u diagramma logicu digià ottenutu di e relazioni entità. Per fà u nostru mudellu più faciule da capisce, avemu aduprà l'opzione di visualizazione più primitiva mudelli ER senza complicazioni di notazioni UML o IDEF:

Database di Messenger (parte 1): cuncepimentu di u quadru di basa

In u nostru esempiu, a persona, u documentu è u "corpu" binari di u schedariu sò entità "esterne" chì esistenu indipindentamente senza u nostru serviziu. Dunque, simpricimenti li percepisceremu in u futuru cum'è certi ligami "in un locu" da UUID.

Disegna diagrammi u più simplice pussibule - A maiò parte di e persone chì vi mustrarà ùn sò micca esperti in leghje UML / IDEF. Ma assicuratevi di disegnà.

Passu 3: Sketching a struttura di a tavula

Circa i nomi di tavule è campiI nomi "russi" di campi è tavulini ponu esse trattati in modu diversu, ma questu hè una materia di gustu. Perchè u quì à Tensor ùn ci hè micca sviluppatori stranieri, è PostgreSQL ci permette di dà nomi ancu in ieroglifi, se chjusu tra virgolette, Tandu preferimu chjamà l'uggetti unambiguously è chjaramente cusì chì ùn ci hè micca discrepanzi.
Siccomu assai persone scrivenu missaghji à noi à una volta, certi di elli ponu ancu fà questu offline, allura l'opzione più simplice hè aduprà UUID cum'è identificatori micca solu per entità esterne, ma ancu per tutti l'uggetti in u nostru serviziu. Inoltre, ponu esse generati ancu in u latu di u cliente - questu ci aiuterà à supportà l'invio di missaghji quandu a basa di dati hè temporaneamente indisponibile, è a probabilità di una collisione hè estremamente bassa.

A struttura di tavula in a nostra basa di dati serà cusì:
Tavule : 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
);

Tables : FR

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

A cosa più sèmplice quandu descrive un formatu hè di cumincià à "svintà" u graficu di cunnessione da tavule chì ùn sò micca riferiti elli stessi à nimu.

Step 4: Truvà i bisogni micca evidenti

Hè cusì, avemu cuncepitu una basa di dati in quale pudete scrive perfettamente è in qualchì manera leghje.

Mettimu in i scarpi di l'utilizatori di u nostru serviziu - chì vulemu fà cun ellu?

  • Ultimi missaghji
    issu ordinati cronologicamente un registru di "i mo" missaghji basatu nantu à diversi criterii. Induve sò unu di i destinatari, induve sò l'autore, induve m'hà scrittu è ùn aghju micca rispostu, induve ùn m'anu micca rispostu, ...
  • I participanti di a currispundenza
    Quale hè ancu participà à sta longa, longa chat ?

A nostra struttura permette di risolve i dui prublemi "in generale", ma micca rapidamente. U prublema hè chì per sorte in u primu compitu incapace di creà index, adattatu per ognunu di i participanti (è duverete estrae tutti i registri), è per risolve u sicondu chì avete bisognu caccià tutti i missaghji nantu à stu tema.

I travaglii di l'utilizatori imprevisti ponu mette in grassu croce nantu à a produtividade.

Passu 5: Smart Denormalization

I nostri dui prublemi seranu risolti da tavule supplementari in quale avemu duplicate parte di e dati, necessariu di furmà nantu à elli indici adatti à i nostri compiti.
Database di Messenger (parte 1): cuncepimentu di u quadru di basa

Tavule : RU

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

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

Tables : FR

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

Quì avemu applicatu dui approcci tipici utilizati quandu creanu tavule ausiliarii:

  • Multiplicà i registri
    Utilizendu un missaghju iniziale, creemu parechji registri di seguitu in diversi tipi di registri per diversi pruprietarii - sia per u mittente sia per u destinatariu. Ma ognuna di i registri ora casca nantu à l'indici - dopu tuttu, in un casu tipicu, vulemu vede solu a prima pagina.
  • Records unichi
    Ogni volta chì mandate un missaghju in un tema specificu, hè abbastanza per verificà se una tale entrata esiste digià. Se no, aghjunghje à u nostru "dizziunariu".

In a prossima parte di l'articulu avemu da parlà implementazione di a particione in a struttura di a nostra basa di dati.

Source: www.habr.com

Add a comment