Plánování databáze MySQL pro webové aplikace

Když tři zaměstnanci ráno paralelně knihují zboží, zákazník kontroluje status dodávky, a back office vytváří fakturu, kvalita aplikace se neprojevuje v jejím designu. Projevuje se v tom, zda všichni vidí přesně stejný, správný stav dat. Plánování databáze MySQL pro webovou aplikaci proto neznamená vytváření tabulek co nejrychleji. Znamená to pochopení skutečných pracovních postupů dostatečně přesně, aby se zajistilo, že data zůstanou spolehlivá i pod zátěží, během chyb, a s růstem firmy.

Obzvlášť v interních platformách, skladových a objednávkových procesech, nebo zákaznických portálech, se databáze často řeší příliš pozdě. Nejprve se vybuduje rozhraní, poté se přidají pole, následované výjimkami. To funguje pro prototyp. V provozu to vede k duplicitním datovým sadám, nejasným stavům, a zprávám, kterým už nikdo plně nedůvěřuje.

Plánování databáze MySQL pro webové aplikace: začněte pracovním postupem

První návrh by neměl začínat názvy sloupců, ale konkrétní pracovní situací. Vezměte příjem zboží: dodávka přichází, je přiřazena k dodavateli a objednávce, množství jsou zkontrolována, je přiřazeno skladové místo, a zásoba se mění. V závislosti na provozu tento proces dodatečně vyžaduje fotografie, kontrolu kvality, status pozastavení, nebo sledovatelnou opravu. Z tohoto pracovního postupu vznikají funkční objekty. Typickými příklady jsou artikly, dodavatelé, objednávky, pozice, skladová místa, pohyby zásob, a uživatelé.

Rozlišení mezi objektem a událostí je klíčové. Artikl popisuje, čím něco je. Pohyb zásoby dokumentuje, že se množství změnilo na konkrétním místě v konkrétním čase. Míchání obojího v jedné tabulce rychle vede ke ztrátě sledovatelnosti.

Několik těžkých otázek pomáhá pro každý objekt: jaká je jedinečná identita? Která informace se smí měnit? Kdo ji smí měnit? Která data musí být uchovávána historicky? A jaká pravidla platí, když dva lidé pracují současně? Tyto otázky zabraňují pozdější improvizaci lépe než dlouhý seznam údajně kompletních databázových polí.

Datový model by měl vyjadřovat pravidla

Databáze není jen úložiště pro vstupy formulářů. Měla by sama vynucovat centrální pravidla. Pokud každý pohyb zásoby musí patřit právě k jednomu artiklu a jednomu skladovému místu, cizí klíče patří do modelu. Pokud se externí číslo objednávky smí vyskytnout jen jednou na nájemce, vyžaduje se jedinečný index. Pokud by pozice nikdy neměla existovat bez hlavičkové objednávky, tento vztah musí být jasně modelován.

MySQL 8 s InnoDB poskytuje pro toto robustní základy: transakce, cizí klíče, mechanismy uzamykání, a konzistentní změny napříč více tabulkami. Při zapisování pohybu, aktuální zásoby, a kontrolního deníku během knihování příjmu zboží by se to mělo dít jako jednotná transakce. Pokud jeden krok selže, nesmí zůstat žádná napůl dokončená operace.

Ne každé pravidlo však patří do databáze. Schválení, komplexní cenová logika, nebo procesní kroky závislé na roli jsou často lépe umístěny v logice aplikace, protože se funkčně mění rychleji. Hranice je pragmatická: pravidla, jejichž porušení trvale poškozuje data, by měla být zabezpečena co nejblíže k datům. Pravidla, která se mění často nebo silně závisí na kontextu, vyžadují dobře otestovaný kód aplikace.

Nezaměňujte historii se současnými hodnotami

Běžnou chybou je ukládání jen aktuální zásoby nebo aktuálního statusu. To stačí, dokud se někdo nezeptá, proč se množství změnilo včera nebo kdo resetoval objednávku. Pro provozní systémy je historie pohybů nebo událostí často hodnotnější než jediné přepisovatelné pole.

Toto neznamená trvalé zaznamenávání každého kliknutí. Měly by být zaznamenávány obchodně relevantní změny: změny statusu, úpravy množství, opravy, schválení, a přiřazení. Dobrý auditní záznam obsahuje časovou značku, uživatele nebo systémový proces, předchozí a novou hodnotu, a srozumitelný důvod, když to pracovní postup vyžaduje. Toto umožňuje vyjasnit chyby, aniž by bylo potřeba prohledávat e-maily, papírové seznamy, nebo zálohy databáze.

Vědomě zvolte klíče, datové typy, a konvence pojmenování

Technická rozhodnutí se zdají malá, ale formují údržbu a integrace po celé roky. Pro interní primární klíče jsou hodnoty BIGINT s automatickým přiřazením často střízlivou, snadno zvládnutelnou volbou. UUID mohou být smysluplné, když data pocházejí offline, více systémů zapisuje nezávisle, nebo externí rozhraní by neměla vystavovat sekvenční ID. Avšak stojí více úložného prostoru a vyžadují o něco více pozornosti u indexů a třídění.

Peněžní částky by měly být uloženy jako DECIMAL, ne FLOAT nebo DOUBLE. Množství také potřebují funkčně přiměřenou přesnost: počty kusů jsou často celá čísla, zatímco hmotnosti a délky nejsou. Časové značky by měly být zpracovávány jednotně, ideálně interně v UTC, zatímco rozhraní zobrazuje místní časové pásmo provozu. Obzvlášť během změn směn a letního času toto zabraňuje těžko nalezitelným nesrovnalostem.

Názvy by měly být také nudné a jednoznačné. order_items nebo inventory_movements jsou užitečnější než kreativní zkratky, kterým rozumí jen původní projektový tým. Konzistentní jednotné nebo množné formy jsou méně důležité než konzistentnost. Stejně smysluplná jsou pole jako created_at, updated_at, a, když je potřeba, deleted_at. Měkké mazání nicméně není standardní povinností. Pro právně nebo provozně relevantní záznamy je čisté stornování obvykle lepší než neviditelně smazaná datová sada.

Indexy sledují skutečné dotazy, ne hádání

Index může masivně zrychlit vyhledávání, ale činí zápisové operace komplexnějšími a spotřebovává úložný prostor. Proto „index na každém poli" není strategie. Nejdůležitější dotazy by měly být stanoveny brzy: otevřené objednávky zákazníka, pohyby artiklu v rámci období, zásoba na skladové místo, nebo nedávno upravené záznamy pro rozhraní.

Pořadí složených indexů zde záleží. Pokud aplikace pravidelně vyhledává podle tenant_id, status, a created_at, složený index v tomto přesném pořadí je často smysluplný. Zda to skutečně sedí, ukazuje prováděcí plán pomocí EXPLAIN, ne pocit. Databáze se nestávají rychlými díky působivým trikům, ale díky pozorovatelným dotazům, odpovídajícím indexům, a realisticky testovaným objemům dat.

Pro rostoucí tabulky je hodnotná jasná strategie uchovávání. Musí technické deníky sedět v primární produkční databázi pět let? Ne nutně. Obchodní záznamy, pohyby, a důkazy kontroly vyžadují jiné doby uchovávání než ladicí informace. Archivace není znakem slabého systému, ale promyšleným provozním rozhodnutím.

Provoz více uživatelů vyžaduje transakce a jasné stavy

Ve webové aplikaci přistupuje více požadavků ke stejným datům současně. Toto je normální v každodenním skladovém provozu, ne výjimka. Dva zaměstnanci mohou knihovat stejnou zásobu, zatímco import vytváří nové objednávky. Bez transakcí a cíleného uzamykání existuje riziko ztracených úprav nebo záporných zásob, které se stanou zjevnými až o týdny později.

Pro kritické operace by mělo být jasné, která data jsou čtena a zapisována v rámci transakce. Někdy stačí atomická aktualizace, jako zásoba, která se mění jen tehdy, když je dostupné množství dostatečné. V jiných případech je smysluplný zámek řádku, aby operace mohla zkontrolovat stav dat kontrolovaným způsobem a upravit ho poté. Dlouhé transakce jsou naopak problematické: blokují jinou práci a zvyšují riziko konfliktů.

Stejně důležitá je omezená sada funkčních stavů. Objednávka by neměla být současně „otevřená", „částečně dodaná", a „ručně zpracovaná" kvůli udržovaným protichůdným polím. Definované přechody statusu činí rozhraní, zprávy, a automatizace jednoduššími. Výjimky mohou být povoleny, ale měly by být pojmenovány a zdokumentovány.

Naplánujte bezpečnost, nájemce, a provoz od začátku

Aplikace by měla používat vyhrazeného databázového uživatele pro MySQL s minimálními oprávněními. Přístup k zápisu pro webovou aplikaci neznamená, že tento uživatel potřebuje mazat tabulky nebo měnit oprávnění uživatelů. Administrativní účty nepatří do produkčních konfiguračních souborů a nikdy do repozitáře.

Když v rámci aplikace pracuje více zákazníků, lokalit, nebo firem, izolace nájemců je architektonické rozhodnutí, ne retroaktivní filtrovací podmínka. Sdílená databáze s tenant_id může být efektivní a snadno udržitelná, ale vyžaduje konzistentní kontroly v každém dotazu a jasná pravidla pro indexy. Oddělené databáze nabízejí silnější izolaci, avšak zvyšují námahu při aktualizacích, vyhodnoceních, a provozu. Která varianta sedí, závisí na požadavcích ochrany dat, objemu dat, a obchodním modelu.

Zálohy jsou zálohami až tehdy, když bylo obnovení otestováno. Vyžaduje se definovaný rytmus pro zálohy, uchovávání, a obnovu. Podobně, monitorování úložného prostoru, pomalých dotazů, a selhaných úloh, spolu se zdokumentovanými aktualizacemi, patří k systému. MySQL 8, PHP 8.4, a moderní webové aplikace mohou být dlouhodobě dobře provozovány, pokud závislosti, přístupové údaje, a kroky nasazení nesídlí výhradně v hlavě vývojáře.

Smysluplný plán před prvním dnem v produkci

Před implementací by měl existovat kompaktní datový model s příkladovými pracovními postupy. Toto zahrnuje klíčové tabulky a vztahy, pravidla statusu, oprávnění, očekávané dotazy, rozhraní, a koncept pro zálohy a auditní deníky. Tento plán nemusí mít sto stran. Musí zachytit rozhodnutí, jejichž pozdější oprava by byla nákladná.

Ve softify.pro proto plánování databáze začíná lidmi, kteří knihují, kontrolují, vychystávají, nebo řeší výjimky. Pokud existující tabulka spolehlivě zobrazuje zvládnutelný proces, může zůstat správným řešením. Pokud pracuje více lidí současně, vznikají záznamy, a chyby musí být sledovatelné, databáze si naopak zaslouží stejné plánovací úsilí jako rozhraní. Nejlepší architektura je nakonec ta, která zjednodušuje pracovní den a stále může být transparentně změněna za dva roky.