Messenger database (bahagi 1): pagdidisenyo ng base framework

Paano mo maisasalin ang mga kinakailangan sa negosyo sa mga partikular na istruktura ng data gamit ang halimbawa ng pagdidisenyo ng database ng messenger mula sa simula.

Messenger database (bahagi 1): pagdidisenyo ng base framework
Ang aming base ay hindi magiging kasing laki at ipinamamahagi, tulad ng VKontakte o Badoo, ngunit "kaya ito ay", ngunit ito ay mabuti - gumagana, mabilis at magkasya sa isang server PostgreSQL - upang maaari kang mag-deploy ng isang hiwalay na halimbawa ng serbisyo sa isang lugar sa gilid, halimbawa.

Samakatuwid, hindi namin hawakan ang mga isyu ng sharding, replication at geo-distributed system, ngunit tututuon ang mga solusyon sa circuit sa loob ng database.

Hakbang 1: Ilang partikular na negosyo

Hindi namin ididisenyo ang aming pagmemensahe nang abstract, ngunit isasama ito sa kapaligiran corporate social network. Ibig sabihin, ang ating mga tao ay hindi "nagkatugma lamang," ngunit nakikipag-usap sa isa't isa sa konteksto ng paglutas ng ilang mga problema sa negosyo.

At ano ang mga gawain ng isang negosyo?.. Tingnan natin ang halimbawa ni Vasily, ang pinuno ng departamento ng pag-unlad.

  • "Nikolai, para sa gawaing ito kailangan natin ng isang patch ngayon!"
    Nangangahulugan ito na ang pagsusulatan ay maaaring isagawa sa konteksto ng ilan ang dokumento.
  • "Kolya, pupunta ka ba sa Dota ngayong gabi?"
    Ibig sabihin, kahit isang pares ng mga kausap ay maaaring makipag-usap nang sabay-sabay sa iba't ibang paksa.
  • "Peter, Nikolay, tingnan ang attachment para sa listahan ng presyo para sa bagong server."
    Kaya, maaaring magkaroon ng isang mensahe ilang tatanggap. Sa kasong ito, maaaring naglalaman ang mensahe Naka-attach na mga file.
  • "Semyon, tingnan mo rin."
    At dapat magkaroon ng pagkakataon na pumasok sa umiiral na sulat mag-imbita ng bagong miyembro.

Pag-isipan natin ang listahang ito ng "halatang" pangangailangan sa ngayon.

Nang walang pag-unawa sa inilapat na mga detalye ng problema at ang mga limitasyon na ibinigay dito, disenyo mabisa database schema upang malutas ito ay halos imposible.

Hakbang 2: Minimal Logic Circuit

Sa ngayon, gumagana ang lahat na halos kapareho sa pagsusulatan sa email - isang tradisyunal na tool sa negosyo. Oo, "algorithmically" maraming mga problema sa negosyo ay magkapareho sa isa't isa, samakatuwid ang mga tool para sa paglutas ng mga ito ay magkakatulad sa istruktura.

Ayusin natin ang nakuha nang lohikal na diagram ng mga relasyon sa entity. Upang gawing mas madaling maunawaan ang aming modelo, gagamitin namin ang pinaka-primitive na opsyon sa pagpapakita Mga modelo ng ER nang walang mga komplikasyon ng mga notasyon ng UML o IDEF:

Messenger database (bahagi 1): pagdidisenyo ng base framework

Sa aming halimbawa, ang tao, dokumento at binary na "katawan" ng file ay "panlabas" na mga entity na umiiral nang hiwalay nang wala ang aming serbisyo. Samakatuwid, iisipin lang namin ang mga ito sa hinaharap bilang ilang mga link "sa isang lugar" ng UUID.

Gumuhit mga diagram nang simple hangga't maaari - karamihan sa mga taong ipapakita mo sa kanila ay hindi eksperto sa pagbabasa ng UML/IDEF. Ngunit siguraduhing gumuhit.

Hakbang 3: Pag-sketch ng istraktura ng talahanayan

Tungkol sa mga pangalan ng talahanayan at fieldAng "Russian" na mga pangalan ng mga patlang at talahanayan ay maaaring tratuhin nang iba, ngunit ito ay isang bagay ng panlasa. Dahil ang dito sa Tensor walang mga dayuhang developer, at pinapayagan kami ng PostgreSQL na magbigay ng mga pangalan kahit sa mga hieroglyph, kung sila nakapaloob sa mga quotes, pagkatapos ay mas gusto naming pangalanan ang mga bagay nang hindi malabo at malinaw upang walang mga pagkakaiba.
Dahil maraming tao ang sumulat ng mga mensahe sa amin nang sabay-sabay, maaaring gawin ito ng ilan sa kanila offline, kung gayon ang pinakasimpleng opsyon ay gumamit ng mga UUID bilang mga identifier hindi lamang para sa mga panlabas na entity, kundi para din sa lahat ng bagay sa loob ng aming serbisyo. Bukod dito, maaari silang mabuo kahit sa panig ng kliyente - makakatulong ito sa amin na suportahan ang pagpapadala ng mga mensahe kapag pansamantalang hindi available ang database, at napakababa ng posibilidad na magkaroon ng banggaan.

Ang istraktura ng draft na talahanayan sa aming database ay magiging ganito:
Mga talahanayan : 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
);

Mga talahanayan: 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
);

Ang pinakasimpleng bagay kapag naglalarawan ng isang format ay ang simulang "i-unwinding" ang graph ng koneksyon mula sa mga talahanayan na hindi naka-reference kanilang sarili sa walang sinuman.

Hakbang 4: Alamin ang mga di-halatang pangangailangan

Iyon lang, nagdisenyo kami ng isang database kung saan maaari kang magsulat nang perpekto at kahit papaano upang mabasa.

Ilagay natin ang ating sarili sa kalagayan ng gumagamit ng ating serbisyo - ano ang gusto nating gawin dito?

  • Mga huling mensahe
    Ito sunud-sunod na pinagsunod-sunod isang registry ng "aking" mga mensahe batay sa iba't ibang pamantayan. Kung saan isa ako sa mga tatanggap, kung saan ako ang may-akda, kung saan sinulat nila ako at hindi ako sumagot, kung saan hindi nila ako sinagot, ...
  • Mga kalahok sa sulat
    Sino ang nakikilahok sa mahaba at mahabang chat na ito?

Ang aming istraktura ay nagbibigay-daan sa amin upang malutas ang parehong mga problemang ito "sa pangkalahatan," ngunit hindi mabilis. Ang problema ay para sa pag-uuri sa loob ng unang gawain hindi makagawa ng index, na angkop para sa bawat kalahok (at kakailanganin mong kunin ang lahat ng mga talaan), at upang malutas ang pangalawa na kailangan mo i-extract ang lahat ng mensahe sa paksang ito.

Maaaring maglagay ng bold ang mga hindi sinasadyang gawain ng user tumawid sa pagiging produktibo.

Hakbang 5: Smart Denormalization

Parehong ang aming mga problema ay malulutas sa pamamagitan ng karagdagang mga talahanayan kung saan namin gagawin duplicate na bahagi ng data, kinakailangan upang bumuo sa kanila ng mga indeks na angkop para sa ating mga gawain.
Messenger database (bahagi 1): pagdidisenyo ng base framework

Mga talahanayan : RU

CREATE TABLE "РССстрБообщСний"(
  "Π’Π»Π°Π΄Π΅Π»Π΅Ρ†"
    uuid
, "ВипРССстра"
    smallint
, "ДатаВрСмя"
    timestamp
, "Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅"
    uuid
, PRIMARY KEY("Π’Π»Π°Π΄Π΅Π»Π΅Ρ†", "ВипРССстра", "Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅")
);
CREATE INDEX ON "РССстрБообщСний"("Π’Π»Π°Π΄Π΅Π»Π΅Ρ†", "ВипРССстра", "ДатаВрСмя" DESC);

CREATE TABLE "УчастникВСмы"(
  "Π’Π΅ΠΌΠ°"
    uuid
, "ΠŸΠ΅Ρ€ΡΠΎΠ½Π°"
    uuid
, PRIMARY KEY("Π’Π΅ΠΌΠ°", "ΠŸΠ΅Ρ€ΡΠΎΠ½Π°")
);

Mga talahanayan: 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)
);

Dito ay naglapat kami ng dalawang tipikal na diskarte na ginagamit sa paggawa ng mga auxiliary table:

  • Pagpaparami ng mga tala
    Gamit ang isang paunang talaan ng mensahe, gumawa kami ng ilang mga follow-up na tala sa iba't ibang uri ng mga rehistro para sa iba't ibang mga may-ari - para sa nagpadala at para sa tatanggap. Ngunit ang bawat isa sa mga rehistro ay nahuhulog na ngayon sa index - pagkatapos ng lahat, sa isang tipikal na kaso, nais naming makita lamang ang unang pahina.
  • Mga natatanging tala
    Sa tuwing magpapadala ka ng mensahe sa loob ng isang partikular na paksa, sapat na upang suriin kung mayroon nang naturang entry. Kung hindi, idagdag ito sa aming "diksyonaryo".

Sa susunod na bahagi ng artikulo ay pag-uusapan natin pagpapatupad ng partitioning sa istruktura ng aming database.

Pinagmulan: www.habr.com

Magdagdag ng komento