Messenger-datumbazo (parto 1): dizajnante la bazan kadron

Kiel vi povas traduki komercajn postulojn en specifajn datumstrukturojn uzante la ekzemplon de desegnado de mesaĝa datumbazo de nulo.

Messenger-datumbazo (parto 1): dizajnante la bazan kadron
Nia bazo ne estos tiel granda kaj distribuita, kiel VKontakteBadoo, sed "tiel ke ĝi estis", sed ĝi estis bona - funkcia, rapida kaj taŭgas sur unu servilo PostgreSQL - por ke vi povu disfaldi apartan ekzemplon de la servo ie flanke, ekzemple.

Sekve, ni ne tuŝos la problemojn de sharding, reproduktado kaj geo-distribuitaj sistemoj, sed fokusiĝos pri cirkvitaj solvoj ene de la datumbazo.

Paŝo 1: Iuj komercaj specifaĵoj

Ni ne desegnos nian mesaĝadon abstrakte, sed integrigos ĝin en la medion kompania socia reto. Tio estas, niaj homoj ne "nur korespondas", sed komunikas inter si en la kunteksto de solvado de certaj komercaj problemoj.

Kaj kiaj estas la taskoj de entrepreno?.. Ni rigardu la ekzemplon de Vasilij, la estro de la disvolva departemento.

  • "Nikolao, por ĉi tiu tasko ni bezonas peceton hodiaŭ!"
    Ĉi tio signifas, ke korespondado povas esti farita en la kunteksto de iuj dokumento.
  • "Kolya, ĉu vi iros al Dota ĉi-vespere?"
    Tio estas, eĉ unu paro da interparolantoj povas komuniki samtempe pri diversaj temoj.
  • "Petro, Nikolay, serĉu en la aldonaĵo la prezoliston por la nova servilo."
    Do, unu mesaĝo povas havi pluraj ricevantoj. En ĉi tiu kazo, la mesaĝo povas enhavi Aldonitaj dosieroj.
  • "Semyon, rigardu ankaŭ."
    Kaj estu okazo por eniri ekzistantan korespondadon invitu novan membron.

Ni restu pri ĉi tiu listo de "evidentaj" bezonoj nuntempe.

Sen kompreni la aplikatajn specifaĵojn de la problemo kaj la limigojn donitajn al ĝi, projektu efika datumbaza skemo solvi ĝin estas preskaŭ neeble.

Paŝo 2: Minimuma Logika Cirkvito

Ĝis nun ĉio funkcias tre simile al retpoŝta korespondado - tradicia komerca ilo. Jes, "algoritme" multaj komercaj problemoj similas unu al la alia, tial la iloj por solvi ilin estos strukture similaj.

Ni riparu la jam akiritan logikan diagramon de la rilatoj de estaĵoj. Por igi nian modelon pli facile komprenebla, ni uzos la plej primitivan montran opcion ER-modeloj sen la komplikaĵoj de UML aŭ IDEF-notacioj:

Messenger-datumbazo (parto 1): dizajnante la bazan kadron

En nia ekzemplo, la persono, dokumento kaj binara "korpo" de la dosiero estas "eksteraj" estaĵoj kiuj ekzistas sendepende sen nia servo. Tial ni simple perceptos ilin estonte kiel iuj ligiloj "ie" per UUID.

Desegni diagramoj kiel eble plej simplaj - la plej multaj el la homoj, al kiuj vi montros ilin, ne estas spertuloj pri legado de UML/IDEF. Sed nepre desegnu.

Paŝo 3: Skizante la tablostrukturon

Pri tabelaj kaj kamponomojLa "rusaj" nomoj de kampoj kaj tabeloj povas esti traktataj malsame, sed ĉi tio estas demando de gusto. Ĉar la ĉi tie ĉe Tensor ne ekzistas eksterlandaj programistoj, kaj PostgreSQL permesas al ni doni nomojn eĉ en hieroglifoj, se ili enfermitaj inter citiloj, tiam ni preferas nomi objektojn malambigue kaj klare, por ke ne estu diferencoj.
Ĉar multaj homoj skribas mesaĝojn al ni samtempe, kelkaj el ili eĉ povas fari tion eksterrete, tiam la plej simpla opcio estas uzu UUIDojn kiel identigilojn ne nur por eksteraj estaĵoj, sed ankaŭ por ĉiuj objektoj ene de nia servo. Krome, ili povas esti generitaj eĉ ĉe la klienta flanko - ĉi tio helpos nin subteni sendi mesaĝojn kiam la datumbazo estas provizore neatingebla, kaj la probableco de kolizio estas ekstreme malalta.

La skiza tabelstrukturo en nia datumbazo aspektos jene:
Tabeloj : 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
);

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

La plej simpla afero kiam oni priskribas formaton estas komenci "malvolvi" la konektan grafeon de tabeloj kiuj ne estas referencitaj sin al neniu.

Paŝo 4: Eltrovu ne-evidentajn bezonojn

Jen ĝi, ni desegnis datumbazon en kiu vi povas skribi perfekte kaj iel legi.

Ni metu nin en la ŝuojn de la uzanto de nia servo - kion ni volas fari kun ĝi?

  • Lastaj mesaĝoj
    ĉi kronologie ordigitaj registro de "miaj" mesaĝoj surbaze de diversaj kriterioj. Kie mi estas unu el la ricevantoj, kie mi estas la aŭtoro, kie ili skribis al mi kaj mi ne respondis, kie ili ne respondis al mi, ...
  • Partoprenantoj de la korespondado
    Kiu eĉ partoprenas en ĉi tiu longa, longa babilado?

Nia strukturo permesas al ni solvi ambaŭ ĉi tiujn problemojn "ĝenerale", sed ne rapide. La problemo estas tio por ordigo ene de la unua tasko ne povas krei indekson, taŭga por ĉiu el la partoprenantoj (kaj vi devos ĉerpi ĉiujn rekordojn), kaj por solvi la duan vi bezonas ĉerpi ĉiujn mesaĝojn pri ĉi tiu temo.

Neintencitaj uzanttaskoj povas meti grase kruci sur produktiveco.

Paŝo 5: Inteligenta Malnormaligo

Ambaŭ niaj problemoj estos solvitaj per pliaj tabeloj, en kiuj ni faros duobligi parton de la datumoj, necesaj formi sur ili indeksojn taŭgajn por niaj taskoj.
Messenger-datumbazo (parto 1): dizajnante la bazan kadron

Tabeloj : RU

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

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

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

Ĉi tie ni aplikis du tipajn alirojn uzatajn dum kreado de helpaj tabeloj:

  • Multobligi rekordojn
    Uzante unu komencan mesaĝrekordon, ni kreas plurajn sekvajn registrojn en malsamaj tipoj de registroj por malsamaj posedantoj - kaj por la sendinto kaj por la ricevanto. Sed ĉiu el la registroj nun falas sur la indekso - finfine, en tipa kazo, ni volos vidi nur la unuan paĝon.
  • Unika rekordoj
    Ĉiufoje kiam vi sendas mesaĝon ene de specifa temo, sufiĉas kontroli ĉu tia eniro jam ekzistas. Se ne, aldonu ĝin al nia "vortaro".

En la sekva parto de la artikolo ni parolos efektivigo de dispartigo en la strukturon de nia datumbazo.

fonto: www.habr.com

Aldoni komenton