Planiranje MySQL baze podataka za web aplikacije
Kad tri zaposlenika ujutro paralelno knjiže robu, kupac provjerava status dostave, a računovodstvo izdaje račun, kvaliteta aplikacije ne vidi se u dizajnu. Pokazuje se u tome vidi li svatko potpuno isto, ispravno stanje podataka. Planiranje MySQL baze podataka za web aplikaciju stoga ne znači stvaranje tablica što je brže moguće. Znači razumjeti stvarne tijekove rada dovoljno precizno da se osigura da podaci ostanu pouzdani čak i pod opterećenjem, tijekom pogrešaka i dok tvrtka raste.
Osobito kod internih platformi, skladišnih i narudžbenih procesa ili portala okrenutih kupcima, baza podataka često se rješava prekasno. Prvo se izgradi sučelje, zatim se dodaju polja, potom iznimke. To funkcionira za prototip. U produkciji to rezultira udvostručenim skupovima podataka, nejasnim stanjima i izvještajima kojima nitko više u potpunosti ne vjeruje.
Planiranje MySQL baze podataka za web aplikacije: krenite od tijeka rada
Prva skica ne bi trebala početi s nazivima stupaca, nego s konkretnom radnom situacijom. Uzmimo prijem robe: isporuka stiže, dodjeljuje se dobavljaču i narudžbi, provjeravaju se količine, dodjeljuje se lokacija u skladištu i zaliha se mijenja. Ovisno o operaciji, ovaj proces dodatno zahtijeva fotografije, kontrolu kvalitete, status blokade ili sljedivu ispravku.
Iz ovog tijeka rada proizlaze funkcionalni objekti. Tipični primjeri su artikli, dobavljači, narudžbe, stavke, lokacije u skladištu, kretanja zaliha i korisnici.
Razlika između objekta i događaja je ključna. Artikl opisuje što nešto jest. Kretanje zalihe dokumentira da se količina promijenila na određenoj lokaciji u određenom trenutku. Miješanje oboje u jednoj tablici brzo dovodi do gubitka sljedivosti.
Nekoliko teških pitanja pomaže za svaki objekt: koji je jedinstveni identitet? Koje se informacije smiju mijenjati? Tko ih smije mijenjati? Koji se podaci moraju čuvati povijesno? I koja pravila vrijede kad dvije osobe rade istovremeno? Ta pitanja bolje sprječavaju naknadnu improvizaciju nego dugačak popis navodno potpunih polja baze podataka.
Model podataka trebao bi izražavati pravila
Baza podataka nije samo spremište za unose iz obrazaca. Trebala bi sama provoditi središnja pravila. Ako svako kretanje zalihe mora pripadati točno jednom artiklu i jednoj lokaciji skladišta, strani ključevi imaju mjesto u modelu. Ako se vanjski broj narudžbe smije pojaviti samo jednom po tenantu, potreban je jedinstveni indeks. Ako stavka nikad ne bi trebala postojati bez zaglavne narudžbe, tu vezu treba jasno modelirati.
MySQL 8 s InnoDB-om za to pruža čvrste temelje: transakcije, strane ključeve, mehanizme zaključavanja i dosljedne promjene u više tablica. Kad se pri knjiženju prijema robe upisuje kretanje, trenutna zaliha i zapisnik inspekcije, to bi se trebalo dogoditi kao jedna cjelovita transakcija. Ako jedan korak ne uspije, ne smije ostati napola dovršena operacija.
Ipak, ne pripada svako pravilo u bazu podataka. Odobrenja, složena logika cijena ili koraci procesa ovisni o ulozi često su bolje smješteni u aplikacijsku logiku jer se funkcionalno brže mijenjaju. Granica je pragmatična: pravila čije kršenje trajno oštećuje podatke trebalo bi osigurati što bliže samim podacima. Pravila koja se često mijenjaju ili snažno ovise o kontekstu zahtijevaju dobro testiran aplikacijski kod.
Ne miješajte povijest s trenutnim vrijednostima
Česta je pogreška pohranjivati samo trenutnu zalihu ili trenutni status. To je dovoljno dok netko ne upita zašto se količina jučer promijenila ili tko je vratio narudžbu. Za operativne sustave povijest kretanja ili događaja često je vrjednija od jednog polja koje se jednostavno prepisuje.
To ne znači da treba trajno bilježiti svaki klik. Trebalo bi bilježiti poslovno relevantne promjene: promjene statusa, izmjene količina, ispravke, odobrenja i dodjele. Dobar revizijski zapis sadrži vremensku oznaku, korisnika ili sistemski proces, prethodnu i novu vrijednost te razumljiv razlog kad to tijek rada zahtijeva. To omogućuje razjašnjavanje pogrešaka bez pretraživanja e-pošte, papirnatih popisa ili sigurnosnih kopija baze podataka.
Svjesno birajte ključeve, tipove podataka i konvencije imenovanja
Tehničke odluke djeluju sitno, ali oblikuju održavanje i integracije godinama. Za interne primarne ključeve, BIGINT vrijednosti s automatskom dodjelom često su trijezan, lako upravljiv izbor. UUID-ovi mogu imati smisla kad podaci nastaju izvanmrežno, više sustava piše neovisno, ili vanjska sučelja ne bi trebala otkrivati sekvencijalne ID-jeve. Ipak, troše više prostora za pohranu i zahtijevaju nešto više pažnje kod indeksa i sortiranja.
Novčani iznosi trebaju se pohranjivati kao DECIMAL, a ne FLOAT ili DOUBLE. Količinama je također potrebna funkcionalno prikladna preciznost: broj artikala često su cijeli brojevi, dok težine i duljine to nisu. Vremenske oznake trebalo bi obrađivati ujednačeno, idealno interno u UTC-u, dok sučelje prikazuje lokalnu vremensku zonu operacije. Osobito tijekom promjena smjena i ljetnog računanja vremena, to sprječava teško uočljive nesuglasice.
Nazivi bi također trebali biti dosadni i nedvosmisleni. order_items ili inventory_movements korisniji su od kreativnih skraćenica koje razumije samo izvorni projektni tim. Dosljedni jednina ili množina manje su bitni od same dosljednosti. Jednako smislena su polja poput created_at, updated_at i, kad je potrebno, deleted_at. Meko brisanje ipak nije standardna obveza. Za pravno ili operativno relevantne zapise, čisto poništenje obično je bolje od nevidljivo obrisanog skupa podataka.
Indeksi prate stvarne upite, ne nagađanje
Indeks može masovno ubrzati pretragu, ali čini operacije pisanja složenijima i troši prostor za pohranu. Zato "indeks na svakom polju" nije strategija. Najvažnije upite trebalo bi utvrditi rano: otvorene narudžbe kupca, kretanja artikla unutar razdoblja, zalihu po lokaciji skladišta ili nedavno izmijenjene zapise za sučelje.
Redoslijed složenih indeksa ovdje je bitan. Ako aplikacija redovito pretražuje po tenant_id, status i created_at, složeni indeks u tom točnom redoslijedu često je smislen. Odgovara li stvarno, pokazuje plan izvršavanja putem EXPLAIN, a ne osjećaj. Baze podataka ne postaju brze zbog spektakularnih trikova, nego zbog vidljivih upita, odgovarajućih indeksa i realistično testiranih količina podataka.
Za tablice koje rastu isplati se jasna strategija zadržavanja. Moraju li tehnički zapisi ostati u primarnoj produkcijskoj bazi pet godina? Ne nužno. Poslovni zapisi, kretanja i dokazi inspekcije zahtijevaju drugačija razdoblja zadržavanja od podataka za debugiranje. Arhiviranje nije znak slabog sustava, nego namjerna operativna odluka.
Rad s više korisnika zahtijeva transakcije i jasna stanja
U web aplikaciji više zahtjeva istovremeno pristupa istim podacima. To je normalno u svakodnevnom skladišnom poslovanju, ne iznimka. Dva zaposlenika mogu knjižiti istu zalihu dok uvoz stvara nove narudžbe. Bez transakcija i ciljanog zaključavanja postoji rizik od izgubljenih izmjena ili negativnih zaliha koje postanu vidljive tek tjednima kasnije.
Za kritične operacije trebalo bi biti jasno koji se podaci čitaju i pišu unutar transakcije. Ponekad je dovoljno atomsko ažuriranje, primjerice zaliha koja se mijenja samo ako je dostupna količina dovoljna. U drugim slučajevima smisleno je zaključavanje retka kako bi operacija mogla kontrolirano provjeriti stanje podataka i naknadno ga izmijeniti. Duge transakcije, s druge strane, problematične su: blokiraju drugi rad i povećavaju rizik od sukoba.
Jednako je važan ograničen skup funkcionalnih stanja. Narudžba ne bi trebala biti istovremeno "otvorena", "djelomično isporučena" i "ručno obrađena" zbog održavanja proturječnih polja. Definirani prijelazi statusa pojednostavljuju sučelja, izvještaje i automatizacije. Iznimke mogu biti dopuštene, ali trebale bi biti imenovane i dokumentirane.
Planirajte sigurnost, tenante i poslovanje od samog početka
Aplikacija bi trebala koristiti namjenskog korisnika baze podataka za MySQL s minimalnim ovlastima. Pristup pisanju za web aplikaciju ne znači da taj korisnik treba moći brisati tablice ili mijenjati korisničke ovlasti. Administrativni računi ne pripadaju produkcijskim konfiguracijskim datotekama i nikad repozitoriju.
Kad unutar jedne aplikacije rade više klijenata, lokacija ili tvrtki, izolacija tenanata arhitektonska je odluka, a ne naknadno dodan uvjet filtriranja. Zajednička baza podataka s tenant_id-om može biti učinkovita i lako održiva, ali zahtijeva dosljedne provjere u svakom upitu i jasna pravila za indekse. Odvojene baze podataka nude jaču izolaciju, ali povećavaju trud pri ažuriranjima, evaluacijama i poslovanju. Koja varijanta odgovara ovisi o zahtjevima privatnosti podataka, količini podataka i poslovnom modelu.
Sigurnosne kopije samo su sigurnosne kopije nakon što je obnavljanje testirano. Potreban je definiran ritam za sigurnosne kopije, zadržavanje i oporavak. Isto tako, sustavu pripada nadzor prostora za pohranu, sporih upita i neuspjelih zadataka, zajedno s dokumentiranim ažuriranjima. MySQL 8, PHP 8.4 i moderne web aplikacije mogu se dobro voditi dugoročno ako ovisnosti, pristupni podaci i koraci implementacije ne postoje isključivo u glavi jednog razvojnog programera.
Smislen plan prije prvog dana u produkciji
Prije implementacije trebao bi postojati kompaktan model podataka s primjerima tijekova rada. To uključuje ključne tablice i odnose, pravila statusa, ovlasti, očekivane upite, sučelja i koncept za sigurnosne kopije i revizijske zapise. Taj plan ne mora imati sto stranica. Mora obuhvatiti odluke koje bi kasnije bilo skupo ispraviti.
U softify.pro, planiranje baze podataka stoga počinje s ljudima koji knjiže, provjeravaju, komisioniraju ili rješavaju iznimke. Ako postojeća tablica pouzdano preslikava upravljiv proces, ona može ostati ispravno rješenje. Ako više ljudi radi istovremeno, nastaju zapisi, a pogreške moraju biti sljedive, baza podataka zaslužuje isti trud planiranja kao i sučelje. Najbolja arhitektura na kraju je ona koja pojednostavljuje radni dan i koja se za dvije godine i dalje može transparentno mijenjati.