Baza noastră nu va fi la fel de mare și distribuită, ca VKontakte sau Badoo, dar „așa că a fost”, dar a fost bun - funcțional, rapid și se potrivesc pe un singur server PostgreSQL - astfel încât să puteți implementa o instanță separată a serviciului undeva în lateral, de exemplu.
Prin urmare, nu ne vom referi la problemele de fragmentare, replicare și sisteme geo-distribuite, ci ne vom concentra pe soluțiile de circuit din interiorul bazei de date.
Pasul 1: Câteva detalii de afaceri
Nu ne vom proiecta mesajele în mod abstract, ci le vom integra în mediu rețea socială corporativă. Adică, oamenii noștri nu „doar corespunde”, ci comunică între ei în contextul rezolvării anumitor probleme de afaceri.
Și care sunt sarcinile unei afaceri?.. Să ne uităm la exemplul lui Vasily, șeful departamentului de dezvoltare.
„Nikolai, pentru această sarcină avem nevoie de un plasture astăzi!”
Aceasta înseamnă că corespondența poate fi efectuată în contextul unora document.
„Kolya, mergi la Dota în seara asta?”
Adică, chiar și o pereche de interlocutori poate comunica simultan pe diverse teme.
„Peter, Nikolay, caută în atașament lista de prețuri pentru noul server.”
Deci, un mesaj poate avea mai mulți destinatari. În acest caz, mesajul poate conține Fișiere atașate.
„Semyon, aruncă o privire și tu.”
Și ar trebui să existe o oportunitate de a intra în corespondența existentă invita un nou membru.
Să ne oprim deocamdată pe această listă de nevoi „evidente”.
Fără a înțelege specificul aplicat al problemei și limitările date acesteia, proiectează efectiv schema bazei de date pentru a o rezolva este aproape imposibil.
Pasul 2: Circuit logic minim
Până acum, totul funcționează foarte asemănător cu corespondența prin e-mail - un instrument tradițional de afaceri. Da, „din punct de vedere algoritmic” multe probleme de afaceri sunt similare între ele, prin urmare instrumentele pentru rezolvarea lor vor fi similare structural.
Să reparăm diagrama logică deja obținută a relațiilor dintre entități. Pentru a face modelul nostru mai ușor de înțeles, vom folosi cea mai primitivă opțiune de afișare Modele ER fără complicațiile notațiilor UML sau IDEF:
În exemplul nostru, persoana, documentul și „corpul” binar al fișierului sunt entități „externe” care există independent fără serviciul nostru. Prin urmare, le vom percepe pur și simplu în viitor ca niște link-uri „undeva” prin UUID.
A desena diagrame cât mai simple - majoritatea oamenilor cărora le vei arăta nu sunt experți în citirea UML/IDEF. Dar asigurați-vă că desenați.
Pasul 3: Schițarea structurii tabelului
Despre numele tabelelor și câmpurilorNumele „rusești” ale câmpurilor și tabelelor pot fi tratate diferit, dar aceasta este o chestiune de gust. Deoarece aici la Tensor nu există dezvoltatori străini, iar PostgreSQL ne permite să dăm nume chiar și în hieroglife, dacă acestea cuprinse între ghilimele, atunci preferăm să numim obiectele fără ambiguitate și clar, astfel încât să nu existe discrepanțe.
Deoarece mulți oameni ne scriu mesaje deodată, unii dintre ei ar putea chiar să facă acest lucru deconectat, atunci cea mai simplă opțiune este utilizați UUID-urile ca identificatori nu numai pentru entitățile externe, ci și pentru toate obiectele din interiorul serviciului nostru. Mai mult, ele pot fi generate chiar și din partea clientului - acest lucru ne va ajuta să acceptăm trimiterea de mesaje atunci când baza de date este temporar indisponibilă, iar probabilitatea unei coliziuni este extrem de scăzută.
Structura schiță a tabelului din baza noastră de date va arăta astfel: Tabele: RU
Cel mai simplu lucru atunci când descrieți un format este să începeți „desfășurarea” graficului conexiunii din tabele care nu sunt referite ei înșiși pentru nimeni.
Pasul 4: Aflați nevoi neevidente
Gata, am conceput o bază de date în care poți scrie perfect și oarecum a citi.
Să ne punem în pielea utilizatorului serviciului nostru - ce vrem să facem cu el?
Ultimele mesaje
Aceasta sortate cronologic un registru al mesajelor „mei” bazat pe diverse criterii. Unde sunt unul dintre destinatari, unde sunt autorul, unde mi-au scris și nu am răspuns, unde nu mi-au răspuns, ...
Participanții la corespondență
Cine participă măcar la această discuție lungă, lungă?
Structura noastră ne permite să rezolvăm ambele probleme „în general”, dar nu rapid. Problema este că pentru sortarea în cadrul primei sarcini nu se poate crea index, potrivit pentru fiecare dintre participanți (și va trebui să extrageți toate înregistrările), iar pentru a le rezolva pe a doua aveți nevoie extrage toate mesajele pe această temă.
Sarcinile utilizatorului neintenționate pot pune bold cruce pe productivitate.
Pasul 5: Denormalizare inteligentă
Ambele probleme vor fi rezolvate prin tabele suplimentare în care vom face duplicat o parte a datelor, necesare pentru a forma pe ele indici potriviți sarcinilor noastre.
Aici am aplicat două abordări tipice folosite la crearea tabelelor auxiliare:
Înmulțirea înregistrărilor
Folosind o singură înregistrare inițială a mesajului, creăm mai multe înregistrări ulterioare în diferite tipuri de registre pentru diferiți proprietari - atât pentru expeditor, cât și pentru destinatar. Dar fiecare dintre registre cade acum pe index - la urma urmei, într-un caz tipic, vom dori să vedem doar prima pagină.
Înregistrări unice
De fiecare dată când trimiteți un mesaj într-un anumit subiect, este suficient să verificați dacă o astfel de intrare există deja. Dacă nu, adăugați-l în „dicționarul”.
În următoarea parte a articolului vom vorbi despre implementarea partiționării în structura bazei noastre de date.