Messenger baza podataka (1. dio): dizajniranje osnovnog okvira

Kako možete prevesti poslovne zahtjeve u specifične strukture podataka koristeći primjer dizajniranja baze podataka za messenger od nule.

Messenger baza podataka (1. dio): dizajniranje osnovnog okvira
Naša baza neće biti tako velika i raspoređena, kao VKontakte ili Badoo, ali “tako da je bilo”, ali bilo je dobro - funkcionalno, brzo i stane na jedan server PostgreSQL - tako da možete, na primjer, postaviti zasebnu instancu servisa negdje sa strane.

Stoga se nećemo doticati pitanja shardinga, replikacije i geo-distribuiranih sistema, već ćemo se fokusirati na rješenja kola unutar baze podataka.

Korak 1: Neke poslovne specifičnosti

Nećemo dizajnirati naše poruke apstraktno, već ćemo ih integrirati u okruženje korporativna društvena mreža. Odnosno, naši ljudi se ne “samo dopisuju”, već međusobno komuniciraju u kontekstu rješavanja određenih poslovnih problema.

A koji su zadaci preduzeća?.. Pogledajmo primjer Vasilija, šefa odjela za razvoj.

  • “Nikolai, za ovaj zadatak nam je danas potrebna zakrpa!”
    To znači da se prepiska može voditi u kontekstu nekih dokument.
  • „Kolja, ideš li večeras na Dotu?“
    Odnosno, čak i jedan par sagovornika može komunicirati istovremeno na razne teme.
  • “Peter, Nikolaj, pogledajte u prilogu cenovnik za novi server.”
    Dakle, jedna poruka može imati nekoliko primalaca. U tom slučaju, poruka može sadržavati Priloženi fajlovi.
  • „Semjone, pogledaj i ti.”
    I trebalo bi da postoji mogućnost da se uđe u postojeću prepisku pozvati novog člana.

Hajde da se za sada zadržimo na ovoj listi „očiglednih“ potreba.

Bez razumijevanja primijenjenih specifičnosti problema i ograničenja koja su mu data, dizajn efektivno shema baze podataka riješiti to je gotovo nemoguće.

Korak 2: Minimalno logičko kolo

Do sada je sve funkcioniralo vrlo slično kao kod e-mail prepiske – tradicionalnog poslovnog alata. Da, „algoritamski“ su mnogi poslovni problemi slični jedni drugima, stoga će alati za njihovo rješavanje biti strukturno slični.

Popravimo već dobijeni logički dijagram odnosa entiteta. Kako bismo naš model učinili lakšim za razumijevanje, koristit ćemo najprimitivniju opciju prikaza ER modeli bez komplikacija UML ili IDEF notacija:

Messenger baza podataka (1. dio): dizajniranje osnovnog okvira

U našem primjeru, osoba, dokument i binarno “tijelo” datoteke su “spoljni” entiteti koji postoje nezavisno bez naše usluge. Stoga ćemo ih u budućnosti jednostavno doživljavati kao neke veze „negdje“ od strane UUID-a.

Draw dijagrami što jednostavniji - većina ljudi kojima ćete ih pokazati nisu stručnjaci za čitanje UML/IDEF-a. Ali svakako crtajte.

Korak 3: Skiciranje strukture tabele

O nazivima tablica i polja„Ruski“ nazivi polja i tabela mogu se različito tretirati, ali to je stvar ukusa. Zbog ovdje u Tensoru nema stranih programera, a PostgreSQL nam dozvoljava da dajemo imena čak i hijeroglifima, ako u navodnicima, onda radije imenujemo objekte nedvosmisleno i jasno kako ne bi došlo do neslaganja.
S obzirom da nam mnogi ljudi odjednom pišu poruke, neki od njih mogu to i učiniti offline, onda je najjednostavnija opcija koristiti UUID-ove kao identifikatore ne samo za eksterne entitete, već i za sve objekte unutar našeg servisa. Štaviše, mogu se generisati čak i na strani klijenta - to će nam pomoći da podržimo slanje poruka kada je baza podataka privremeno nedostupna, a vjerovatnoća kolizije je izuzetno mala.

Struktura nacrta tabele u našoj bazi podataka će izgledati ovako:
Tablice : 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
);

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

Najjednostavnija stvar pri opisivanju formata je početi "odmotavati" graf povezivanja iz tabela koje nisu referencirane sebe nikome.

Korak 4: Otkrijte neočigledne potrebe

To je to, osmislili smo bazu podataka u koju možete savršeno pisati i nekako citati.

Stavimo se u kožu korisnika naše usluge – šta želimo s tim?

  • Poslednje poruke
    ovo hronološki poredane registar “mojih” poruka na osnovu različitih kriterijuma. Gde sam ja jedan od primalaca, gde sam autor, gde su mi pisali a ja nisam odgovorio, gde mi nisu odgovorili,...
  • Učesnici prepiske
    Ko uopće učestvuje u ovom dugom, dugom razgovoru?

Naša struktura nam omogućava da oba ova problema riješimo „općenito“, ali ne brzo. Problem je u sortiranju unutar prvog zadatka nije moguće kreirati indeks, pogodan za svakog od učesnika (i moraćete da izvučete sve zapise), a za rešavanje drugog vam je potreban izdvojiti sve poruke na ovu temu.

Nenamjerni korisnički zadaci mogu biti podebljani križ na produktivnosti.

Korak 5: Pametna denormalizacija

Oba naša problema bit će riješena dodatnim tabelama u kojima ćemo duplirani dio podataka, potrebno da se na njima formiraju indeksi prikladni za naše zadatke.
Messenger baza podataka (1. dio): dizajniranje osnovnog okvira

Tablice : RU

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

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

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

Ovdje smo primijenili dva tipična pristupa koja se koriste prilikom kreiranja pomoćnih tabela:

  • Umnožavanje zapisa
    Koristeći jedan zapis inicijalne poruke, kreiramo nekoliko naknadnih zapisa u različitim tipovima registara za različite vlasnike - i za pošiljaoca i za primaoca. Ali svaki od registara sada pada na indeks - na kraju krajeva, u tipičnom slučaju, želimo da vidimo samo prvu stranicu.
  • Jedinstveni zapisi
    Svaki put kada pošaljete poruku u okviru određene teme, dovoljno je provjeriti postoji li takav unos već. Ako ne, dodajte ga u naš “rječnik”.

U sljedećem dijelu članka ćemo govoriti o tome implementacija particioniranja u strukturu naše baze podataka.

izvor: www.habr.com

Dodajte komentar