Messenger duomenų bazė (1 dalis): bazinės sistemos projektavimas

Kaip verslo reikalavimus paversti konkrečiomis duomenų struktūromis, naudojant pavyzdį, kaip sukurti Messenger duomenų bazę nuo nulio.

Messenger duomenų bazė (1 dalis): bazinės sistemos projektavimas
Mūsų bazė nebus tokia didelė ir paskirstyta, kaip VKontakte arba Badoo, bet "taip, kad buvo", bet buvo geras - funkcionalus, greitas ir telpa viename serveryje PostgreSQL – kad, pavyzdžiui, galėtumėte įdiegti atskirą paslaugos egzempliorių kažkur šone.

Todėl mes neliesime dalijimosi, replikacijos ir geografiškai paskirstytų sistemų klausimų, o sutelksime dėmesį į grandinės sprendimus duomenų bazės viduje.

1 veiksmas: kai kurios verslo specifikos

Mes nekursime savo pranešimų abstrakčiai, o integruosime juos į aplinką įmonės socialinis tinklas. Tai yra, mūsų žmonės ne „tiesiog susirašinėja“, bet bendrauja tarpusavyje spręsdami tam tikras verslo problemas.

O kokie verslo uždaviniai?.. Pažvelkime į plėtros skyriaus vadovo Vasilijaus pavyzdį.

  • „Nikolajai, šiai užduočiai mums šiandien reikia pleistro!
    Tai reiškia, kad susirašinėjimas gali būti vedamas kai kurių kontekste dokumentas.
  • „Kolya, ar eisi šį vakarą į Dotą?
    Tai yra, net viena pašnekovų pora gali bendrauti vienu metu įvairiomis temomis.
  • „Petrai, Nikolajaus, naujo serverio kainoraštį ieškok priede.
    Taigi, gali būti viena žinutė keli gavėjai. Tokiu atveju pranešime gali būti Prikabinti failai.
  • – Semjonai, irgi pažiūrėk.
    Ir turėtų būti galimybė įvesti esamą susirašinėjimą pakviesti naują narį.

Kol kas apsistokime prie šio „akivaizdžių“ poreikių sąrašo.

Nesuvokiant taikomosios problemos specifikos ir jai suteiktų apribojimų, projektavimas veiksmingas duomenų bazės schemą išspręsti beveik neįmanoma.

2 veiksmas: minimali loginė grandinė

Kol kas viskas klostosi labai panašiai kaip susirašinėjimas el. paštu – tradicinis verslo įrankis. Taip, „algoritmiškai“ daugelis verslo problemų yra panašios viena į kitą, todėl jų sprendimo įrankiai bus struktūriškai panašūs.

Pataisykime jau gautą objektinių ryšių loginę schemą. Kad mūsų modelis būtų lengviau suprantamas, naudosime primityviausią rodymo parinktį ER modeliai be UML ar IDEF žymėjimų komplikacijų:

Messenger duomenų bazė (1 dalis): bazinės sistemos projektavimas

Mūsų pavyzdyje asmuo, dokumentas ir dvejetainis failo „kūnas“ yra „išoriniai“ objektai, kurie egzistuoja nepriklausomai be mūsų paslaugos. Todėl ateityje juos tiesiog suvoksime kaip kai kurias UUID nuorodas „kažkur“.

Lygiosios kuo paprastesnes diagramas - Dauguma žmonių, kuriems juos parodysite, nėra UML/IDEF skaitymo ekspertai. Bet būtinai pieškite.

3 veiksmas: lentelės struktūros eskizas

Apie lentelių ir laukų pavadinimus„Rusiški“ laukų ir lentelių pavadinimai gali būti traktuojami skirtingai, bet tai yra skonio reikalas. Nes čia Tensor nėra užsienio kūrėjų, o PostgreSQL leidžia mums suteikti vardus net hieroglifais, jei jie įtraukta į kabutes, tada mes norime pavadinti objektus vienareikšmiškai ir aiškiai, kad nebūtų neatitikimų.
Kadangi daugelis žmonių mums rašo žinutes vienu metu, kai kurie iš jų netgi gali tai padaryti neprisijungus, tada paprasčiausias variantas yra naudoti UUID kaip identifikatorius ne tik išoriniams subjektams, bet ir visiems mūsų paslaugos objektams. Be to, jie gali būti generuojami net kliento pusėje – tai padės mums palaikyti žinučių siuntimą, kai duomenų bazė laikinai nepasiekiama, o susidūrimo tikimybė itin maža.

Lentelės struktūros juodraštis mūsų duomenų bazėje atrodys taip:
Lentelės : 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
);

Lentelės: 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
);

Paprasčiausias dalykas aprašant formatą yra pradėti „išvynioti“ ryšio grafiką iš lentelių, kuriose nėra nuorodų patys niekam.

4 veiksmas: išsiaiškinkite neakivaizdžius poreikius

Tai viskas, mes sukūrėme duomenų bazę, kurioje galite rašyti puikiai ir kažkaip skaityti.

Įsitaisykime į savo paslaugos vartotojo kailį – ką mes su tuo norime daryti?

  • Paskutinės žinutės
    Jis chronologine tvarka „mano“ pranešimų registras, pagrįstas įvairiais kriterijais. Kur aš esu vienas iš gavėjų, kur aš esu autorius, kur jie man parašė, o aš neatsakiau, kur jie man neatsakė, ...
  • Susirašinėjimo dalyviai
    Kas net dalyvauja šiame ilgame, ilgame pokalbyje?

Mūsų struktūra leidžia mums išspręsti abi šias problemas „apskritai“, bet ne greitai. Problema ta, kad rūšiavimas vyksta atliekant pirmąją užduotį nepavyko sukurti indekso, tinka kiekvienam dalyviui (ir jūs turėsite išgauti visus įrašus), o norint išspręsti antrą jums reikia išskleisti visus pranešimus šia tema.

Nenumatytos vartotojo užduotys gali būti paryškintos kryžminis produktyvumas.

5 veiksmas: išmanusis denormalizavimas

Abi mūsų problemas išspręs papildomos lentelės, kuriose mes pasikartoja duomenų dalis, būtina ant jų suformuoti mūsų užduotims tinkamus indeksus.
Messenger duomenų bazė (1 dalis): bazinės sistemos projektavimas

Lentelės : RU

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

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

Lentelės: 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)
);

Čia taikėme du tipinius metodus, naudojamus kurdami pagalbines lenteles:

  • Įrašų dauginimas
    Naudodami vieną pradinį pranešimo įrašą, skirtingų tipų registruose sukuriame kelis tolesnius įrašus skirtingiems savininkams – tiek siuntėjui, tiek gavėjui. Bet kiekvienas iš registrų dabar patenka į indeksą – juk įprastu atveju norėsime matyti tik pirmąjį puslapį.
  • Unikalūs rekordai
    Kiekvieną kartą siunčiant žinutę konkrečioje temoje, pakanka patikrinti, ar toks įrašas jau yra. Jei ne, įtraukite jį į mūsų „žodyną“.

Kitoje straipsnio dalyje kalbėsime apie skaidymo įgyvendinimas į mūsų duomenų bazės struktūrą.

Šaltinis: www.habr.com

Добавить комментарий