Messenger-database (diel 1): ûntwerp fan it basiskader

Hoe kinne jo saaklike easken oersette yn spesifike gegevensstruktueren mei it foarbyld fan it ûntwerpen fan in messenger-database fanôf it begjin.

Messenger-database (diel 1): ûntwerp fan it basiskader
Us basis sil net sa grut en ferspraat wêze, lykas VKontakte of Badoo, mar "sadat it wie", mar it wie goed - funksjoneel, fluch en past op ien tsjinner PostgreSQL - sadat jo bygelyks in apart eksimplaar fan 'e tsjinst earne oan 'e kant kinne ynsette.

Dêrom sille wy de problemen fan sharding, replikaasje en geo-ferspraat systemen net oanreitsje, mar sille wy rjochtsje op circuitoplossingen binnen de database.

Stap 1: Guon saaklike spesifikaasjes

Wy sille ús berjochten net abstrakt ûntwerpe, mar yntegrearje yn 'e omjouwing sosjaal bedriuw netwurk. Dat is, ús minsken korrespondearje net "gewoan", mar kommunisearje mei elkoar yn 'e kontekst fan it oplossen fan bepaalde saaklike problemen.

En wat binne de taken fan in bedriuw?.. Lit ús sjen nei it foarbyld fan Vasily, it haad fan 'e ûntwikkeling ôfdieling.

  • "Nikolai, foar dizze taak hawwe wy hjoed in patch nedich!"
    Dit betsjut dat korrespondinsje kin wurde fierd yn 'e kontekst fan guon dokumint.
  • "Kolya, geane jo dizze jûn nei Dota?"
    Dat is, sels ien pear petearen kinne tagelyk kommunisearje oer ferskate ûnderwerpen.
  • "Peter, Nikolay, sjoch yn 'e taheaksel foar de priislist foar de nije server."
    Dus, ien berjocht kin hawwe ferskate ûntfangers. Yn dit gefal kin it berjocht befetsje Taheakke triemmen.
  • "Semyon, sjoch ek ris."
    En der moat in kâns wêze om besteande korrespondinsje oan te gean útnoegje in nij lid.

Litte wy no stilbliuwe by dizze list mei "dúdlike" behoeften.

Sûnder begripe de tapaste spesifikaasjes fan it probleem en de beheinings jûn oan it, design effektyf databankskema om it op te lossen is hast ûnmooglik.

Stap 2: Minimal Logic Circuit

Oant no ta wurket alles heul gelyk oan e-postkorrespondinsje - in tradisjoneel saaklik ark. Ja, "algoritmysk" binne in protte saaklike problemen ferlykber mei elkoar, dêrom sille de ark foar it oplossen fan har struktureel ferlykber wêze.

Litte wy it al krigen logyske diagram fan entiteitsrelaasjes reparearje. Om ús model makliker te begripen te meitsjen, sille wy de meast primitive werjefteopsje brûke ER modellen sûnder de komplikaasjes fan UML- of IDEF-notaasjes:

Messenger-database (diel 1): ûntwerp fan it basiskader

Yn ús foarbyld binne de persoan, dokumint en binêre "lichem" fan it bestân "eksterne" entiteiten dy't ûnôfhinklik besteane sûnder ús tsjinst. Dêrom, wy sille gewoan waarnimme se yn 'e takomst as guon keppelings "ergens" troch UUID.

Draw diagrams sa ienfâldich mooglik - de measte minsken dy't jo se sille sjen litte binne gjin saakkundigen yn it lêzen fan UML / IDEF. Mar wês wis te tekenjen.

Stap 3: Skizze de tabelstruktuer

Oer tabel- en fjildnammenDe "Russyske" nammen fan fjilden en tabellen kinne oars wurde behannele, mar dit is in kwestje fan smaak. Fanwege de hjir by Tensor d'r binne gjin bûtenlânske ûntwikkelders, en PostgreSQL lit ús nammen jaan, sels yn hiëroglyfen, as se ynsletten yn quotes, dan neame wy objekten it leafst ûndûbelsinnich en dúdlik, sadat der gjin diskrepânsjes binne.
Om't in protte minsken tagelyk berjochten nei ús skriuwe, kinne guon fan harren dit sels dwaan offline, dan is de ienfâldichste opsje brûke UUID's as identifiers net allinich foar eksterne entiteiten, mar ek foar alle objekten binnen ús tsjinst. Boppedat kinne se sels oan 'e kliïntkant generearre wurde - dit sil ús helpe by it ferstjoeren fan berjochten as de databank tydlik net beskikber is, en de kâns op in botsing ekstreem leech is.

De ûntwerptabelstruktuer yn ús databank sil der sa útsjen:
Tafels: 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
);

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

It ienfâldichste ding by it beskriuwen fan in opmaak is om de ferbiningsgrafyk te "ûntwikkeljen". út tabellen dy't net ferwiisd harsels oan nimmen.

Stap 4: Fyn net-foar de hân lizzende behoeften

Dat is it, wy hawwe ûntwurpen in database wêryn jo kinne skriuwe perfekt en ien of oare manier lêze.

Litte wy ússels yn 'e skuon sette fan' e brûker fan ús tsjinst - wat wolle wy dermei?

  • Lêste berjochten
    dizze gronologysk sortearre in register fan "myn" berjochten basearre op ferskate kritearia. Wêr't ik ien fan 'e ûntfangers bin, wêr't ik de auteur bin, wêr't se my skreaunen en ik net antwurde, wêr't se my net antwurden, ...
  • Dielnimmers fan de korrespondinsje
    Wa docht sels mei oan dit lange, lange petear?

Us struktuer lit ús beide problemen "yn 't algemien" oplosse, mar net fluch. It probleem is dat foar sortearjen binnen de earste taak kin net oanmeitsje yndeks, geskikt foar elk fan 'e dielnimmers (en jo sille alle records moatte ekstrahearje), en om de twadde op te lossen dy't jo nedich binne extract alle berjochten oer dit ûnderwerp.

Unbedoelde brûkerstaken kinne fet set wurde krús op produktiviteit.

Stap 5: Smart Denormalization

Us beide problemen wurde oplost troch ekstra tabellen wêryn wy sille duplikaat diel fan 'e gegevens, nedich om te foarmjen op harren yndeksen geskikt foar ús taken.
Messenger-database (diel 1): ûntwerp fan it basiskader

Tafels: RU

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

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

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

Hjir hawwe wy twa typyske oanpak tapast dy't brûkt wurde by it meitsjen fan helptabellen:

  • Fermannichfâldigje records
    Mei ien earste berjochtrecord meitsje wy ferskate opfolgingsrecords yn ferskate soarten registers foar ferskate eigners - sawol foar de stjoerder as foar de ûntfanger. Mar elk fan 'e registers falt no op 'e yndeks - ommers, yn in typysk gefal wolle wy allinich de earste side sjen.
  • Unike records
    Elke kear as jo in berjocht ferstjoere binnen in spesifyk ûnderwerp, is it genôch om te kontrolearjen oft sa'n yngong al bestiet. As net, foegje it dan ta oan ús "wurdboek".

Yn it folgjende diel fan it artikel sille wy prate oer útfiering fan partitioning yn 'e struktuer fan ús databank.

Boarne: www.habr.com

Add a comment