ja bych mel nekolik otazek ohledne tech modernich technologii (na autora ale i na ostatni odborniky, kteri zde ctou a mohou sdelit konkretni zkusenosti)
Aktualne jsme u toho, provest zasadni zmeny u informacniho systemu jednoho zaklaznika. Je to letite software, ktere jede se sitovou databazi a za dlouha leta provozu to umi radu veci, ktere bezne informacni systemy na trhu nedokazou - proto chce zakaznik zachovat pokud mozno vse, co system umi, ale souhlasi s prechodem na moderni databaze a programovaci prostredi.
Dnes je mozno se rozhodnout pouze pro nejakou relacni databazi. Existuji jine exoticke systemy, ale z politickych duvodu je treba asi sahnout k temto. Stavajici system bezel bez transakci a tech ruznych integrit (30 let a kupodivu se nikdy neztratila zadna data a ani se nejak jinak neznicila) - presto se uvazuje o tom, ze se ACID pouzije a system se na to upravi -> coz je jedna z tech bolestivych zmen.
Otazka1: Je to skutecne bezpodminecne nutne u systemu rizeny vyroby pracovat s transakcemi?
Casto se hovori o te referencni integrite. Kdysi davno jsem zazil, jak kolegove u zakznika udelali tu integritu 'spravne' a pote se pri smazani jedne radky hledal backup, protoze se 'cascade' smazala 1/2 databaze.
Otazka2: Je to s tou referencni integritou skutecne tak dulezite a nebo to vice prekazi nez pomaha. Opet, nejedna se o ucetnictvi ale o rizeni a pripravu vyroby. Zkusenosti z praxe vitany
Zakaznikovi se libi free databaze (linux) v uzsim vyberu je prave Postgresql, MariaDB, MaxDB a Firebird. Zbezne jsme prohledli zakladni sql-syntax a neshledali jsme vlastne vubec zadne rozdily.
Zde se jedna skutecne o zakladni sql-prikazy. Radi bychom totiz, kdyz uz ses tim budeme zabyvat to udelali tak, aby to bezelo s kazdou tou databazi. Storage procedury nechceme pouzivat.
Otazka3: Odpovida to zkusenostem, je to realne?
Jak jiz uvedeno, je informacni system plny ruznych vychytavek a zvlastnosti. Proto se jevi jako jedine schudne pouzit jednoduche sql-prikazy a zpracovani provadet v aplikacnim servru (tak je to nyni take) s tim, ze se vyuziji prapared statements. Udelali jsme si nekolik testu na takove hracce (CPU Celeron 837, HDD 2,5'' 5400 U/min)) a MariaDB s Innodb dokaze provest 10 tisic selectu za vterinu. To by nam bohate stacilo a mohli bychom jit tedy cestou jednoduchych prikazu, misto toho vsechno prekopat.
Otazka4: Jsou zkusenosti s prepared statement skutecne takove, ze moderni databaze obdobne prikazy neparsuji a hned vyvolaji provadeci plany. Jaka je procentuelne asi to zrychleni?
Pro rozpady kusovniku a jine rekurzivni zalezitosti by se nabizela ta CTE funkcionality - autorovo tema. U zakaznika je to tak, ze v prubehu toho rozpadu se na urcite urovni nebo podle nejakych priznaku rozhoduje, zda se ma jit ve strukture o uroven nize a nebo take ne. Zakaznik si proste vede v kusovniku u pozice prepinac, ktery rika, zda se ma v tom okamziku dale provadet rekurze a nebo zda se ma system rozpadu chovat tak, jako by uz polozka byla konecna (nakupni polozka). Jestli jsem to v clanku dobre pochopil, tak v tom prostrednim selectu u toho prikazu 'with recursion' by se neco takoveho muselo zohlednit. To mi prijde hrozne obtizne.
Otazka5: je u tech rekurzi mozno v prubehu toho zpracovani jen za pomoci toho selectu provest nejake rozhodovani?
U tech rekurzivnich struktur je jeste jedna takova neprijemna vec. Kdyz se ten kusovnik zapise 'nesikovne', tak se ten rozpad zacykli.
Otazka 6: je v ramci CTE nejak osetreno to zacykleni a jak. Je uzivateli v ramci tech relacnich databazi nabidnuta nejaka podpora, aby napr. ten kusovnik nemohl zapsat 'nesikovne'
Ad 1 a 2 – Podle mne to chápete špatně. Transakce nebo referenční integrita nejsou umělá omezení, která vám mají házet klacky pod nohy když modelujete reálný svět. Právě naopak, jsou to pomůcky, které vám pomáhají udělat databázový model tak, aby odpovídal reálnému světu. Třeba když přesouváte výrobek z jednoho skladu do druhého, nemůže se vám stát, že v druhém skladu se výrobek objeví, ale v prvním nezmizí – a k tomu slouží transakce, aby se ta operace (odečtení z jednoho skladu a přičtení do druhého) provedla buď celá, nebo vůbec. Podobně ta referenční integrita – to, že se vám smazala půlka databáze, svědčí o tom, že to rozhodně nebylo udělané správně. Za prvé se kaskádový delete nebo update používá jen velmi výjimečně, za druhé to zase slouží k modelování reality – takže pokud obsluha zadala, že se má něco smazat, měla se dozvědět, že na dané věci závisí to a to a to, a v tom okamžiku by si musela uvědomit, že chce mazat něco, co v realitě stále existuje.
Ad 3 – V základní syntaxi SQL příkazů se různé databáze opravdu neliší, proto je SQL definováno jako standard. Liší se v tom, co umí navíc a jak dobře umí pracovat s daty. Pokud potřebujete jenom někam zapsat seznam záznamů a pak je zase přečíst, zvládne to perfektně i MySQL, a dokonce v tom bude lepší, než jiné databáze, protože bude rychlejší. Pokud potřebujete v jedné transakci zapsat hromadu strukturovaných navzájem provázaných údajů, další údaje z toho dopočítat a udržovat integritu dat (bohatší, než co dokáže běžná referenční integrita), MySQL vám bude k ničemu, v jednodušších případech si vystačíte s PostgreSQL, a pro složitější databázi vám stejně nezbyde nic jiného než Oracle.
Ad 4 – MySQL opravdu není dobrá na zkoumání toho, jak se chovají moderní relační databáze. Pokud chcete databázi jenom jako hloupé úložiště záznamů a veškerou logiku chcete provádět v aplikaci, je z relačních databází MySQL/MariaDB asi nejlepší volba. Ale je otázka, zda v takovém případě je vůbec dobrou volbou relační databáze. Každopádně je pak zbytečné zkoumat do hloubky vlastnosti moderních relačních databází, protože vy je používat nechcete.
Ad 5 – Ano, v rekurzivním dotazu se samozřejmě vyhodnocují podmínky stejně, jako v kterémkoli jiném – akorát tam máte navíc předchozí úroveň a aktuální úroveň záznamů. Ale jak už jsem psal, je otázka, zda je pro vás relační databáze dobrá volba, když píšete, že nechcete používat žádné její podstatné vlastnosti a spíš řešíte, jak ji ohnout do svého pojetí. Takhle se pracovalo několik posledních desetiletí (relační databáze byly prakticky jediné dostupné spolehlivé úložiště dat, takže všichni řešili, jak svůj model ohnout pro relační databázi), v posledních pár letech je boom No-SQL databází, které řeší právě to, že ne každý model je vhodné násilím ohýbat do relační databáze.
Ad 6 – tohle právě řeší kontrola integrity dat v databázi. Jenže když nechcete v databázi řešit žádnou logiku a měla by jí zajišťovat jen aplikace měla by aplikace řešit i tohle.
1. Transakce řeší několik problémů. Ve vašem případě to mohou být tyto dva problémy: více lidí měnících si vzájemně data a problém se selháním některé z operací. Ale tady velmi záleží na tom, zda to pro vás opravdu problémy jsou. Systém se dá napsat tak, aby mu nevadilo, že si uživatelé vzájemně vidí nedokončené transakce. Stejně tak jde napsat tak, aby se vypořádal se selháním některé z dílčích operací. Například převod materiálu z lokace A na lokaci B: ponížím stav materiálu na lokaci A. Pokud to selže, tak selhala transakce. Pokud to projde, tak navýším stav materiálu na lokaci B. Pokud to selže, tak opět navýším stav materiálu na lokaci A (vrátím materiál). Transakční databáze vám v tomhle zjednoduší práci, nemusíte nic moc testovat. Pokud vám B selže, tak prostě uděláte rollback. Pokud to už ale zprogramované máte, tak cpát tam silou transakce bude zbytečná práce navíc.
2. Referenční integrita je něco trochu jiného. Například řeknete, že v tabulce stavu skladu v poli číslo položky smí být jen taková položka, která existuje v tabulce položek. Tuto kontrolu ale můžete provádět sám, ve své aplikační logice. Pak vám referenční integrita nic moc nenabízí. Ostatně řada ERP systémů ji nepoužívá a vše kontroluje aplikační server. A co se cascade delete týká, tak to je naprostá marginalita. Nechci říkat, že se to nikdy nikde nepoužívá, ale sám jsem to použil jen na škole v semestrálce. Obecně řečeno tím říkáte, že když smažete položku, tak chcete smazat i veškeré záznamy o položce - stav skladu, historii skladových transakcí, objednávky atd. To skoro nikdy nechcete. Naopak chcete, aby vám referenční integrita oznámila, "sorry, položka už byla použita, smazat nepůjde".
3. Jen bych uvedl, že "aby to běželo s každou" nebývá úplně triviální úloha. Ačkoliv ty databáze umí ANSI SQL, tak některé věci budete muset psát několikrát. Vybrat si dvě nebo tři je průchozí, ale ověřovat a přizpůsobovat funkci na 4+ různých databázích je hodně práce navíc.
4. Nemám moc s čím srovnat. Osobní zkušenost mám tu, že se SQL vyplatí používat více. On SELECT dokáže poskládat data hodně efektivně. Ostatně to je jeho účel. Určitě je to lepší, než si stáhnout obsah několika tabulek do aplikačního serveru a teprve tam si začít data spojovat. A on i vhodně napsaný INSERT a UPDATE dokáže potěšit (insert into A select from B where x not in select from C). Takže třebas rozpad kusovníku děláme SELECTem.
5. Jednotlivé databáze nabízí různé možnosti. Kolikrát silnější než ANSI SQL. Například rozpad kusovníku není v Oracle žádný velký problém, má to více řešení. Rozhodovat se to neumí, ale vy píšete ten dotaz a můžete si tam zvolit jaké podmínky chcete. Takže můžete napsat dotaz, který se na fantomech zastavuje, a jiný, který vám rozpadne i fantomy. Můžete si tam přidat podmínky na datum platnosti, nebo také ne. Neříkám, že je to triviální úloha, ale v roce 2016 to je s Oracle nebo PostgreSQL úloha efektivně řešitelná přímo v SQL.
6. Databáze sama o sobě to kontrolovat nebude. Klidně se zacyklí. Data vrací průběžně, takže takhle můžete načíst biliony záznamů a TB dat, případně číst do nekonečna. Aby k zacyklení nedošlo si musíte zajistit sám. Možností je řada, například to konktrolovat při ukládání a záznam nedovolit uložit. To je ale těžší, než se zdá. Nebo můžete SELECT omezit na hloubku zanoření. Tedy že vám nerozpadne kusovník hlouběji než třebas do sedmé úrovně. Nebo to zajistit povahou dat - mít položky typu vyráběná, fantom a komponenta. A do kusovníku dovolit vložit jen záznamy, kde je kombinace M < F, M < K nebo F < K. Nebo omezit čtení výsledků na počet řádků (například po 1000 komponentách se zastavit s tím, že asi bude něco špatně). Kombinovat to lze s integrity reportem, který bude cíleně hledat zacyklené kusovníky a reportovat je. Možností je plno, ale databáze samotná vám nic snadného nenabídne.
Pokud máte aplikační logiku už zprogramovanou, pak bych to pojal jen jako migraci. Je prakticky jedno na co, ale volil bych spíše PostgreSQL. Je "futureproof". Ve smyslu, že pokud jednou budete chtít od databáze něco víc, tak PostgreSQL to umí. Důležité je, že většinu věcí, co by za vás mohla řešit databáze, už vyřešených zjevně máte. Takže s transakcemi, referenční integritou apod. bych počkal až do okamžiku, kdy to budete potřebovat.
predne diky za odpovedi i vsem ostatnim.
1. ja jsem nazoru, ze transakce nejsou potreba, ani kdybychom to museli psat znova. Uvazujeme o tom ale z toho duvodu, ze vseobecne je to povazovana za potrebne a vhodne (nakonec i zde v diskuzi). A bohuzel, kdyz nekdo cizi pak hovori se zakaznikem a dozvi se, ze tam transakce nejsou, tak jsem jako dodavatele ocernovani, ze problematice nerozumime. My sice muzeme na zaklade logfilu u stavajiciho systemu ukazat, ze za poslednich 15 let nemeli uzivate vubec sanci videt nedokoncenou transakci, ale kdyz kazdy prof. na univerzite je nazoru ze to musi byt, tak nemame sanci. Rozumnych nazoru jako je Vas je minumum presto diky.
Kdyz uz jsme u toho vaseho prikladu: kdyz cast te transakce neprojde - co delate tedy krome toho rollbacku - nastartujete ji znova? - to by se vlastne melo udelat, ne? - a nebo se odsune ta odpovednost na uzivatele, at se s tim popere?
2. Diky za to upozorneni, ze ERP systemy to nepouzivaji. Na internetu je to ale v ruznych prikladech skoro vzdy. Odhledneme od toho CASCADE, to je takovy kriklavy pripad, ktery barvite ukazuje ta mozna negativa. Mne by konkretne zajimalo napr, kdyz mate u kusovniku podminku, ze polozky musi v tabulce polozek uz existovat, jak se to dela prakticky - smite zalozit kusovnik az tehdy, kdyz jsou vsechny polozky v systemu? Nebo se pouziji nejake dummy-identifikace a pak se prepisuje?
3. U tech databazi me tesi, ze panuje shoda, ze ty 3 databaze jsou mozne. Co by mne zajimalo je, co se skryva za tou formulaci - 'nejake veci se musi psat vicekrat'. Zkontroloval jsem datove typy - tam nejsou rozdily. CURD je take identicke. Mozna se LIMIT nekde drive lisil, ale vice mne nenapada.
4. Na to prepare odpovedel pan Stehule dole a to je pro nas potesitelne. Je mi jasne, ze selecty, ktere dokazi na jedno parsrovani dodat rychle mnozstvi dat z ruznych tabulek maji vyhodu, ale to by melo ten dopad, ze bychom nemohli pouzit stavajici naprogramovanou logiku. To je vubec ten zasadni problem pri pouziti tech rel. databazi - jestlize mam jemnou granulitu modulu, ktere vyzaduji jen male mnozstvi dat jsou mi selecty , ktere vrati obrovske mnozstvi dat najednou k nicemu. To je ta rozdilna filozofie a my bychom se s nejakou migraci vubec nezabyvali, kdyby ty stare databaze byly jeste k mani.
5. Diky za ty poznamky k CTE. Tohle je vec, ktera se da podle vseho od cele problematiky trochu separovat a kdyz to bude mit smysl bude to mozne pouzit. Chapu, ze v techhle vecech se bude muset asi pro kazdou databazi udelat vlastni reseni.
6. V soucasnem systemu je to udelano podobne jak popisujete - tedy cely ten 'produkcni strom' se nachazi v binarnich stromech v pameti a vsechny zmeny v databazi se online promitnou do te pameti (tedy vsechna relevantni data). Proto je mozno po stisknuti klavesnice behem nekolika milisekund zjistit, jestli nedojde k zacykleni. A otazkou bylo, zda moderni SQL systemy neco takoveho nabizeji nebo jestli neco takoveho neexistuje jako nejaky standarni doplnek. Stavajici system se da sice pouzit, ale ten kdo to programoval uz neni k dispozici a hrabat se v tom uz nikdo nechce :-(
Jeste jednou diky
Ad 1, transakce: V okamziku, kdy musim psat do dvou tabulek zaroven, tak uz si to bez transakce nelajsnu. I kdyz je pravda, ze povaha vasi aplikace muze byt takova, ze to ustojite i bez transakce. A co delam po rollbacku? Zalezi dle povahy aplikace. Pokud to je neco s GUI, tak uzivateli reknu, ze se to nepovedlo a on to zkusi znova. Pokud to je nejaka sluzba na serveru, tak to sam zkusi za chvili znovu.
Ad 2, referencni integrita: Kdyz jsem pred 15 lety brigadnicil, tak jsem taky nechapal, k cemu to tam je, vzdyt si to prece ohlida aplikace. Pak jsem parkrat daval do kupy data, protoze ma aplikace tenkrat nebyla uplne bezchybna. A kusovnik pratkicky? Asi nerozumim otazce, ale pokud chce nekdo rict, ze se nekde vyskytuje sroubek a maticka, tak prece ten sroubek a maticka uz musi v DB existovat. Pokud ale chce nekdo nadefinovat novy smontovany produkt, ve kterem je novy typ sroubku a novy typ maticky a tohle chce ulozit do DB, tak zahajim transakci, vlozim do DB novy sroubek, novou maticku, novy smontovany produkt, priradim k nemu sroubek a maticku, ukoncim transakci.
Ad 3, rozdily mezi SQL: Jak pisete, LIMIT/TOP. Pak me takhle z hlavy napadaji ruzne NOW, CURRENT_TIMESTAMP, nekdo umi VARCHAR(MAX) a jiny pouze VARCHAR(4000)...
Ad 5+6, kusovnik a zacykleni: Tak na neco podobneho bych napr. pouzil nejakou stored proceduru na SQL serveru. Aplikace by ji poslala produkt, ktery me zajima, procedura by chvili chrochtala a vratila by tabulku dilu, ze kterych se dany produkt sklada. Protoze neovladam techniky popsane v tomto clanku, tak bych tu proceduru proste nejak upatlal v jazyce daneho SQL serveru. Nejak bych si tam holt osetril to zacykleni. Melo by to vyhodu, ze by to bezelo na serveru, takze hodne rychle, a ze serveru ke klientovi by sel pouze vysledek. Ale jak sam pisete, evidentne uz to mate nejak poreseno v klientovi/aplikaci.
Jak pise Karel, nejspise v prvnim kole skoncite tak, ze SQL server pouzijete pouze jako novejsi uloziste dat, ale veskera inteligence zustane v aplikaci. Takhle probihala moje prvni brigada s SQL, kdyz jsem musel predelat nejakou aplikaci ve FoxPro, aby brala data z SQL. Taky jsem to tenkrat zvladl bez transakci, referencni integrity, stored procedur... protoze jsem to proste neznal.
Ad 1 – myslím, že nevíte, co to transakce jsou a k čemu slouží. Transakce nejsou nějaký bonus, který by program nějak vylepšoval. Transakce jsou způsob, jak zajistit splnění nějakých předpokladů (a existují různé druhy transakcí, které zajišťují různé předpoklady). Můžete napsat, že splnění těch předpokladů nepotřebujete, můžete napsat, že jejich splnění zajistíte jinak, než transakcemi – ale „transakce nejsou potřeba“ je nesmyslné tvrzení.
Nechápu, jak můžete psát, že transakce nejsou potřeba a nepoužíváte je, a zároveň psát, že uživatel neviděl nedokončenou transakci. Tak používáte transakce nebo nepoužíváte? Když je nepoužíváte, uživatel nemohl vidět nedokončenou ani žádnou jinou transakci.
Řešení, když transakce neprojde, záleží na kontextu. Někdy dává smysl zopakovat ji znovu automaticky, někdy dává smysl nechat to na uživateli, někdy nedává vůbec smysl ji opakovat a je potřeba uživateli jenom vypsat zprávu, proč není možné danou akci provést.
Ad 2 – proč byste zakládal nějaké dummy položky a pak je přepisoval? Jak byste to dělal úplně bez databáze, bez softwaru, bez počítačů? Budete na nějakou kartu psát nějaké dummy položky a pak je přepisovat, nebo tam rovnou napíšete ty správné položky?
Ad 3 – mají ty databáze stejnou podporu uložených procedur, funkcionálních indexů, CTE, windowing funkcí? Na CRUD a LIMIT nepotřebujete relační databázi, to zvládne i CSV soubor…
Ad 4 – vůbec netuším, o čem to píšete. SELECT vám vrátí přesně ty záznamy a údaje, o které si řeknete. Když použijete hloupou databázi a logiku budete mít v aplikaci, budete muset z databáze tahat velké množství dat a zpracovávat je až v aplikaci. Když použijete rozumnou databázi a použijete ji správně, vrátí vám přesně jenom ta data, která uživatel potřebuje, a udělá to podstatně rychleji, než kdyby to řešila vaše aplikace.
Ad 6 – ano, moderní SQL systémy takové věci nabízejí, dokonce i ty nemoderní. Akorát si nesmíte myslet, že SQL jsou jenom základní CRUD operace a za vrchol umění SQL považovat LIMIT.
ad 1) ano, podobnych veci sem videl nekolik a se 100% uspesnosti jsem vzdy (zcela uzivatelsky) zaridil nekonzitenci dat v databazi. Neni nic krasnejsiho, nez kdyz treba ze zmineneho skladu mizi zbozi kamsi do vzduchoprazdna, a to jen proto, ze se sice odepise, ale uz nepripise tam, kam ma. A zadny rollback neni, protoze tvurce prece transakce nepotrebuje.
ad 2) ano, mnoho z nich to nepouziva, protoze vznikaly v dobe, kdy databaze == dbf. A take to podle toho vypada, klidne vam dovoli smazat hlavicky a v databazi zustanou plonkove polozky.
ad 3) ... mozne je lecos, ale stejne se tvurce nevyhne tomu, ze co na jedne funguje, se na druhe chova "divne". Moh bych sem napastovat desikty prikladu kdy se pro ruzny databaze musi query prepsat. Sice bude delat presne totez, ale pouzije jinou syntax. Casto z naprosto neznamych duvodu - jednoduse na pohled neexistuje duvod proc by to nemelo fungovat, ale nefunguje. Pokud se zacne resit vykon, je to sranda jeste vetsi. Databaze A je vyrazne rychlejsi s joinem, databaze B se subselectem.
Jenom bych upřesnil, že momentálně se diskutuje o atomičnosti transakcí, ale transakce relačních databází mají čtyři vlastnosti, označované jako ACID – atomicitu, konzistenci, izolovanost a trvanlivost (durability).
Pokud Backup píše, že nepotřebuje transakce, není jasné, zda nepotřebuje žádnou těch čtyř vlastností, nebo nepotřebuje některé (jak je zajistí bez transakcí?, nebo je zajišťuje jiným způsobem (jakým?).
Navíc je důležité zdůraznit, že transakce může klidně implementovat samotná aplikace, a to s takovýma vlastnostma jaké potřebuje. Což je, pokud jsem dobře pochopil, příklad toho konvertovaného systému. A celkem i věřím že to funguje, protože kdysi se tak aplikace bežně psaly.
V případě nových aplikací je to ale otázka důvěry. Když někdo začne tvrdit že transakce nepotřebuje a napíše aplikaci zcela bez nich, tak mám šanci asi 10000:1 že je to prostě tlučhuba. Pokud vytahne ty důkazy že ta aplikace existuje a funguje bezchybně, tak dobře - patří mezi ty jedničky.
Což je, pokud jsem dobře pochopil, příklad toho konvertovaného systému.
Jsem si skoro jistý, že v takovém případě by Backup nepsal „transakce nepotřebujeme“ a jeho komentáře by nevypadaly, že moc neví, k čemu vlastně transakce slouží. Napsal by „transakce nepotřebujeme, protože máme požadavky XYZ a ty zajišťujeme pomocí ABC“.
Z použití fráze "sled operací" je snad zřejmé, že se ptám na transakce ve smyslu dávky několika SQL příkazů - insert/update/delete (a možná nějaký ten prasoselect) - uzavřené mezí BEGIN a COMMIT, případně ten ROLLBACK.
O vlastnostech db transakce jako takové jsem se nebavil.
Pokud jsem špatně pochopil původní tvrzení a jsem OT, omlouvám se...