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

Kako možete prevesti poslovne zahtjeve u specifične podatkovne strukture pomoću primjera dizajniranja messenger baze podataka od nule.

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

Stoga se nećemo doticati pitanja šardinga, replikacije i geo-distribuiranih sustava, već ćemo se usredotočiti na sklopovna rješenja unutar baze podataka.

Korak 1: Neke poslovne specifičnosti

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

A koji su zadaci poduzeća?.. Pogledajmo primjer Vasilija, voditelja odjela za razvoj.

  • "Nikolai, za ovaj zadatak trebamo zakrpu danas!"
    To znači da se dopisivanje može voditi u kontekstu nekih dokument.
  • "Kolja, ideš li na Dotu večeras?"
    Odnosno, čak i jedan par sugovornika može komunicirati istovremeno o raznim temama.
  • “Peter, Nikolay, pogledajte u prilogu cjenik za novi server.”
    Dakle, jedna poruka može imati nekoliko primatelja. U tom slučaju poruka može sadržavati Priložene datoteke.
  • "Semyone, pogledaj i ti."
    I trebala bi postojati prilika za ulazak u postojeću korespondenciju pozovite novog člana.

Zadržimo se za sada na ovom popisu “očitih” potreba.

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

Korak 2: Minimalni logički sklop

Za sada sve funkcionira vrlo slično dopisivanju putem e-pošte - tradicionalnom poslovnom alatu. Da, "algoritamski" su mnogi poslovni problemi slični jedni drugima, stoga će alati za njihovo rješavanje biti strukturno slični.

Popravimo već dobiveni logički dijagram odnosa entiteta. Kako bismo lakše razumjeli naš model, koristit ćemo najprimitivniju opciju prikaza ER modeli bez komplikacija UML ili IDEF notacija:

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

U našem primjeru, osoba, dokument i binarno "tijelo" datoteke su "vanjski" entiteti koji postoje neovisno bez naše usluge. Stoga ćemo ih u budućnosti jednostavno percipirati kao neke poveznice “negdje” po UUID-u.

crtati dijagrame što jednostavnije - većina ljudi kojima ćete ih pokazati nisu stručnjaci za čitanje UML/IDEF-a. Ali svakako nacrtajte.

Korak 3: Skiciranje strukture stola

O imenima tablica i polja"Ruska" imena polja i tablica mogu se tretirati drugačije, ali to je stvar ukusa. Jer ovdje u Tensoru nema stranih programera, a PostgreSQL nam dopušta davanje imena čak i hijeroglifima, ako ih ima u navodnicima, tada radije imenujemo objekte nedvosmisleno i jasno kako ne bi bilo odstupanja.
Budući da nam puno ljudi piše poruke odjednom, neki od njih to mogu učiniti izvan mreže, onda je najjednostavnija opcija koristiti UUID kao identifikatore ne samo za vanjske subjekte, već i za sve objekte unutar naše usluge. Štoviše, mogu se generirati čak i na strani klijenta - to će nam pomoći da podržimo slanje poruka kada je baza podataka privremeno nedostupna, a vjerojatnost kolizije je izuzetno niska.

Nacrt strukture tablice u našoj bazi podataka izgledat će ovako:
Stolovi : 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
);

Stolovi: 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 veze iz tablica koje nisu referencirane sebe nikome.

Korak 4: Saznajte neočite potrebe

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

Stavimo se u kožu korisnika naše usluge – što želimo učiniti s njom?

  • Posljednje poruke
    ovo kronološki poredani registar "mojih" poruka na temelju različitih kriterija. Gdje sam ja jedan od primalaca, gdje sam autor, gdje su mi pisali a nisam odgovorila, gdje mi nisu odgovorili,...
  • Sudionici dopisivanja
    Tko uopće sudjeluje u ovom dugom, dugom razgovoru?

Naša struktura omogućuje nam rješavanje oba problema "općenito", ali ne brzo. Problem je što za sortiranje unutar prvog zadatka nije moguće stvoriti indeks, prikladan za svakog od sudionika (i morat ćete izdvojiti sve zapise), a za rješavanje drugog trebate izdvojiti sve poruke na ovu temu.

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

Korak 5: Pametna denormalizacija

Oba naša problema riješit će dodatne tablice u kojima ćemo duplicirati dio podataka, potrebne da bismo na njima formirali indekse prikladne za naše zadatke.
Messenger baza podataka (1. dio): projektiranje osnovnog okvira

Stolovi : RU

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

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

Stolovi: 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 koji se koriste pri izradi pomoćnih tablica:

  • Množenje zapisa
    Koristeći jedan početni zapis poruke, kreiramo nekoliko pratećih zapisa u različitim vrstama registara za različite vlasnike - i za pošiljatelja i za primatelja. Ali svaki od registara sada pada na indeks - uostalom, u tipičnom slučaju, htjet ćemo vidjeti samo prvu stranicu.
  • Jedinstveni zapisi
    Svaki put kada pošaljete poruku unutar određene teme, dovoljno je provjeriti da li takav unos već postoji. Ako nije, dodajte ga u naš "rječnik".

U sljedećem dijelu članka govorit ćemo o provedba particioniranja u strukturu naše baze podataka.

Izvor: www.habr.com

Dodajte komentar