Si si mund të përkthesh kërkesat e biznesit në struktura të dhënash konkrete duke e ilustruar me projektimin e një baze për një mesazher nga fillimi.
- Pjesa 1: projektimi i kornizës së bazës

Baza jonĂ« nuk do tĂ« jetĂ« aq masive dhe e shpĂ«rndarĂ«, ose , por «pĂ«r tĂ« qenë», por e mirĂ« â funksionale, e shpejtĂ« dhe tĂ« pĂ«rballojĂ« njĂ« server PostgreSQL â qĂ« tĂ« mund tĂ« bĂ«jmĂ« njĂ« instancĂ« tĂ« veçantĂ« tĂ« shĂ«rbimit diku nĂ« anĂ«n tjetĂ«r, pĂ«r shembull.
Prandaj, nuk do të trajtojmë çështjet e sharding, replikimit dhe sistemeve të geoshpërndarë, por do të fokusohemi në zgjidhje skemash brenda DB-së.
Hapi 1: Disa veçori specifike të biznesit
Ne do ta projektoshim këmbimin tonë të mesazheve jo abstrakt, por duke e inkorporuar në mjedisin e një . Kështu që njerëzit tanë nuk «thjesht shkruajnë», por komunikojnë midis tyre në kontekstin e zgjidhjes së disa detyrave të biznesit.
Cilat janĂ« detyrat e biznesit?.. Le tĂ« shohim nĂ« shembullin e Vasiliy â drejtorit tĂ« departamentit tĂ« zhvillimit.
- «Nikolai, këtë detyrë patch duhet që sot!»
Pra, biseda mund të kryhet në kontekstin e ndonjë gjëje të dokumentit. - «Kolya, le të shkojmë në Dota mbrëmjen?»
Kështu që, edhe për një çift të vetëm biseduesish, komunikimi mund të zhvillohet në të njëjtën kohë në tema të ndryshme. - «Petr, Nikolai, shikoni dokumentin e bashkangjitur për çmimin e serverit të ri.»
Kështu, një mesazh mund të ketë several adresatë.Njëherësh, mesazhi mund të përmbajë skedarë të bashkangjitur. - «Semen, ti gjithashtu shiko.»
Dhe duhet të ketë mundësinë për të ftuar një pjesëmarrës të ri në bisedën ekzistuese Le të ndalemi për momentin në këtë listë «të qarta» të nevojave..
Pa kuptuar specifikat praktike të detyrës dhe kufizimeve që ajo vendos, për të projektuar
një skemë të efektshme të DB-së për zgjidhjen e saj është praktike e pamundur.
Hapi 2: Skema logjike minimale
PĂ«r momentin, skema duket shumĂ« e ngjashme me bisedat e email-it â njĂ« mjet tradicional i biznesit. Po, «algorithmically» shumĂ« detyra tĂ« biznesit janĂ« tĂ« ngjashme me njĂ«ra-tjetrĂ«n, kĂ«shtu qĂ« edhe mjetet pĂ«r zgjidhjen e tyre do tĂ« jenĂ« strukturnĂ« tĂ« ngjashme.
Le të fiksojmë skemën logjike të marrëdhënieve të entiteteve që kemi arritur deri tani. Për të lehtësuar kuptimin e modelit tonë, do të përdorim variantin më të thjeshtë të paraqitjes pa komplikime UML ose IDEF-notacione:

Në shembullin tonë, personi, dokumenti dhe trupi binar i skedarit janë entitete «të jashtme», që ekzistojnë edhe pa shërbimin tonë. Prandaj, do t'i perceptojmë më pas si disa referenca «diku» me UUID.
Vizato skemat sa mĂ« tĂ« thjeshta â shumica e atyre qĂ« do t'i tregoni ato nuk janĂ« ekspertĂ« nĂ« leximin e UML/IDEF. Por â sigurisht, vizatoni.
Hapi 3: Hidhni strukturën e tabelave
Për emrat e tabelave dhe fushaveNë lidhje me emrat "rusë" të fushave dhe tabelave, mund të keni mendime të ndryshme, por kjo është çështje shije. Pasi që nuk kemi zhvillues të huaj, dhe PostgreSQL na lejon të jepni emra madje edhe me hieroglifë, për sa kohë që janë të rrethuara me thonjëza, ne preferojmë të emërojmë objektet në mënyrë të qartë dhe të kuptueshme, në mënyrë që të mos ketë keqkuptime.
Duke marrĂ« parasysh qĂ« mesazhet shkruhen nga shumĂ« njerĂ«z nĂ« tĂ« njĂ«jtĂ«n kohĂ«, disa nga ata mund ta bĂ«jnĂ« kĂ«tĂ« nĂ« mĂ«nyrĂ« offline,mundĂ«sia mĂ« e mirĂ« Ă«shtĂ« tĂ« pĂ«rdorĂ«sh UUID si identifikues jo vetĂ«m pĂ«r entitetet e jashtme, por edhe pĂ«r tĂ« gjitha objektet brenda shĂ«rbimit tonĂ«. E pĂ«r mĂ« tepĂ«r, ato mund tĂ« gjenerohen edhe nĂ« anĂ«n e klientit â kjo do tĂ« na ndihmojĂ« tĂ« mbajmĂ« dĂ«rgimin e mesazheve edhe nĂ« rastin e mungesĂ«s afatshkurtĂ«r tĂ« DB-sĂ«, dhe probabiliteti i kolizionit Ă«shtĂ« shumĂ« i ulĂ«t.
Struktura e projektuar e tabelave në db-në tonë do të duket në këtë mënyrë:
Tabelat : RU
CREATE TABLE "Tema"(
"Tema"
uuid
PRIMARY KEY
, "Dokument"
uuid
, "Emri"
text
);
CREATE TABLE "Mesazh"(
"Mesazh"
uuid
PRIMARY KEY
, "Tema"
uuid
, "Autori"
uuid
, "DataKohë"
timestamp
, "Teksti"
text
);
CREATE TABLE "Adresat"(
"Mesazh"
uuid
, "Personë"
uuid
, PRIMARY KEY("Mesazh", "Personë")
);
CREATE TABLE "Skedari"(
"Skedari"
uuid
PRIMARY KEY
, "Mesazh"
uuid
, "BLOB"
uuid
, "Emri"
text
);Tabelat : 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
);Më e thjeshta në përshkrimin e formatit është të fillosh të «shkruash» grafikun e marrëdhënieve nga tabelat që nuk referohen për askënd.
Hapi 4: Zbuloni nevojat që nuk janë të dukshme
E gjithë, ne projektuam një bazë në të cilën mund të shkruajmë mirë dhe dhe ndonjëherë lexojmë.
Le tĂ« vendosim veten nĂ« vendin e pĂ«rdoruesit tĂ« shĂ«rbimit tonĂ« â çfarĂ« do tĂ« dĂ«shironim tĂ« bĂ«nim me ndihmĂ«n e tij?
- Mesazhet e fundit
Kjo të renditura kronologjikisht në një regjistër të mesazheve «të mia» sipas disa kritereve. Aty ku unë jam një nga adresat, ku unë jam autori, ku dikush më shkroi, por unë nuk kam përgjigjur, ku nuk më është përgjigjur,⊠- Pjesëmarrësit e bisedës
Kush merr pjesë në këtë bisedë shumë të gjatë?
Struktura jonĂ« lejon tĂ« zgjidhen tĂ« dy kĂ«to detyra «nĂ« pĂ«rgjithĂ«si», por shpejt â jo. Problemi Ă«shtĂ« se pĂ«r renditjen nĂ« kuadĂ«r tĂ« detyrĂ«s sĂ« parĂ« nuk Ă«shtĂ« e mundur tĂ« krijosh njĂ« indeks, e pĂ«rshtatshĂ«m pĂ«r tĂ« gjithĂ« pjesĂ«marrĂ«sit (dhe do tĂ« duhet tĂ« nxirren tĂ« gjitha regjistrimet), ndĂ«rsa pĂ«r zgjidhjen e dytĂ« Ă«shtĂ« e nevojshme tĂ« nxirren tĂ« gjitha mesazhet pĂ«r tema.
Detyrat e paplanifikuara të përdoruesve mund të vendosin një vulë të rëndë në performancën.
Hapi 5: Denormalizimi i arsyeshëm
Të dyja problemet tona do të zgjidhen duke shtuar tabela të tjera, në të cilat ne do të dyfishojmë një pjesë të të dhënave, të nevojshme për formimin e indekseve që i përshtaten detyrave tona.

Tabelat : RU
CREATE TABLE "RegistryMessages"(
"Pronari"
uuid
, "TipiRegistry"
smallint
, "DataOra"
timestamp
, "Mesazhi"
uuid
, PRIMARY KEY("Pronari", "TipiRegistry", "Mesazhi")
);
CREATE INDEX ON "RegistryMessages"("Pronari", "TipiRegistry", "DataOra" DESC);
CREATE TABLE "PjesëmarrësiTemës"(
"Tema"
uuid
, "Personi"
uuid
, PRIMARY KEY("Tema", "Personi")
);Tabelat : 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)
);Këtu kemi aplikuar dy qasje tipike që përdoren gjatë krijimit të tabelave mbështetëse:
- Shumëzimi i regjistrimeve
Ne formojmĂ« nga njĂ« regjistrim origjinal mesazhi disa regjistrime pasuese nĂ« forma tĂ« ndryshme pĂ«r regjistrat pĂ«r pronarĂ« tĂ« ndryshĂ«m â si pĂ«r dĂ«rguesin ashtu edhe pĂ«r marrĂ«sin. MegjithatĂ«, çdo regjistĂ«r tani pĂ«rputhet me indeksin â pasi nĂ« rastin tipik ne do tĂ« duam tĂ« shohim vetĂ«m faqen e parĂ«. - Unikalizimi i regjistrimeve
Me çdo dĂ«rgesĂ« mesazhi brenda njĂ« teme specifike, mjafton tĂ« kontrollohet nĂ«se njĂ« regjistĂ«r i tillĂ« ekziston tashmĂ«. NĂ«se jo â ne e shtojmĂ« atĂ« nĂ« "fjalorin" tonĂ«.
Në pjesën tjetër të artikullit do të flasim për në strukturën e bazës sonë.
Burimi: habr.com
