Zobrazit příspěvky

Tato sekce Vám umožňuje zobrazit všechny příspěvky tohoto uživatele. Prosím uvědomte si, že můžete vidět příspěvky pouze z oblastí Vám přístupných.


Témata - Urvustrop

Stran: [1]
1
Vývoj / Návrh relační databáze
« kdy: 25. 04. 2019, 13:18:45 »
Nechci někomu na potkání vykládat know-how, ani nežádám vyzrazení suprfičur ostatních. Spíš chci dát prostor ostříleným architektům, aby se pochlubili svým originálním přístupem a inspirovali jiné ztracené duše.
Nastíním problém, který jsem řešil u nás a zároveň předložím řešení, které momentálně používáme:

Vyvíjíme nástroj pro vytváření formulářových aplikací. Je psaná ve WPF, datovou část stavíme nad MSSQL. Klíčem je pro nás silně relační databáze. Výhodou je následná vizualizace její struktury v návrháři datových zdrojů (přes cizí klíče je možné se "proklikat" hlouběji a vynášet sloupce, které jsou potřeba).
Pomocí tohoto nástroje, který obsahuje rozšířené formulářové kontrolky a další komponenty, se poskládá celá appka podle potřeb zákazníka. Její skládání mají na starost implementátoři.

Momentálně vytváříme aplikaci pro evidenci blíže nespecifikovaných objektů, pro účely dalšího popisu řekněme auta a jejich součásti. Objekty jsou mezi sebou svázány (kolo je namontované na nějaké auto). Nad objekty jsou vytvářené různé agendy (např. tickety, platnost kontrol, ...).
Problém je, že objektů je spousta druhů, každý druh má své specifické vlastnosti, které jsou irelevantní pro jiné druhy (auto má počet náprav, které jsou pro kola nesmyslnou vlastností, a naopak poloměr je pro kolo fajn, ale evidovat ho u auta je jaksi zbytečné).
Rozhodli jsme se proto, že objekty budeme dělit do skupin a pro každou skupinu bude vytvořena konkrétní tabulka s potřebnými sloupci. S tím samozřejmě přišla spousta problémů, například jednoznačný identifikátor, který by byl snadný k vygenerování a přesto dostatečně rychlý při vyhledávání (GUID je z hlediska rychlosti tragický). Nebo způsob, jak propojit přes cizí klíče tyto tabulky s tabulkami jednotlivých agend. V neposlední řadě je tu samotné zobrazení dat v aplikaci - jak v seznamu ticketů vypsat jméno objektu, když je pokaždé uložené v jiné tabulce?
Po řadě pokusů a omylů jsme dospěli k řešení, které jistě není dokonalé, ale momentálně splňuje naše požadavky. Pomocí řady triggerů, funkcí, procedur a jiných hrůz jsme zapracovali do struktury databáze tabulku, která funguje jako most mezi tabulkami objektů a tabulkami agend. Toto přemostění obsahuje primární autoinkrementální klíč, který je používaný jako cizí klíč v tabulkách agend a zároveň jako cizí klíč u jednotlivých řádků v tabulkách objektů. Pod každou objektovou tabulkou je vygenerovaný AFTER INSERT, DELETE trigger, který po insertu řádku objektové tabulky vytvoří nový řádek v tabulce přemostění a Id vytvořeného řádku následně vloží do řádku s objektem, který trigger spustil. Toto Id je používáno ve všech místech aplikace - agendy, hierarchie objeků, atd. Obdobná automatika funguje při mazání.
Další tabulka slouží k evidenci skupin (její název, název tabulky). Pod touto tabulkou je trigger, který má na starost generování view, které dává k dispozici přehled všech evidovaných objektů a jejich základních vlastností (evidenční číslo, název, ...). Při vytvoření nové skupiny je select view triggerem upravený tak, aby prováděl union i z tabulky nové skupiny. Implementátor pak ví, že přehled objektů je v tomto view a při vytváření datového zdroje formulářů agend chodí pro vlastnosti objektů právě sem (je to prakticky jediná situace, kdy nemůže při vytváření datového zdroje jednoduše procházet vazby mezi tabulkami).
Tímhle molochem je zajištěná integrita dat (nelze smazat objekt, na který je vystaven ticket apod), každý objekt má svůj jednoznačný identifikátor, a zároveň není v databázi hypertabulka, která by musela obsahovat stovky sloupců, aby zahrnula všechny evidovatelné vlastnosti.

Popsaný přístup má samozřejmě i své nevýhody. Mezi největší momentálně řadím nemožnost/náročnost přesunu objektu z jedné skupiny do druhé.

Řešili jste někdy něco podobného? A jak?

Stran: [1]