To su same vyborne rady. Nepouzivajte JOINY v relacnej databaze a nepouzivajte funkcie nad stlpcami. Skvele, zmenim koli tomu specifikaciu systemu a klientovi poviem ze by ten vypocet uzavierky bol pomaly tak ju radsej nebudeme robit.
A samozrejme vsetko si drzte v 4NF cokolvek ine je uz denormalizovane. Uzivatelom dajte len jednoduche nahlady (nejoinovat) oni si to nejako pospajaju v hlave alebo ved na co im je ten excel.
Nie je postup skor opacny ze mam problem a MUSIM ho nejako vyriesit nie sa mu vyhnut? A preto je niekedy dobrym riesenim 'predpocitany' (denormalizovany) stlpec. JOIN cez unikatny dostatocne maly kluc (integer ako unikatny surrogate key) je absolutne rychla zalezitost. A to sme sa nedostali este ani k duplikovaniu udajov z dovodu rozdelenia domenovej logiky. Alebo triky akymi sa vyhnut v multithreadingu dead lockom alebo ako minimalizovat write locky a ako prisposobit databazu takemuto druhu spracovania.
Cely vyvoj databazy je riadeny logikou, nemozem uvazovat iba nad strukturami (domenou) ale aj na funkciami a sposobom akym sa tieto udaje spracovavaju (busines logika). Frekvenciou ich citania, modifikacie a pridavania. Tieto faktory ovplyvnuju akou optimalizacnou strategiou sa rozhodnem ist no a v kazdom pripade nezabudajme na predcasnu optimalizaciu, to je uplne to najhorsie co mozete urobit. Takze priklad so zamestnancami je uplne jedno ako urobite lebo ak ich bude okolo 5.000 a tu najvacsie organizacie v nasich koncinach tak to bude v relacnej DB rychle aj ked to urobite so vsetkymi antipaternami spomenutymi v tomto clanku.
Clanok mozno pre zaciatocnika s SQL dobry ale trochu odtrhnuty od praxe. Ak som to prehnal prepacte snazil som sa byt konstruktivny.
Předpokládám, že ten příklad se zaměstnanci byl uvedený opravdu jen jako jednoduchý, snadno pochopitelný příklad. Nečekal bych, že to někdo vezme tak doslova.
Taky už jsem dělal databázi, u které jsem si říkal, že tam bude jen pár tisícovek záznamů, protože přece i ty největší organizace v našich končinách nemají více než 5000 zaměsnanců, ale pak se z toho vyvinula evidence obyvatel na evropské úrovni (neberte mě zase TAK doslovně - nebyla to evidence lidí).
K funkcím "nad stĺpcami":
select * from data where time > '2016-11-17' and time < '2016-11-18';
50 msecs
select * from data where date(time) = '2016-11-17';
Běží dosud, prohledává sekvenčně miliardu záznamů. Musím to za chvíli zabít, za chvíli mi začnou volat, že něco není v pořádku.
Mozno som bol po ranu precitlively :-). Treba ale zdoraznit ze optimalizovat sa oplati skutocne iba nad skutocne VEEEELKYMI udajmi. Radovo GB dat dnesne stroje zjedia ako nic. Pamatam ze udaje v SAPe jedneho podniku mali 3GB po 2 rokoch pouzivania, v dnesnej dobe by to utiahlo PC za par tisic. Ja dam tiez nieco:
accledgertrans - 150990 zaznamov
Testovaci stroj nejaky normalny server s 30timi virtualmi:
> select count(*) from accledgertrans where createddate between '2016-07-01' and '2016-07-30'
Elapsed time (seconds) - Total: 0.045, SQL query: 0.044
> select count(*) from accledgertrans where date(createddate) between '2016-07-01' and '2016-07-30'
Elapsed time (seconds) - Total: 0.137, SQL query: 0.137
No a prave minuly tyzden sme optimalizovali po 3 rokoch intenzivneho pouzivania databazu. Klient si zacat stazovat ze uz sa to prilis spomalilo. Az po 3 rokoch konecne maju dost udajov a mozeme sa pozriet na dotazy ktore naozaj pouzivaju aby sme ich mohli analyzovat. Nemalo zmysel robit to pred 3mi rokmi. Toto zvladlo zopar indexov, ale robili sme uz aj komplet prerobenie logiky koli optimalizacii. Ano aj to sa robi ale az potom ako mam skutocne udaje a skutocne dotazy. Klientovi sa aj tak neda verit, v case analyzy ani sam netusi kolko tych udajov bude.
Souhlasím s tím, že je celkem zbytečné nějak výrazně optimalizovat databázi dříve, než se v ní objeví dostatečné množství dat. Databáze se někdy chovají na první pohled dost chaoticky a čas strávený dotazem může na objemu dat záviset velmi nelineárně.
Předpokládám ale, že tento článek měl být varováním před něčím jiným, než před předčasnou optimalizací. Velkou část těch situací v článku uvedených jsem si prožil a dnes už tak nějak podvědomě tuším, kudy cesta nevede. Mé dnešní databázové návrhy jsou často poznamenané snahou vyhnout se situacím v článku.
Dneska už na podobně věci myslím už při návrhu aplikace. Spoustu věcí dnes dělám v databázi Sqlite pro PC, Raspberry a podobné stroje - tam to může být kritické i při pár stovkách tisíc záznamů.
Množství a šíře problémů, které se řeší pomocí databází, je mnohem větší, než si my dva dovedeme představit. Myslím si proto, že je dobře, když se s námi někdo podělí o svoje zkušenosti, byť se nám mohou jevit jako banality.
Úprava schématu je drahá - pokud se jednou schéma navrhne špatně, tak je to nadlouho. A přitom si stačí pamatovat a respektovat pár jednoduchých doporučení.
Bohužel velká většina, téměř všechny problémy s databázemi jsou způsobené nějakou banalitou. Živím se jako databázový konzultant, a člověk si už kolikrát připadá jak v jednom nonstop dejavu. Opravdu originálních problémů je promile - ale pak to stojí za to (low level problémy v zámcích kernelu nebo Postgresu). Téměř všechno, s čím se obyčejně a často setkávám jsou banality - bohužel některé z nich nelze za rozumné náklady opravit.
Někdy je to o to smutnější, že nepochopené banální problémy dokopali uživatele, i vývojáře do bizarních řešení a ještě do větších problémů. Proto jsem to tady napsal - je to absolutní minimum - co by si každý z IT mohl zapamatovat.
"dnesne stroje" to je nekdy raspberry pi, a nebo, dokonce (coz osobne pouzivam) mysql na nas s 128M pameti. a tam je hranice velkych dat je trochu jinde. a i na tech vykonnejsich strojich mensi efektivita databazi se projevi na uctu za elektinu nebo, v pripade cloudoveho hostingu, na uctu za virtualni procesorove jednotky.
Trochu mám pocit, že v článku občas čtete slova, která jsem nenapsal, a naopak to, co jsem napsal, nevidíte.
V prvé řadě musím vědět, co píši za aplikaci a pro koho. Kolik budu mít dat - za rok, za tři, za pět let. Malé databáze Vám leccos odpustí. U velkých můžete mít problém.
Pokud píšete aplikaci, která je postavená nad databází - a data a operace nad databází jsou důležité, pák úvahy o návrhu schématu rozhodně nejsou z kategorie premature optimization. V době, kdy přijdete na problémy s výkonem - někdy za týden, jindy za rok, už nemůžete udělat žádné větší změny ve schématu aniž byste radikálně přepisoval aplikaci.
Obecně bych souhlasil, ale je to podle mě trochu složitější. Předesílám, že jsme tedy spíš ze světa Oraclu, ale myšlenkové pochody jsou snad platformě nezávislé, aspoň v tomto případě :)
IMHO na dotazu s mnoha JOINy není nic špatného; např. v normalizované OLTP databázi, kde to vede ideálně na NESTED LOOPy po indexech. Tím spíš, že může být hodně nacachováno a provádí se pak spíš logické IO. A díky statistikám indexů obvykle chyba v odahu není příliš zásadní.
Samozřejmě, že v tom světě skladů má smysl se joinům ideálně vyhýbat, ale někdy to prostě nejde - např. když mi aplikace sype fakta a do reportu musím přidat atributy z dimenzí. Pak ale může mít smysl obětovat normalizaci a join mít ten join předpočítaný a materializovaný; abych ho nemusel počítat pokaždé, když si někdo otevře v BI nástroji první obrazovku. Samozřejmě záleží na zadání - jestli chce BI aktuální přesné hodnoty, nebo třeba v 5min intervalech.
Tím chci jen říct, že opravdu moc záleží na ujasnění si, co vlastně mám dělat. "vyhýbejte se mnoha joinům v dotazu" a "normalizujte, co to jde" - omlouvám se za zkratky, ale snad nejsou úplně mimo - tedy nepovažuji za univerzálně platné rady pro začátečníky, čímž je tedy kategoricky nevyvracím.
Nicméně chápu, že nemusí být rozumné jej hned na začátku vyděsit existencí různých světů s různými pravidly.
Nejsem proti JOINům - jsem proti zbytečným JOINům - když máte reálně 10 entit, tak budete mít 9 JOINů. Když entity rozkouskujete podle tříd, tak už máte třeba 20, 30 tabulek a 20-30 JOINů.
Získat data z jednoho objektu - to nikdy nebude problém - je téměř jedno jestli udělám 10 nebo 100 nested loopu, které budou vracet jeden řádek - tam budou rozdíly max. v jednotkách ms. I když u 50 JOINů a více se už bude pálit čas i na plánování dotazu. Jakmile ale budete počítat report, a i v OLTP databázi chcete počítat reporty, tak nested loop bude to poslední, co budete chtít vidět v prováděcím plánu - a se špatnými odhady už je to o přetlačování databáze a typicky oser.
Jestli něco začátečníci musí pochopit, pak je to fakt, že každý sw má nějaké limity a hranice, za které je už nepraktické jej dál používat, ohýbat. Běžně se setkávám s neskutečnými problémy plynoucí z toho, že Excel někdo používá jako databázi - nebo že MS Access se používá nikoliv pro 30 lidí, jak byla zamýšlená, ale pro 300 lidí. To, že vývojáři vůbec nerespektovali realitu, dneska vede k tomu, že pár firem má těžké provozní problémy a nefunkční systémy. Jsou tu různé světy, mají různá pravidla, různé limity a ty limity je nutné znát.
Jasně, to jsme pak na stejné lodi ;) Jinak tedy nevím jak v PG, ale v ORA není nutné vždy pálit CPU parsováním/optimalizováním - plány se cachují a přepoužívají, je-li to možné - pokud tedy někdo neni prase a nedělá "WHERE id = '1'". To jsem bohužel v produkci už viděl a pak samozřejmě cursor_cache obsahuje tisíc podobných ošklivých dotazů, kde rozdíl v SQL jsou právě jen hodnoty ID; prostě to nahoře v JAVE slepili jako řetězec a nazdar, bojuj databáze!
Jasně, ani používání proměnných není samospásné a může vést k jiným problémům; např. v těch DWH je určitě lepší obětovat čas CPU za lepší plán, než šetřit parsování a seknout se (řádově) v kardinalitě, třeba kvůli roztodivné distribuci hodnot. Ale to jsme už trochu jinde... pochopil jsem co chcete říct a souhlasím.
Postgres plány sám od sebe nekešuje - musí se použít explicitně prepared statements - Postgresový planner je o něco rychlejší, a od určité složitosti používá genetickou optimalizaci - takže náročnost optimalizace není exponenciální - navíc mnohem větší hrůzu než z opakovaného plánovaní mají vývojáři pg strach z neadekvátní kardinality.
Autor chtel zcela jiste misto eliminace JOINu spise uvest, ze problem je predcasna materializace databazovych vet v ramci provadeciho planu. To je to podstatne, proc nejake DB systemy dokazou zvladnout spousty JOINu, aniz by to melo fatalni dopady na vykon. A to je taky duvod proc kdyz uz to relacni technologie nestiha, musi se nejcasteji na sloupcove baze a kdyz ani ta to neda, tak se musi jit do log-merge struktur.
Tenhle článek jsem potřeboval před dvaceti lety. Takhle se můžu jenom pousmát a vzpomenout si, jak jsem byl kdysi nezkušený a blbý = cítil jsem se jako génius (entity-atribute-value - EAV a výsledné dotazy vypadají impozantně a mnohem geniálněji, než poloprázdná tabulka). Otázka je, jestli bych před těmi dvaceti lety článku rozuměl a dokázal se podle toho zařídit. Vždyť EAV vypadá tak sofistikovaně, hodné mého génia - ego je strašná věc.
V létě jsem měl malinký konflikt s jedním mladým zaměstnancem. Zabudoval do jedné drobné, již fungující aplikace vlastní jednoduchou obdobu ORM. S kolegou jsme mu to opatrně rozmluvili a celé jeho ORM zrušili. Ale dodnes mám podezření, že nám stejně neuvěřil. ON by to ukočíroval - ego je strašna věc.
Myslím, že na konstrukce uvedené v článku budete narážet až do konce života.
Tak ORM bylo, nebo asi ještě i je, velmi v módě. Někde má smysl, resp. dobře se s tím pracuje a výkon nijak netrpí, obzvláště v kombinaci s cache jak na straně aplikace, tak na straně databáze, lazy loadingem atd . . . V tom je právě asi to, o čem jsi psal, že nějaká větší optimalizace má smysl až od určité úrovně, resp. složitosti nebo množství (krom obecně platných principů a smysluplných věcí).
A to z Vás ani nikdo nevzpomenul, ale záleží také na tipu databáze a na jazyku, použitém pro systém, ale taky na účelu, protože jinak budeš psát třeba aplikaci, kde záleží na nejakém frontu na každé milisekundě * počet návštěvníků a jinak když je to jedno, hlavně aby programátor co nejrychleji namlátil vypisy složitě souvisejících dat do 15 -30 stránek za týden, nebo to často měnil po malých objememech . . .
S ORM jsem se nikdy nezkamarádil. V mém případě (kolega je na tom stejně) to obvykle vedlo právě k různým děsům v databázové vrstvě, takže část aplikace dělala "někde něco" uvnitř bez rozumné možnosti to ovlivnit a část aplikace byla pracně přepsaná z ORM na optimalizované dotazy. Než mít v jedné aplikaci dva různé přístupy k jedné věci, přijde mi vhodnější to sjednotit.
To byl i důvod, proč se mi nelíbilo ORM vymyšlené kolegou v naší aplikaci. Jednodušší část, se kterou si kolega poradil, byla z jednoduchých selektů přepsaná do jednoduchých mapových struktur (které si musel každý nový příchozí nastudovat a pochopit) a složitá část zůstala ve složitých SQL dotazech.
Jasně. A to je právě to. Klidně můžeš mít na 90% aplikace výpisy relačních dat, na které se to hezky hodí a můžeš sekat třeba templates "jak Baťa cvičky" a pak, u 5~ % udělat složité dotazy, většina ORM to dovoluje a ještě ke všemu ti to vrátí v oněch entitách pokud chceš a pak to zase vysypeš do templaty . . . .
Ale je pravda, že jediné kde si to dokážu opravdu představit tak, aby mi to nikdo nevymluvil je, když vezmeš třeba nějaké Core aplikace - třeba společný admin ke kterému se pak už jenom přidávají custom weby pro klienty a u těch klientů právě sekáš ty templaty a tohle ti hodně pomůže. to jo . . ale jinak to taky rád nemám - už jsem s tím dělal v PHP, Javě, C# a něco podobného a velmi odlehčeného jsem si spíchl pro wordpress, ale já si stejně myslím, že optimalizace má smysl vždycky, protože jednou, až to bude potřeba, už může být úplně pozdě a nebo to být nereálné - např. (cena/výkon) + plánovaný rovoj . . .
Každopádně ORM nebo ne není největší problém tvorby aplikací ani náhodou . . . Už třeba jenom jmenými konvencemi, resp. jejich nedodržováním, se dá udělat harakiri v podstatě z čehokoliv - co jsem se teď naposledy setkal - Máš třeba modul "Description", někdo jeho "main" třídu pojmenuje "Labels", vytvoří z ní instanci "LevýBanner", který si dál předává funkcemi jako LB a do šablony si to pošle jako Blok1 v array "partials" a tohle ti udělá s 10 - 20 komponentama na stánce, tak se můžeš jít klouzat. A pokud tohle udělá s ORM Entitama a sloupcema ["mapping"], tak bych zrovna zařal shánět jiné místo . . . ;-)
podla mna je najdolezitejsie vybrat si databazu a navrh podla problemu - je rozdiel ci ukladas stovky objektov (ciselniky) po 50 records, spatial data, alebo minutove data z burzy za 30 rokov.
kazdy z problemov ma ine poziadavky na zapis a citanie dat .
napriklad zbalenie suvisiacich 1000 datapointov do jedneho BLOBu a ku tomu key bolo asi 140x rychlejsie pre dany problem ako pisat nejake uchylne query cez 7 tabuliek
Pridam jeste jedn oblibeny anti-pattern
select * from table x where x = :filter or :filter is null
Je hezke, ze muzete pouzit jeden SQL dotaz, pro dve ruzne veci. Dokud, ale databaze nevi jakou hodnotu ma bind parametr, tak ani nemuzete vedet, jaky to bude mit exec plan. V realu to konci FTS.
Docela by me zajimalo, jake je doporucovane reseni pro tabulku s heterogennimi daty. Dam priklad - chci ukladat sekvencni vyskyt ruznorodych udalosti, samozrejme jsou tam nejaka data (sloupce) jednotna, typicky treba cas vyskytu nebo typ udalosti, ale zaroven se jednotlive typy udalosti lisi v popisnych atributech. Pokud je tech typu omezene mnozstvi, prijde mi dedicnost jako vhodna aplikace, tady nejde o ORM, ale ta data k tomu podle me prirozene vedou...
Obecně doporučované řešení jsou normální formy - v relačních databázích. V moderních databázích si můžete pomoci neatomickými typy - JSON, XML - anebo můžete použít NoSQL databáze. Za univerzálnost se ale platí. V relační databázi NULL mne stojí jeden BIT. V případě stovek sloupců už může být docela drahé zjistit jestli je hodnota NULL nebo ne. U XML, JSONu mne zase stojí rozbalení dokumentu, parsování, iterace. Záleží na okolnostech.
Můžete si pomoci funkcionálním indexem, případně nějakým speciálním indexem - v Postgresu např. GIN index pro jsonb typ - něco jako funkcionální index MySQL učitě má. Pokud ale uděláte full scan, tak Vám nic nepomůže - jedině se chytat jiných relačních (atomických) atributů a do neatomických typů jít až nakonec.
Díval jsem se na to, ale vypadá to, že to bude fungovat od verze 5.7.x, takže to zatím nepůjde, ale až bude chvilka, vyzkouším to na dev. serveru.
Prozatím jsem to vyřešil tak, že připojím k tabulce se společnými vlastnostmi tabulku specifickou pro daný typ. Ovšem tím musím nejspíše řešit celou logiku v aplikaci. Zatím to není problém.
Vypadá to, že jsem si v databázi udělal malého krakena a to v tom smyslu, že záznamy nespojuji pomocí primárního indexu, ale pomocí hashe, který je uložen v Varchar typu a nad ním je index.
Je to proto, že když generuji záznamy napříč tabulkami, tak nejprve vytvořím hash a pak jím sváži další záznamy, protože v tu chvíli neznám id záznamu. Hash ovšem může obsahovat všechny znaky ASCII.
pokud máte append only data, pak můžete použít sloupcové databáze. Tam tabulky se stovkami sloupců nejsou problém. Nicméně zase, dědičnost je špatně - obvykle - třeba u workflow systémů je to jedno - tam se většinou pracuje s izolovanými objekty a OOP přístup tam ničemu nevadí. Pokud ale databázi používáte pro agregaci, řazení, reporting tak je dědičnost koncept, který ve stávajících databázích není dobře podporovaný.
Predpokladam, ze nezpracovavate cele db vety, ale jedete jen po par atributech. Pokud vam jde o pohodli, pouzijte sloupcove baze. Pokud se vam v dotazech objevuji urcite sloupce pomerne pospolu a standardni sloupcove baze to uz neutahnou, musite jit na big-data reseni s log-merge strukturami a shlukovanim sloupcu v souvislych datovych blocich. Tohle umi principialne HBase, ale to je "nestastne" reseni kvuli svemu pomalemu podkladu "Hadoopu", resp. hdfs. Nejlepsi je proto u vykonostne narocnych reseni zaplatit profesionala.
Dekuju vsem za odpovedi, asi jsem mel napsat, ze mi jde o relacni DB se zvlastnim prihlednutim k PostgreSQL (protoze Pavel S. je na PG odbornik a shodou okolnosti je to databaze, se kterou pracujeme u nas nejvice). Podobnych prikladu je vic, resime to vselijak, ale nejak se mi nechce pridavat jeste dalsi technologii - snad by mohlo pomoci i vyuziti JSON storage. Zajima me to ale i obecne, co s tim kdo pripadne dela.
Jedná-li se o různé, nepříbuzné typy záznamů, je první chybou dávat je do jediné tabulky, je možno pro každý typ vytvořit jednu.
Jedná-li se o vzájemně příbuzné typy (podtřídy), není pro ně RDB vhodná, ale dá se to ojebat klasickými postupy ORM - buďto pro každý podtyp udělat extra tabuli, nebo to narvat do obecné tabule.
Další možností je použití neschématové DB, tj. dokumentové či jiné, tam je uložení vaším problémem, ne problémem databáze.
Proč název článku mluví obecně o databázích, ale řeší jen relační?
Proč prvním pravidlem návrhu není výběr typu databáze podle typu zpracovávaných dat?
Uvědomuje si autor, že ukládání objektových dat (zřejmé z příkladu) do relační databáze je jeden z nejsložitějších způsobů vzhledem k užití ORM?
ORM je predevsim o tom, ze tvurce nemusi premejslet, protoze se to udela "samo". Ze to bude (pri prekroceni nejakeho mnoztvi dat/zatezi) pomale, pripadne zcela nepouzitelne, neni prevazne v okamziku kdy to dela podstatne. Je dokonce dost pravdepodobne, ze ten problem ktery on vyrobi, bude nasledne muset resit nekdo uplne jiny. Takze proc by se tim mel zabyvat.
BTW: Vubec nejlepsi vec se kterou sem se setkal je mit jednu centralni tabulku IDcek ... a davat do ni i logy. Ono to sice teoreticky je krasne v tom, ze ID je unikatni v ramci cely databaze ... ale taky v tom, ze jen to logovani s naprostym klidem pri prekroceni nejaky kriticky hranice celej system uplne odstavi.
"ORM je komplikovaná záležitost, a osobně ji beru jako jeden z největších omylů IT", uff. Ale ved ORM je nastroj, dost silny a pre niekoho mozno komplikovany ale OMYL moze byt iba zverit ho nekompetentnemu cloveku. Nastroj ako taky je to vyborny, dnes dokonca v mnohom standardizovany (pre Javu JPA) a robi to co ma, riesi mnohe chyby ktorych by sa programatori dopustali bez neho a vytvara abstrakciu nad rozne DB systemy.
Objektove a NoSQL databazy neriesia mnohe z toho co relacne databazy zvladaju s lahkostou.
Já bych neházel všechna ORM do jednoho pytle. Jsou přeci i různá odlehčené ORM.
Taky nevím, proč by měl vadit mix generovaných a ručně psaných dotazů (pokud to bude přehledně strukturované). Triviální dotazy mi vygeneruje ORM a netriviální nebo výkonově kritické si napíšu sám.
Problém s ORM vidím spíš tam, kde není zajištěna konzistence na úrovni databáze a spoléhá se jen na ORM nebo aplikační úroveň. Pak není možno přistupovat k databázi přímo, protože to snadno rozbiju, není možné z databáze zjistit kardinalitu, validace atd.
Ale tak to přece obvykle dopadne - buďto vyrobím obrovské ORM, které se bude snažit vyčarovat složité, rychlé dotazy do RDB (stejně se mu to nepovede), nebo se na to vyseru, ORM udělám mrňavé a několik náročných dotazů vyřeším ručně, což je daň za použití RDB. Mimochodem proto si dělám ORM sám, protože zatím jsem viděl jen ty obrovské, univerzální molochy.
Buďto je váš systém databázocentrický (což považuju z mnoha důvodů za chybu), pak se budete muset v spolehnout na prostředky oné DB k zajištění konzistence (a SQL v RDB je hodně primitivním prostředkem), nebo máte aplikačněvrstvocentrický systém, kdy zapracování (i částečně) konzistence ještě do DB je 1. zmenšením pravděpodobnosti chyby, 2. přiděláním práce, 3. porušením DRY.
Buďto je váš systém databázocentrický (což považuju z mnoha důvodů za chybu)
Proč za chybu? Já to považuji už v podstatě za něco jako framework kolem kterého můžu aplikaci postavit a nemusím řešit věci, které chytří lidé vymysleli daleko lépe a efektivněji.
k zajištění konzistence (a SQL v RDB je hodně primitivním prostředkem)
No upřímně, polovina diskuse se tady točí kolem toho co dokážou vývojáři zprasit a za takové situace házet na ně ještě odpovědnost za něco tak náročného, jako je konzistence dat, je trochu úlet. Viděl jsem mnoho programů, které chtěli řešit konzistenci sami a totálně selhávaly. Proč? Protože ti autoři se ani neobtěžovali si něco zjistit o prostředcích, které používají. Lidi, kteří se neobtěžují si zjistit ani základy db, tak stejně tak kašlou na věci jako konzistence fs apod. Takže řešit konzistenci v aplikaci je cesta do pekel a místo toho je lepší používat systém, který už tu konzistenci má pár desítek let vyřešenou.
Protože musíte kompletní konzistenci realizovat v DB (relačně nad objektovými daty v relacích), přičemž ORM stejně budete asi řešit v aplikační vrstvě, takže to máte rozstrkané na 2 místech. Stejně se nevyhnete duplicitám (porušení DRY), mimoto prostředky PL/SQL jsou mizivé proti Javě. Dále jste se připravil o možnost jednoduše prohazovat nejen různé typy DB pod aplikační vrstvou, ale často i jen různé RDB, protože každý výrobce si (PL)SQL mastí po svém.
Konzistence dat je součástí každého doménového modelu (ať je umístěn kdekoli), ta se v DB sama od sebe neudělá. A nepředstavujte si, že to spočívá pouze v existujících záznamech k cizím klíčům! Často jsou to rozsahy hodnot, formáty řetězců, počty záznamů či celé výpočty přes mnoho entit (opět složitě nad rozloženými objekty!). SQL na toto nebylo původně navrženo, šlo o jednoduchý dotazovací jazyk, který se dolepoval!
Můžete prosím do odpovědí dávat i citace z komentáře na který reagujete? Místní systém neodsazuje komentáře a často tak není poznat na koho reagujete.
Protože musíte kompletní konzistenci realizovat v DB (relačně nad objektovými daty v relacích), přičemž ORM stejně budete asi řešit v aplikační vrstvě, takže to máte rozstrkané na 2 místech.
Datovou strukturu si definuju v databázovém schématu, včetně datových typů a jejich omezení (je to třeba celé číslo, ale v daném modelu se vyskytují pouze čísla od do, takže si tam vrazím CHECK) a potom s tím appka pracuje. Nemusím to řešit podruhé v app (ale jistě můžu), protože db mi data neodpovídající schematu stejně nepřijme.
Konzistence dat je součástí každého doménového modelu (ať je umístěn kdekoli), ta se v DB sama od sebe neudělá. A nepředstavujte si, že to spočívá pouze v existujících záznamech k cizím klíčům! Často jsou to rozsahy hodnot, formáty řetězců, počty záznamů či celé výpočty přes mnoho entit (opět složitě nad rozloženými objekty!).
No já si to tak nepředstavuju, viz výše. Ano, db mi nezajistí úplně vše, ale to co jsem viděl v praxi, tedy přístup: to pořešíme v aplikaci a db použijeme jen jako úložiště záznamů, tak to vždy vedlo do pekel. Pro mě je dobré schema se všemi omezeními naprostý základ.
„...citace...“
Někteří nadávají, že citace zabordelují diskusi. Lepší by bylo borce, který kdysi funkční odsazování zkurvil, párkrát kopnout do zadku, aby se zbráboral.
CHECK je primitivní kontrola. Jak vytvoříte např. kontrolu dokladu, zda součty několika údajů jeho položek jsou sumárně na dokladu v pořádku? V obj. modelu je to trivialita na řádek, v SQL je to na dotaz, v horším případě na proceduru.
V aplikaci to *musíte* řešit podruhé. Jak byste kontrolovat validitu objektu během zpracování (výpočty, plnění uživatelem, ...)? Extra procedurou nebo funkcí (těmi to většinou nejde) v DB? Nebo to najebal do tabule a když se to vyjebe, tak je to špatně, když ne, použijete ROLLBACK? Nebo jak?
Peklo pro mě byly projekty, kde se vše jebalo do RDB a za ukrutných časových nároků se to ladilo a upravovalo a případně zpětně promítalo do aplikace.
Někteří nadávají, že citace zabordelují diskusi. Lepší by bylo borce, který kdysi funkční odsazování zkurvil, párkrát kopnout do zadku, aby se zbráboral.
Ano, to by bylo jistě lepší, ale s tím my nic neuděláme.
CHECK je primitivní kontrola. Jak vytvoříte např. kontrolu dokladu, zda součty několika údajů jeho položek jsou sumárně na dokladu v pořádku?
Třeba tak, že k datům v DB budu přistupovat pouze přes procedury. Tím mám zajištěnou konzistenci, datový model i spolehlivé ukládání dat. Na jedné vrstvě.
Nebo to najebal do tabule a když se to vyjebe, tak je to špatně, když ne, použijete ROLLBACK? Nebo jak?
S tím, že se transakce nepovede, stejně musí program počítat. Nevidím nic špatného na tom tento prostředek (obecně řízení transakcí) přímo jako součást frameworku, na kterém program stavím.
. Dále jste se připravil o možnost jednoduše prohazovat nejen různé typy DB pod aplikační vrstvou, ale často i jen různé RDB, protože každý výrobce si (PL)SQL mastí po svém
Tohle zni hezky. V realu je to chimera. V praxi se nic takoveho nedeje. Muze se stat, ze vymenite OS. Napr Unix => Linux. Muze se stat, ze zmenite nekolikrat aplikacni framework, homemade ORM => MyBatis => Hibernate => EclipseLink. V realnem svete u funkcni aplikace se rozhodne nechcete zmenit databazi.
Tak mozna po 10ti letech a vetsinou je to soucasti kompletniho prepsani cele aplikace.
ORM vas ani zdaleka neodstini ode vsech specifik Db engine.
Některé velké ERP systémy umí běžet proti více databázím. Takže i když si kupříkladu koupíte od Oracle JDE E1, tak provozovat ho můžete proti konkurenční DB. Je to obchodní strategie, dát zákazníkovi na výběr aby se tolik nebál. Ale cena za to je obrovská, z vlastností DB se použijí tak akorát primární klíče. Nemá to ani Foreign key a vše musí řešit vrstva těsně nad databází, která se stará o transakce a integritu dat. Na druhou stranu to opravdu funguje.
Nikdo to nedělá ne proto, že by to nebylo třeba, ale že systém je vytvořený tak, že to NEJDE. To je podstatný rozdíl. A přesně o tom mluvím. Potřeba vyměnit databázi (z jakéhokoliv důvodu), nebo rozdělit data do více DB dle způsobu zpracování, to není nic zvláštního (pro někoho). Samozřejmě, že když je apl. logika v DB, tak to skončí nákladným přepracováním celého systému. Sám píšete, jak prohazujete OS (nejspodnější SW vrstva) či frameworky pro persistenci (které bývají prorostlejší do modelu více, než by bylo zdrávo; hned nad DB), ale výměna DB je z nějakého důvodu špatně? Proč?
Potřeba vyměnit databázi […] není nic zvláštního (pro někoho).
Mně to teda docela zvláštní připadá. Protože relační databáze je technicky vzato sice samostatná služba, ale často je velmi úzce s aplikací svázána, je to fakticky součást aplikace. A velké databáze jsou různé, nejsou to jen různé implementace téhož standardu. Takže změna databáze neznamená jenom třeba trochu jiný zápis SQL příkazů, ale znamená to i tu a tam změnit logiku aplikace, někde třeba změnit strukturu ukládaných dat atd. Pokud máte aplikaci napsanou univerzálně, musíte použít nejmenší společný jmenovatel dostupných funkcí, a tím se zbytečně ochuzujete o všechno to, co mají jednotlivé databáze navíc. Pokud aplikaci převedete z Oraclu na MySQL, je otázka, proč ji vůbec provozovat na Oraclu.
Na operačním systému tyhle aplikace nebývají zdaleka tolik závislé, jako na databázi, protože od OS toho obvykle požadují minimum – aby uměl spustit proces, uměl ukládat soubory (a i tomu se dnes aplikace vyhýbají), a zprostředkoval síťovou komunikaci.
„...často je velmi úzce s aplikací svázána, je to fakticky součást aplikace...“
To může být právě ta chyba. Jedinou vazbou mezi aplikací (s dom. modelem) a DB má být onen mapovač, který je jiný pro každý typ DB, přechod na jinou DB je pak právě věcí pouze výměny mapovače.
„Takže změna databáze neznamená jenom třeba trochu jiný zápis SQL příkazů, ale znamená to i tu a tam změnit logiku aplikace, někde třeba změnit strukturu ukládaných dat atd.“
Tak to určitě ne, struktura a logika dom. modelu je dána, jeho přepis do DB je práce mapovače. To samozřejmě nevylučuje, že mapovač obvykle má několik speciálních funkcí pro několik specifických operací pro dosažení optimalizace. Aplikaci (dom. model) nezajímá, jaký šunt visí pod ním. Upravil-li jste dom. model dle omezení DB, chcete po něm práci mapovače.
Ad konzistence, vyvojari nejsou schopni zaridit ani daleko primitivnejsi pozadavek - unikatni cislo dokladu. Natoz konzistenci dat. Transakce je pak pro ne velmi casto spis sprosty slovo. Bud vubec netusi, ze neco takovyho existuje, nebo nemaji poneti, k cemu by to jako melo bejt dobry.
Takze pak ta "aplikacni konzistence" dopadne presne jak dopadnout musi. Trebas ze soudruzi aktualizujou stav skladu ... zbozi ze skladu zmizi ... ale na dokladu vydejky se neco nepovede, takze zadna nevznikne. A protoze skladnik je zviratko cinorode, tak to zkusi jeste 10x .... aby mu nakonec system zahlasil, ze zadne dalsi zbozi v tom plnem regale neni.
Ale to je asi nepochopenie ORM. Prvy ucel je ABSTRAKCIA nad DB. Pokial pouzivam Criteria a HQL je mi jedno s akou DB robim. Mozem si to prepnut na Oracle, PostgreSQL, MS-SQL a vsetko funguje. Za dalsie to OPTIMALIZUJE pristup k udajom pomocou Lazy loading, Eager fetch, Flushing, ... . Ak od biznis logiky zavisi ci potrebujem dalsie udaje pri spracovani nemusim robit zbytocne komplikacie a framework sa postara v pripade potreby o dotiahnutie udajov pripadne optimalizuje updaty v DB, neviditelne a tak aby vsetko fungovalo. No a uplne najviac je to BEST PRACTICE takze postupne ked sa zisti ze existuje optimalnejsi postup na fetch alebo mapovanie udajov z objektu alebo do objektu tak nemusim prerobit celu aplikaciu ale iba dam novsiu verziu frameworku. Je to presne ten isty princip ako Garbage Collector. Super programator to nepotrebuje ale vsetci vo vasom teame su Super programatori? Radsej tam budem mat tento framework ktory vsetci pouzivaju a mozem ako architekt kludnejsie spavat a mozem ist iba po tych vynimkach kedy sa nepouziva a zistit ci je to naozaj potrebne.
No a samozrejme existuju aj specialne 'rucne' robene selecty/updaty pre specialne pripady ale vzdy treba dodrzovat pravidlo 80/20 cize na 80% pripadov by mal stacit framework, 20 urobit rucne. Ak mam pravdu povedat za posledne roky je to u nas asi 95% vsetkeho ciste Criteria a HQL.
Právě že je to pochopení ORM, a vámi uváděné příklady jsou přesně to, co je špatně. Abstrakce nad DB, používání univerzálních prostředků – to znamená, že nepoužíváte specifické prostředky databáze, které umožňují přístup optimalizovat. „Optimalizace“ přístupu pomocí lazy loading, eager fetch, flushing – to optimalizuje z hlediska ORM, ale z hlediska relační databáze to často je pravý opak, načítají se zbytečná data, připojují zbytečné tabulky. Ale hlavní problém je v samotném principu ORM – data se neukládají tak, jak by měla být uložena v relační databázi, ale je to jenom hloupá serializace objektů.
Jak už bylo řečeno, s ORM není problém, když je dat málo, to databáze zvládne hrubou silou. Problém je, když je těch dat hodně a potřebujete to optimalizovat tak, aby s nimi databáze mohla pracovat efektivně. Nepomůže vám, když budete psát 20 % dotazů ručně, když je problém ve struktuře databáze.
"používání univerzálních prostředků" - presne naopak pouzivaju sa optimalne prostriedky danej databazy o to sa stara ta prekladova vrstva, ja si o nieco poziadam a vykona sa to optimalne tak ako to ta konkretna DB umoznuje. Napriklad strankovanie, ak DB umoznuje seek (cez limit alebo rownum) tak to ta prekladova vrstva urobi ak nie tak to urobi inac optimalne pre danu DB.
"z hlediska relační databáze to často je pravý opak" zase zle - je to optimalne pretoze to su presne tie blbe optimalizacie, z disku nacitavate cely sektor je uplne jedno kolko stlpcov pokial sa to do stranky vojde (co sa na 99% pripadov vojde) tak je to optimalne, zly priklad.
"jenom hloupá serializace objektů" - to ste asi este nevideli 'hlupu' serializaciu objektu.
"když je problém ve struktuře databáze" - ale ved struktura je uplne rovnaka v com je struktura DB ina ci robim priamo v SQL alebo cez ORM? Nie raz sme mapovali existuju aplikaciu fungujucu cez ulozene procedury do ORM bez zmeny, maximalne boli vynutene zmenou biznisu nie potrebou ORM.
Ne, nepoužívají se optimální prostředky dané databáze. Stránkování je nezajímavá trivialita. Optimální prostředky databáze jsou například analytické funkce, hierarchické dotazy, agregované dotazy atd. Znáte nějaké ORM, které tohle používá?
Ad načítání celého sektoru – opět uvádíte příklad špatné optimalizace. Za prvé jsem nepsal o zbytečném načítání dalších položek z jednoho řádku, ale o zbytečných joinech. A i tím zbytečným načítáním celého řádku můžete dotaz podstatně pokazit, protože je klidně možné, že ve skutečnosti potřebujete jenom dva údaje, které máte v indexu – a databáze pak nemusí datovou tabulku číst vůbec.
Ne, struktura databáze nemusí být stejná. Různé ORM nástroje se chlubí tím, že umožňují z objektové reprezentace vytvořit strukturu databáze. A když je databázová struktura navržena samostatně, dělá to zase problém ORM nástrojům.
To, že vám ORM dobře funguje na menších datech, kde prostě stačí hrubí výkon, neznamená, že to stejně dobře bude fungovat i u velkých dat, kde už potřebujete pracovat s tím, co ta databáze dobře umí – nemůžete jí prostě naložit a doufat, že si s tím nějak poradí.
Cez HQL pouzivame aj analyticke funkcie, agregovane dotazy a az ked je to ABSOLUTNE nevyhnutne pouzije sa ciste SQL. Dokonca si mozete vybrat aj tie dva stlpce uplne bez problemov cez HQL a ulozit do ineho objektu. Ale kolko percent dotazov to je?
Struktury mozu byt ine, skuseny programator to urobi dobre v SQL aj v ORM. Neskuseny to cez ORM tak nedomrvi ako cez ciste SQL kedy to na 100% urobi zle. Garantovane to skuseny programator urobi RADOVO rychlejsie DOBRE rovno v ORM.
Ziadne mensie data, pouzivame ORM nad najvacsou DB v tomto state (Slovensko). Uplne bez problemov. Pouzivame fetch mapy, dlhe vety, ORM nad parametricke view, spustanie procedur, ... dnes vsetko cez standardne JPA.
To ste si iba vy nejako vykonstruovali co je a co nie je ORM. ORM je napriklad JPA ktore obsahuje aj JPQL ktore robi tu transparenciu o ktorej pisem. Ta 'hnusna' medzivrstva medzi vami a DB. Ale ak sa vam JPQL nepozdava co toto, to uz je dostatocne 'hnusne' aby ste to prehlasili za ORM?
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
Root<Department> d = query.from(Department.class);
Join<Department,Teacher> teachers = d.join(Department_.teachers);
query.multiselect(d.get(Department_.name),cb.count(teachers)).groupBy(d.get(Department_.name));
Pre mna 1000 krat lepsie ako nejaky povalujuci sa string v kode pretoze ked niekto refactoruje nazov fieldu tak viem kde sa co pokazilo. To ze potom mame nadstavbu pre programatorov ktorym staci urobit:
List<ConditionalCriteria> conditions = criteriaFor(Person.class)
.select(PersonProperties.name().last())
.select(PersonProperties.salary()).min()
.withProperty(PersonProperties.sex()).eq(Gender.MALE)
.groupBy(PersonProperties.name().last())
.orderBy(PersonProperties.name().last()).ascending()
.build();
A vieme to optimalne bezat nad vsetkymi DB ktore ani neviem vymenovat. Sazmorejme takychto dotazov je minimum ale neznamena ze nepouzivame ORM alebo ze nie su optimalne.
Podle té vaší definice, že ORM je jakékoli mapování z relační databáze do objektů, je ORM i provedení dotazu, ručí vytvoření objektu pro každý řádek a načtení hodnoty z položky řádku a její zápis do nějakého atributu objektu. Nebo-li by se ORM používalo v každé aplikaci napsané v objektovém jazyce a využívající relační databázi. A tak jsem to nemyslel já a zcela jistě to tak nemyslel ani Pavel Stěhule. Problém není v tom mapování dat do objektu, problém je v těch automaticky vytvářených neefektivních dotazech, problém je v přizpůsobování struktury databáze ORM místo přizpůsobování efektivní práci s daty, problém je, že programátor nějak „magicky“ dostane data a ani neví, jaké dotazy se kvůli tomu musely provést, jestli pro ně vůbec má indexy apod.
Povalující se stringy nejsou jedinou alternativou k ORM. Klidně můžete mít továrny na vytváření SQL dotazů, můžete je mít nějak označené, takže pak v testu dokážete vygenerovat všechny SQL dotazy, které v aplikaci připadají v úvahu, můžete zkontrolovat, zda je databáze dokáže zpracovat (tedy zda jsou syntakticky správně a neodkazují se na neexistující tabulky, sloupce nebo funkce), můžete rovnou zkontrolovat, jaké mají prováděcí plány, zda třeba nechybí nějaký index.
Problém ORM není v tom, že by se nehodilo na jednoduché věci. Problém je v tom, že tím, že před programátorem skrývá databázi, dozví se programátor, že je něco špatně, až když je daleko za tou hranicí, kdy je ORM ještě vhodné použít.
"nemá ani šanci se databáze naučit" -> a to musi ked prave riesi zauctovanie polozky ako side efekt biznis procesu pri reakcii na event stielany z messagingu po transformacii cez XML? Kazdy ma predsa svoje starosti. To neznamena ze ORM je zlo. Pomaha riesit programatorovi problem ktory ma. Prave ten specialista ktory sa v ORM a SQL vyzna mu pripravi rozhranie kde on uz dostava objekt a nastavi na nom nejaky field. On je specialista na biznis ma z toho dost velku hlavu a fakt nemusi ovladat najnovsie funkcie novej verzie Oracle DB.
"a to musi ked prave riesi zauctovanie polozky"
No to by kurva mel, protoze pak to dopadne tak, ze az se tu polozku bude snazit zauctovat stovka ucetnich, tak se to cely podela, prave proto, ze programator vubec netusi, co to v ty databazi dela.
A pokud to nezvlada, at de delat ten biznis k lopate.
> pak to dopadne tak, ze az se tu polozku bude snazit zauctovat stovka ucetnich, tak se to cely podela
A vy zas nechapete ze ja ako architekt im tam nanutim tranzakcie a versioning a "pak se to nepodela", lebo kazdu vyniku z tychto pravidiel prezriem a chcem mat poriadne zdovodnenu.
Ano "jakékoli mapování z relační databáze do objektů" -> definicia ORM - Object Relational Mapping, to nie je moja definicia.
"automaticky vytvářených neefektivních dotazech" -> vacsina je automaticky efektivna, neefektivne sa daju optimalizovat (ked je treba).
"přizpůsobování struktury databáze ORM" -> Kedy a co sa prisposobuje ORM, aspon nejaky hmatatelnejsi priklad, ja vam poviem ovela lepsie automaticke prisposobenie sa efektivnej praci nez ORM, surrogate keys, autoincrement, version (kontrola integrity), ... co ziskate okamzite pouzitim ORM frameworku namiesto cisteho SQL.
Programator sa nijako 'magicky' nedostava k datam. Pyta sa externeho systemu na objekty ktore splnaju nejake podmienky. To nie je ziadna magia a nedostava riadky ale objekty, to je cely rozdiel. V 80% pripadov a viac automaticky efektivne s moznostou optimalizacie nejakym dalsim specialistom v pipeline. Podobne ako v SQL. Ziadny rozdiel. Ak programator nerozumie co robi tak isto vam zabije tu databazu aj v SQL.
"jaké mají prováděcí plány, zda třeba nechybí nějaký index" - Na to su specialisti co v teame taketo veci riesia, treba ich aj v SQL tak ako aj v ORM, absolutne ziadny rozdiel. To co vy pisete stale dookola ze nejaky zaciatocnik nieco v ORM pokazi, ale to pokazi aj v SQL ked nevie co robi. Potom tam mate specialistu ktory to prejde a mozno upravi indexy alebo dotaz. Opat nic specialne co by bol ORM problem.
"Pokud by měl přístup k databázi, tak nepochybně indexy správně navrhne" -> toto odporuje tomu co sam hovorite kedze vase konzultacie odhaluju tieto problemy aj v pripade cisteho SQL. Preco tito SQL specialisti nenavrhli dotaz a index spravne? Sam pisete ze sa s tym stale stretavate. ORM vam skor pomoze to urobit spravne nez nespravne.
Buďto je to začátečnická neznalost - nebo ORMka (Java, Python) nebo db komponenty (MS Access, Visual Basic, ..). V podstatě jakýkoliv nástroj, který umožní používat databáze bez znalostí, znamená, že znalosti vývojáře ohledně databáze stagnují - a pokud jeho aplikace roste, a on ne (znalostmi), tak je problém na světě.
Což už je pomůcka, která Vám umožňuje se střelit do nohy - toto není jednoznačná výhoda. Pro: uděláte méně chyb, kód je čitelný. Proti - vůbec nevíte o tom, že generujete dotaz, který může být náročný, nebo že generujete jednotky až desítky dotazů. Pro zkušeného programátora je to pomůcka, pro nezkušeného to může být past.
vacsina je automaticky efektivna, neefektivne sa daju optimalizovat
Nikoli, ORM nemá prostředky k tomu vytvářet efektivní dotazy. ORM vytváří dotazy podle struktury objektů – zda ten dotaz bude nebude efektivní je pouze věcí náhody.
surrogate keys, autoincrement
To s ORM nijak nesouvisí, umělé klíče jsou věcí návrhu struktury databáze, autoincrement se řeší prostředky databáze.
version (kontrola integrity)
Version neřeší kontrolu integrity, je to způsob řešení optimistického zamykání záznamů.
Pyta sa externeho systemu na objekty ktore splnaju nejake podmienky. To nie je ziadna magia a nedostava riadky ale objekty, to je cely rozdiel.
No jo, jenže v tom externím systému právě žádné objekty nejsou. Tam jsou data uložená v tabulkách. A „magie“ je právě v tom, jak vybrat ta data splňující určité podmínky. Abyste ta data mohl efektivně vybírat, musíte si je nejprve správně připravit (mít je uložené ve správné struktuře a vytvořit pro ně správné vyhledávací struktury), a pak musíte správně zkonstruovat dotaz (s využitím té struktury a vyhledávacích struktur). Přičemž to první ORM nijak neovlivní, k tomu druhému má jen některé informace (zná pouze vazby objektů, nezná všechny vazby v databázi a nepoužívá informace o existujících indexech).
Ak programator nerozumie co robi tak isto vam zabije tu databazu aj v SQL.
Rozdíl je v tom, že když programátor používá SQL a dospěje k dotazu, který napsat neumí, tak ho prostě napsat nemůže a musí to vyřešit někdo jiný. S ORM si jenom řekne, že chce objekty splňující nějaké podmínky, a ORM ten dotaz nějak poskládá. Takže na to, že je to celé úplně špatně, dotyčný programátor ani nemusí přijít.
Na to su specialisti co v teame taketo veci riesia, treba ich aj v SQL tak ako aj v ORM, absolutne ziadny rozdiel.
Rozdíl je v tom, jestli se od začátku řeší efektivní přístup k databázi, nebo jestli se všechno hodí na ORM a hrubou sílu databáze, a pak se to začne řešit až když se ukáže, že z ORM lezou šílené neefektivní dotazy.
To co vy pisete stale dookola ze nejaky zaciatocnik nieco v ORM pokazi, ale to pokazi aj v SQL ked nevie co robi.
Rozdíl je právě v tom, že v případě SQL to zjistí, že neví, co má dělat, v případě ORM to nezjistí, protože ORM vždycky nějaký dotaz poskládá.
"Stránkování je nezajímavá trivialita", podobne ako dnes spomenute JOIN, funcie nad stlpcom, autoincrementalne ID, left/full join.
Stránkování je nezajímavá trivialita, přidáte podmínku na klíč >= začátek stránky a limit. Na tom není co řešit – jediné, co se na tom dá zkazit, je to, že se spolehnete na nějaké automatické mechanismy a místo hledání klíče v indexu použijete offset, čímž donutíte databázi procházet celý index od začátku.
Naproti tomu když máte spojení dvou velkých tabulek, které ve výsledku vrací 100 záznamů, můžete ho mít udělané tak, že se z jedné tabulky podle indexu vybere 100 záznamů a k nim se podle indexu dotáhne podle indexu 100 záznamů z druhé tabulky. A nebo může to omezení dělat teprve ten join, takže z jedné tabulky vytáhnete (třeba podle indexu) 10 milionů záznamů, z druhé tabulky (třeba podle indexu) 30 milionů záznamů, a teprve jejich průnikem vznikne ta výsledná sada 100 záznamů. Oba jsou to joiny nad tabulkami s desítkami milionů záznamů vracející 100 řádků, ale ten první se provede velmi rychle a efektivně, na provedení toho druhého spotřebuje databáze spoustu zdrojů.
a to musi ked prave riesi zauctovanie polozky ako side efekt biznis procesu pri reakcii na event stielany z messagingu po transformacii cez XML
Myslím, že tu nikdo nechtěl tvrdit, že ORM je v jednoduchých případech použitelné. Problém je v tom, že skrývá databázi, takže se zakryje ten zlomový okamžik, kdy ORM přestává být dobrý sluha a začíná být zlý pán, a přijde se na to až mnohem později. A druhý problém je v tom, že když se někde ORM použije, hodně těžko se části nahrazují něčím jiným – protože všechny ty automagické funkce ORM předpokládají, že ORM je pánem nad databází a ono si rozhoduje, kdy bude co načítat nebo ukládat.
> umělé klíče jsou věcí návrhu struktury databáze, autoincrement se řeší prostředky databáze.
A kolko zaciatocnikov to pozna a vie spravne pouzivat?
> který napsat neumí
Ale umi, jen blbe - dokazom budiz clanok pod ktory piseme komentare
> hrubou sílu databáze
Vy mate z toho ORM neprimerane velky strach, pokrocile ORM frameworky su dnes velmi efektivne a dobre a jednoducho optimalizovatelne
> ORM je v jednoduchých případech použitelné
Je pouzitelne aj v komplikovanych pripadoch
> ono si rozhoduje, kdy bude co načítat nebo ukládat
Nie nerozhoduje, viete to ovplyvnit - flush(), detach(), ...
Pouzivali ste niekedy na nejako skutocnom projekte napriklad Hibernate? Toto co tu pisete je velke historia a ORM je dnes asi trochu dalej nez ked ste s tym naposledy robili. A tak ako som pisal inde nie VSETKO musi byt absolutne prisposobene efektivnej praci s DB. Treba iba aby to bolo dostatocne rychle a pouzitelne, pripadne lahko optimalizovatelne.
Na projektu snad bude pracovat někdo, kdo umělé klíče zná a naučí začátečníky, jak to mají používat. Pokud tam nikdo takový nebude, neudělají umělé klíče ani s ORM, stejně jako nebudou vědět, že mohou přes ORM pracovat s autoinkrementy nebo sekvencemi.
Špatně napsané dotazy jsou v článku zmíněné jen u čistých predikátů, a ty lze úplně stejně napsat i v HQL. Navíc zrovna tohle jsou chyby, které jsou většinou vidět na první pohled (pokud to dotyčný zná), přinejhorším to ukáže exekuční plán. A ty chyby se snadno opravují.
Co znamená, že jsou frameworky velmi efektivní a dobře a jednoduše optimalizovatelné? Znamená to, že nějaký ORM framework umí načíst třeba cizí klíče z databáze a vynechat zbytečný join (pokud třeba tabulky mají vazby A → B → C, ale mají společné klíče, takže je možné spojit přímo A → C)? Nepoužíváme nejnovější verzi Hibernate, ale umí teda aktuální verze alespoň do SQL dostat hinty (třeba alespoň z HQL)? Nebo co si mám představit pod „optimalizovatelné“?
"úplně stejně napsat i v HQL"
Ale v HQL povacsinou nepisete, povacsinou pouzivate criteria a standardne mapovanie. Ked mam vsade kusy SQL nebodaj sa mi nejako spajaju v kazdej triede inac inac sa tam mapuju parametre hladajte to tam. Mozno ani nenajdete.
Vacsinou si KAZDY kto nepouziva ORM lebo sa mu to nepaci (not invented here) po case urobi nejaky jednoduchy mapovy framework, sklada tie query, nejak dava parametre, ... vzdy ZLE. To ORM mi dovoluje kludnejsie spavat. Keby sme mali robit veci bez neho uz si tu trham vlasy. Prave tu sedim za projektom, stredna velkost, servisna vrstva (NO GUI) 420.000 riadkov kodu, 412 entit, par ludi, pol roka roboty. Neviem si predstavit robit to v SQL a rucne mapovat. Optimalizovali sme txLedger v uctovnictve (vela pohybov) a nejake davkove spracovanie, mozno zopar dalsich veci. Inac vsetko ostatne standardne ORM. Takze max 10% rucnych optimalizacii - a to sa stale bavime o HQL. Cisteho SQL (complexny update v uzavierke, ..), zopar vynimocnych pripadov. Kazda entita podporuje Paging, Versioning, Auditing.
"Nebo co si mám představit" v tomto pripade napriklad fetch plan. Pre danu busines funkciu potrebujem a->c, a->d, a->b->q, pre inu iba a->c.
Už jsem to psal několikrát, takže to napíšu naposledy – ano, pro menší projekty, jaké popisujete, může být ORM v současné době stále ještě přínosné. Problém je, že ORM neškáluje – například proto, že se před programátorem pokouší skrývat databázi, a jak se má někdo naučit používat složitější konstrukce, když jsou před ním skrývány ty jednoduché. Nebo proto, že když musíte opustit automaticky generované příkazy a HQL a potřebujete použít nativní SQL, začnete mít problémy s tím, že ORM nemá moc rádo, když mu něco měníte pod rukama.
Jinak důvod, proč je ORM divné, je také v tom, že ORM se snaží relační databáze prezentovat jako úložiště objektů. Tak buď se je lepší ukládat objekty, a pak je divné to násilím mapovat do relační databáze a asi by stálo za to úsilí věnované do ORM raději investovat do objektových databází, nebo má ukládání do relačních databází své výhody, a pak je divné je pomocí ORM skrývat.
O ručním mapování tu píšete jenom vy, samozřejmě existují knihovny na zkopírování hodnot z výsledku dotazu do vlastností objektu nebo z vlastností objektu do parametrů příkazu.
Rozsáhlé skládání dotazů, které vede na velké množství různých dotazů, je špatné samo o sobě, a nezáleží na tom, zda je skládá ORM nebo někdo ručně. Protože na velké množství dotazů těžko můžete optimalizovat databázi. A navíc to vypovídá o tom, že asi uživatelům neposkytujete ty údaje, které potřebují, takže to musí řešit „vytvářením“ (prostřednictvím aplikace) velkého množství dotazů. Různorodé dotazy mají význam v případě analýzy dat, ale to je trochu jiná disciplína a k použití ORM tam není už vůbec žádný důvod.
V tom příkladu s fetch plánem nějak nevidím, v čem by se použití ORM mělo lišit od nativních dotazů.
Pak už by to nebylo ORM :) - V korporátním prostředí se pro aplikační programování prosadila Java s čistě objektovým paradigmatem. Objektové databáze se v korporátu skoro neprosadily - pár pokusů se proti IBM, Oraclu a Microsoftu nikdy neprosadilo. Takže tu jsou dvě relativně neslučitelné (ale neprotiřečící si) koncepce, které mělo něco sloučit - pokud možno něco, co bude dobře znít uším managerů - s ORM nepotřebujete drahé experty na Oracle, DB2, ...
Ono by OOP nemuselo být apriori špatně - chyba je, že se snaží ohnout práci s relační databází na ISAM postup - iterace nad záznamy. Výchozí úroveň objektu odpovídá záznamu - a programátor dál může programovat iterace, tak jak je zvyklý - a to je na tom to špatné. Kdyby výchozí objekt odpovídal relaci - tak by mapování bylo výrazně jednodušší - některé knihovny jsou takhle postavené - jestli se ještě jedná o ORM nebo nikoliv - to už bude opravdu hodně subjektivní - nicméně i s takovou knihovnou musí vývojář umět používat ten typ databáze, který je použit v projektu samostatně - byť jen proto, aby mohl udělat diagnostiku, aby mohl efektivně řešit problémy, aby se hloupě nenechal databází zatlačit do rohu, odkud není úniku ..
Ono by OOP nemuselo být apriori špatně - chyba je, že se snaží ohnout práci s relační databází na ISAM postup - iterace nad záznamy. Výchozí úroveň objektu odpovídá záznamu - a programátor dál může programovat iterace, tak jak je zvyklý
Rad bych jen dodal, ze ORM nejen ohyba praci s DB, ale i celkove mrvi objektovy navrh. Napr. vyzaduje neparametricky konstruktor (tj. je mozne vytvorit neinicializovany objekt) a nuti vytvaret gettery/settery pro vsechny atributy. U cehoz to obvykle take casto skonci. Takze ve skutecnosti takto namapovane objekty neobsahuji zadnou vlastni logiku a prisne vzato jsou to struktury. ...se kterymi se pracuje proceduralnim zpusobem.
A kdyz se to shrne, tak rada projektu, ktera pouziva ORM, ve skutecnosti s daty nakonec nepracuje ani objektove, ani relacne.
Vy to pořád nechápete! Relační a objektový model nejsou 2 způsoby uložení jedněch dat, to jsou 2 různé podstaty dat! A protože jsou z podstaty jiné, je takovým problémem je převádět mezi sebou.
Mimoto mícháte do sebe koncept ORM a implementaci ORM, neboť i experti z Oracle používají ORM.
Protože relační databáze jsou desetiletími prověřené, ví se, co zvládnou, a pokud jim někdo svěří důležitá data, určitě nebude v případě problémů popotahován za volbu neověřené technologie. Objektové nebo grafové databáze jsou v porovnání s relačními databázemi pořád spíš experimentem. Druhá věc je pak to, že spousta informačních systémů jsou vlastně různé evidence, které se dobře modelují v relačních databázích. Nepřirozené jsou tam spíš ty objekty – pro mne je spíš otázka, proč se u webových aplikací vůbec dělá ten objektový mezistupeň, místo aby se data z relační databáze rovnou transformovala do HTML/XML/JSON a opačně.
Druhá věc je pak to, že spousta informačních systémů jsou vlastně různé evidence, které se dobře modelují v relačních databázích.
Ano, ale to vůbec neodpovídá této diskusi, kdy jsou tady někteří skalními příznivci datových objektů.
pro mne je spíš otázka, proč se u webových aplikací vůbec dělá ten objektový mezistupeň, místo aby se data z relační databáze rovnou transformovala do HTML/XML/JSON a opačně.
Ano, to je přesně ono. Data, která jsou více nebo méně v přirozené relační formě se nejdřív v jedné vrstvě převedou na objekty a potom se ty objekty mapují na relace. Praštěné na hlavu.
Já ORM považuju za zlo (na počátku projektu vypadá že pomůže a potom už je to jen koule na noze) a nikde to samozřejmě nemáme. Tak jsem poněkud zaskočen touto diskusí, kdy někteří vypadají, že bez ORM nevyjdou z domu.
Taky je to asi tím, že v PG je hromadu let možnost ukládat i nerelační data (hstore, teď json), takže nestrukturovaná data rvu rovnou tam.
Tak jsem trochu čekal, že ORM má trochu hlubší smysl než jen v tom, že "máme nasazenou SQL databázi a nic dalšího tady nebude".
Nikdo neříká, že musíte používat hned objektové či grafové DB, přístupnější jsou dnes dokumentové DB, které už jen tím, že umějí ukládat uvnitř dokumentu seznamy, což RDB nedokáže (překvapení?), tak mají nepoměrně jednodušší mapování objekt <-> dokument.
Napište příklad nějaké evidence, která je z povahy relační.
Napište příklad nějaké evidence, která je z povahy relační.
Je možné, že je to jen zvyk a síla relačních databází, které dokázaly relační model propašovat až do uživatelských modelů. A že by to tedy z uživatelského hlediska šlo modelovat i jinak. Ale v současné době bych asi těžko hledal evidenci, která relační není. E-shop – seznam zboží, zboží je v kategoriích, seznam zákazníků, zákazník má seznam objednávek, v objednávce je seznam zakoupeného zboží. Fakturace – seznam faktur, z každé faktury odkaz na dodavatele, seznam položek faktury. Sklady – zase seznam typů položek, seznam umístění a vazba kolik položek kde leží. Evidence osob – seznam osob, seznam adres, osoba má různé typy adres (trvalý pobyt, korespondenční, fakturační). A uživateli se to vždy prezentuje jako seznam vybraný podle nějakých kritérií, zvolím si jeden záznam, vidím jeho detail a v něm zase odkaz na jiný seznam nebo jiný záznam.
Nemůžu se vyjadřovat k těm ostatním tématům, ale relační fakturace je mýtus. Faktury, a obecně účetní doklady, jsou z povahy věci dokumenty. Položky faktury samy o sobě nedávají žádný smysl, ale musí být v samostatné tabulce, protože ... bagr. Položky faktury patří na fakturu. V dokumentovém světě žádný problém. V relačním -- nelze. S adresami na fakturách je to mimochodem taky zajímavé -- adresa samozřejmě na první pohled patří k nějaké osobě, na kterou má být z faktury vazba, jenže adresa osoby se v čase mění, takže z faktury bude buďto vazba na verzi adresy (koncept umělý a navíc omezující), nebo se spíš ta adresa na fakturu zkopíruje. Ostatně je i na tom papíře.
S adresami na fakturách je to mimochodem taky zajímavé -- adresa samozřejmě na první pohled patří k nějaké osobě, na kterou má být z faktury vazba, jenže adresa osoby se v čase mění, takže z faktury bude buďto vazba na verzi adresy (koncept umělý a navíc omezující), nebo se spíš ta adresa na fakturu zkopíruje.
Nevím, proč by verze adresy měla být umělý koncept. Lidé se stěhují zcela běžně. Dokonce lidé mění i jména. Toto dodnes vývojáři různých systémů pro správu kontaktů nepochopili, takže pokud chci evidovat, že se někdo přestěhoval, tak to musím různě ohýbat. Přitom by bohatě stačilo, kdyby daný typ adresy byl prostě jen seznamem adres s různými rozsahy platnosti. Totéž u jména. Nejedná se jen o (typicky) ženy po svatbě, znám lidi, kteří si nechali kompletně změnit jméno i příjmení. Dokonce i města mění jména. A zkuste to zadat do nějaké programu kontaktů... V lepším případě pouze exploduje celý vesmír.
"Nevím, proč by verze adresy měla být umělý koncept."
Oni soudruzi vyvojari jeste stale nepochopili, ze i jeden clovek muze mit klidne 10telefonu, a 15 emailu ... takze tak maximalne naflakaj do tabulky 2-4 sloupce, a ... "si to tam napisete a oddelte treba strednikem ne ..." s cimz se vazne bezvadne pracuje.
Oni soudruzi vyvojari jeste stale nepochopili, ze i jeden clovek muze mit klidne 10telefonu, a 15 emailu ... takze tak maximalne naflakaj do tabulky 2-4 sloupce, a ... "si to tam napisete a oddelte treba strednikem ne ..." s cimz se vazne bezvadne pracuje.
Mě na tomhle vlastně nejvíc fascinuje ta psychologie. Ti lidi sami mají běžně x mailů a y telefonů, ostatně pro to píšou i appky, vyměňují firmware a podobně. A teď by mě zajímalo, co přesně se musí stát, aby člověk, který ví že je na světě víc než jedna adresa, tu appku napsal takhle blbě. Jako to jim vypadne mozek z hlavy? Fakt nevím.
Ad napište a oddělte středníkem. Tady někde probíhala diskuse o validování a konzistenci dat. Normálně napsaná aplikace by nic takového nepřipustila. Prostě v poli emailová adresa bude emailová adresa a ne Babička od Božky.
Jednou jsem v poli telefon našel záznam: 'stejný jako sousedka'.
"Jednou jsem v poli telefon našel záznam: 'stejný jako sousedka'."
... normalka, to uz me vubec nevyvede z miry, takovych zaznamu v tech databazich co k nim mam pristup sou tisice. A pak se soudruh managor strasne divi, ze jeho novy uzasny telefonni system ktery ma zaznamenavat hovory aby si on moh kreslit nesmyslne grafy ... nezaznamenava vubec nic.
Další příklad, proč je to v RDB složitější - když potřebuju seznam emailů (bez požadavku na složitější zpracování), v dokumentové DB uložím v dokumentu jejich seznam. Triviální. Ne tak v RDB, tam buďto dám jeden sloupec, odkud si to vylámu, nebo nadimenzuju několik sloupců, nebo udělám extra tabulku, která povede VŠECHNY seznamy emailů všech osob. Každé z těchto 3 řešení je horší nebo složitější.
Samozřejmě, že i v relačním světě můžete pracovat s historií - buďto ručně - přidáte si informaci o platnosti, nebo to už podporují některé databáze přímo - viz temporální databáze, případně dneska i část ANSI/SQL - http://www.slideshare.net/CraigBaumunk/temporal-extensions-tosql20112012010438
Pokud mám databázový systém, který mi umožňuje implementaci logiky, tak proč ně? Rozbíjí se tím monolitický design, zvyšuje se tím reuse, operace s daty se dělají blízko datům.
Když se podíváte na Hadoop like systémy, tak byť jsou napsané v Javě, tak používají koncept podobný uloženým procedurám - stěhují algoritmus na databázový server - blíž k datům. U velkých dat je mnohem praktičtější přesunout výpočet než přesouvat data.
Samozřejmě, že ne každá technologie je dostatečně vyspělá, aby mi umožňovala plnohodnotné programování - to, co nabízí Oracle, DB2, Postgres ale programátora nijak neomezuje. Předpokládám, že až NoSQL databáze trochu vyspějí, tak sofistikovanější API budou nabízet také.
"ale relační fakturace je mýtus"
what? polozky faktury patri = maji relaci, k te konkretni fakture, na polozkach je relace na konkretni sluzby nebo zbozi, relace na cenotvorbu atd atd.
Ze nekdo neumi navrhnout strukturu je jeho (a zdaleka ne jen jeho) problem. Firmu v databazi reprezentuje nejaky zaznam firmy, adresa neni jeho soucasti, protoze adres v relaci k tomu zaznamu muze byt N. Soucasti faktury je pochopitelne nejen realace na zaznam "firma", ale prave relace na zaznam "adresa firmy". Pokud se firma prestehuje, tak jen pribude dalsi zaznam adresa, a maximalne se nekde nastavi jako vychozi. Takze vsechny stavajici faktury si podrzi spravne udaje. Nemluve o tom, ze jako "bonus" nepotrebuju mit dalsi sloupce s adresama soukromych osob ... protoze adresa je proste zaznam v tabulce adres.
Ano, spousta vyvojaru sou prasata bez mozku, ktery neco takhle primitivniho nedokazou pochopit, natoz vytvorit.
To vubec nemluvim o moznosti vsechny pripadne zmeny auditovat (v tech relacich, neb vzdy patri ke konkretnimu zaznamu), a pak lze kdykoli zobrazit stav libovolneho zaznamu k libovolnemu historickemu datu.
Obávám se, že ve vašem případě jde o klasickou záměnu pojmů: Termín „relace“ (ang. relation) neznamená vztah (ang. relationship), ale „n-tice“. Takže „polozky faktury patri = maji relaci“ je nesmysl, položky mají vztah (k faktuře), ale podstatou se nejedná o n-tice, ale objekty/uzly grafu s hranami - vztahy. Takže tvrzení „ale relační fakturace je mýtus“ znamená „ale n-ticová fakturace je mýtus“ a je správné.
Faktura jsou mrtvá data. Adresa v ní musí být uložena, stejně jako ceny atd. Takže faktura vlastně je dokonalý příklad dokumentu.
Něco jiného je objednávka, výrobní příkaz apod. Tam je část dat uložena (kusovník, vytvoření kopií z TPV), ale plno dalších je tam referencí (účetní hodnota komponent, nákladová střediska atd.)
V každém případě je ale model stále relační. I když mám popisek položky vykopírovaný do faktury (aby dodatečný tisk vypadal přesně tak jako originál), tak je tam pořád relace na id položky. Takže mohu kdykoliv spouštět dotazy typu "kdy, komu a kolik jsem fakturoval za položku XY". To je něco, co v dokumentové databázi nefunguje levně. Vyhledáváte podle atributu. Přidejte si dotazy podle zákazníka, země dodání, kódu DPH, dopravce atd.
A to ta faktura má ještě reference do účetnictví. Jedna faktura může mít více účetních dokladů, na jednom dokladu může být více faktur, faktura se páruje s platbami, pokud se neplatí rychle, tak se musí účtovat kurzové rozdíly atd. Prostě roste vám počet dokumentů, které spolu mají nějaké relace. Rychle se dostanete do stavu, kdy se vám ty dokumenty vyplatí cpát do relační databáze.
A v adresách se vám motají dvě věci: číselník adres a registr dodavatelů/odběratelů atd. V ERP se to běžně spojuje do jednoho, ale stále to jsou dvě různé věci. To první jen říká nějakou výchozí adresu dodací, výchozí adresu fakturační, výchozí platební podmínky atd. Na objednávkách se to vykopírovává a pak se to může přepsat. Ten registr je pak o kreditu, kontaktech atd. Zda chcete 400x denně vypisovat tu samou adresu, to je vaše volba. Ale pokud chcete sledovat výši a čerpání kreditu zákazníka, pak se bez "umělého a omezujícího konceptu" číselníku zákazníků neobejdete.
„Faktura jsou mrtvá data. Adresa v ní musí být uložena, stejně jako ceny atd.“
Chyba - 1. přijdete o identitu adresy, 2. to bude velké. Buďto víte, kdy byla faktura vystavena a adresa je ta platná k tomuto okažiku daného subjektu, nebo ji můžete ze subjektu explicitně označit a zachováte její identitu (a ještě je to menší). Kopírovat není nic třeba.
„ I když mám popisek položky vykopírovaný do faktury...“
Ta samá chyba. Položka má identitu a je dán její název buďto napořád (objekt je modelován jako immutable), nebo v času (mutable). Vykopírovávat není nic třeba.
„To je něco, co v dokumentové databázi nefunguje levně. Vyhledáváte podle atributu.“
V dokumentové DB si buďto držíte seznam všech položek, ve kterých hledáte (obdoba RDB, nevhodné), nebo v případě, že potřebujete často zjišťovat faktury s položkou, si pro položku držíte seznam faktur (v RDB nejde). Pak nehledáte nic!
Záměna termínů vztahy - relace.
Naopak, čím více vztahů máte, tím hůře se modelují v RDB (zde jsou nutné při JOINech prohledávané vazební tabulky) a je vhodnější je ukládat do DB, která umí seznamy (odstraňuje vyhledávání).
Už zase něco vykopírováváte? Jak potom u faktur zjišťujete shodu adres, když jste přišel o identitu? Porovnáním hodnot???
Číselník je koncept z RDB pojmenovaný dle vnitřního označení relace řešeného obvykle číslem (přestože to často bez problémů může být řetězec), v objektovém modelu nic takového není, ten používá seznam s položkami s identitou. Je vidět ten rozdíl?
Faktury nejsou dokumenty (jestli se bavíme ve smyslu DB), ty nemají implicitní vazby na související entity, ale objekty, případně uzly grafu, ty vazby mají. To samozřejmě neznamená, že je do dokumentu nejde (jako do relací) explicitně uvést.
„Položky faktury patří na fakturu. V dokumentovém světě žádný problém. V relačním -- nelze.“
Přesně to jsem psal v předchozí odpovědi - RDB NEUMÍ ukládat implicitní seznamy, řeší to explicitně cizími klíči!
Adresa má být namodelována jakkoli jako součást měnícího se subjektu (způsobů je více).
A to je přesně ono: To, co jste popsal, je objektovým systémem s vyjmenováním vzájemných vztahů prvků, to není relační model!
Co se stane, když to narvete do RDB? Implicitní, přímé paměťové vazby musíte rozpojit a nahradit explicitními klíči, které je třeba dohledávat (to je i u dokumentové DB, ale ne např. u objektové DB), ale především např. položky faktury už nejsou uloženy v krátkém seznamu faktury, ale v jedné obrovské tabulce se VŠEMI ostatními položkami všech faktur, kdy je třeba dle klíče EXPLICITNĚ sestavovat jejich seznam, protože RDB seznamy ukládat neumí (dokumentová i objektová DB to umějí). V případě, že každá položka faktury (či jiná entita) je trochu jiná (což je zcela běžné), tak budete navíc řešit, jak narvat polymorfní prvky do jedné tabulky, nebo je rozstrkávat do více tabulek. Změna struktur za chodu systému je další věc, která u RDB vzhledem ke schematičnosti nejde. Vazby m:n je třeba řešit vazební tabulkou, vazby 1:n je třeba někdy otočit z 1->n na 1<-n, protože opět seznam nejde uložit, takže místo aby faktura odkazovala na svoje položky (v dokumentové DB standard), musím opačně v položkách uvést fakturu. Atd. Neboli relační model je zcela jiný než objektový.
Implicitní, přímé paměťové vazby musíte rozpojit a nahradit explicitními klíči
Co si představujete pod výrazem "přímé paměťové vazby"? Jestli jako odkaz z jedné datové struktury (místa v paměti) na jinou datovou strukturu, třeba jako v C, tak toto si pomalu každý vyšší jazyk řeší po svém a u složitějších kolekcí už ten odkaz rozhodně není tak přímý.
Jinými slovy, toto je pouze implementační detail. Propojit tři tabulky (n:m) pomocí klíčů je úplně stejný implementační detail.
ale především např. položky faktury už nejsou uloženy v krátkém seznamu faktury, ale v jedné obrovské tabulce se VŠEMI ostatními položkami všech faktur, kdy je třeba dle klíče EXPLICITNĚ sestavovat jejich seznam, protože RDB seznamy ukládat neumí
Jednak některé DB seznamy ukládat umí, ale především, čemu konkrétně vadí že ty položky jsou v jedné obrovské tabulce? Pokud potřebuju vytáhnout položky k dané faktuře, tak je to jeden join (kterej bude rychlejší, než mi dokumentová databáze vrátí jeden kompletní dokument - kterej je mimochodem taky uložený na disku v jednom obrovském souboru - a to včetně dat, který nepotřebuju). V čem má být problém?
„Co si představujete pod výrazem "přímé paměťové vazby"? Jestli jako odkaz z jedné datové struktury (místa v paměti) na jinou datovou strukturu, třeba jako v C, tak toto si pomalu každý vyšší jazyk řeší po svém a u složitějších kolekcí už ten odkaz rozhodně není tak přímý.“
Programově tečku (ve Smalltalku mezeru), tj. odkázání triviálně názvem, vnitřně implementačně pointer na objekt (Smalltalk, jak si to řeší Java, netuším), tj. bleskově, každopádně nemá smysl řešit nějakou rychlost procesoru a paměti, rychlost práce DB s diskem je 100x pomalejší.
„...Propojit tři tabulky (n:m) pomocí klíčů je úplně stejný implementační detail.„
Vzhedem k tomu, že tu vazební tabulku musíte extra číst a dělat s ní JOIN (tj. hledat v ní), tak to určitě není pouze implementačním detailem.
„Jednak některé DB seznamy ukládat umí...“
Ale o těch tu nikdo neuvažoval.
„...ale především, čemu konkrétně vadí že ty položky jsou v jedné obrovské tabulce?“
Že je musíte v indexu cizího klíče se statisíci záznamy nejdřív najít.
„...je to jeden join (kterej bude rychlejší, než mi dokumentová databáze vrátí jeden kompletní dokument...“
Čtení dokumentu jako celku (dle klíče) je velice rychlé, je to jediný, celistvý kus dat.
Vzhedem k tomu, že tu vazební tabulku musíte extra číst a dělat s ní JOIN (tj. hledat v ní), tak to určitě není pouze implementačním detailem.
To je implementační detail. Jestli v nějakém jazyku napíšete objekt.neco
(a ono se v pozadí vykoná magie nad pamětí toho programu), nebo zavoláte metodu get_data()
a v té si napíšete select neco from neco join neco where neco
, tak je to jen implementační detail. To, že tu magii nad kolekcemi objektů (ve vyšších jazycích) nevidíte neznamená, že tam není.
nemá smysl řešit nějakou rychlost procesoru a paměti, rychlost práce DB s diskem je 100x pomalejší
Aha, takže tatáž data jednou předpokládáte v paměti a podruhé na disku. A do té paměti se dostala jak? I relační db může mít data v paměti a většinou se i snaží, aby tam byla.
Že je musíte v indexu cizího klíče se statisíci záznamy nejdřív najít.
vs.
Čtení dokumentu jako celku (dle klíče) je velice rychlé
Takže v případě relační db použití indexu vadí zatímco v případě jiné db použití (většinou stejně naimplementovaného indexu) nevadí.
je to jediný, celistvý kus dat
A to je právě to. Ten dokument může být velký stovky MB. Takže rychle vyhledáte (podle indexu) jeden celistvý dokument, ve které máte všechno a načíst to z disku trvá.
Relační db vznikly proto, aby se ukládalo (proto normální formy) a četlo (proto vhodné dotazy) minimum dat. Takže na stejnými daty zavolám vhodně napsaný dotaz a vrátí se pouze to minimum, co chci. To, že je součástí dat i fotodokumentace mě v danou chvíli nezajímá a db server to ani nemusí číst. Pokud by to bylo v jednom dokumentu, tak se to čte vše.
Zas mícháte dohromady práci v paměti a DB - v paměti (objekt.metoda) mě optimalizace nezajímá, v DB (select ...) ano, protože tam je každé čtení z disku navíc znát. Takže to, co máte v paměti aplikace, musíte rozlámat na kousky, které jdou nastrkat do DB. Podle toho, jak to rozdělíte, to bude rychlé.
Ano, zde máte pravdu, oboje je přes index, takže podobně rychlé. To jsem si neuvědomil.
Jestli máte běžný dokument velikosti stovek MB, něco je špatně. Průměrný normalizovaný dokument může být kolem kilobajtů až desítek KB.
Normální forma není vázaná na RDB, jak si někteří myslí, normalizovaný či denormalizovaný dokument jde stejně dobře udělat i v dokumentové či objektové DB či v objektu v paměti. Rovněž ve čtení nepotřebných dat není RDB nijak vyjímečná, každá DB čte záznamy v nějakých skupinách, protože po položkách se to nevyplatí řešit (a z pohledu objektů je to přímo nekoncepční). Zrovna RDB obsahuje při mapování obecných objektů na relace (v případě obecné tabulky) sloupce, které se plní jen někdy. Velká data nemusíte nutně v dok. DB včlenit do dokumentu, stačí je vést samostatně. V objektové DB je to automaticky, protože i ta data jsou objektem (např. obrázek).
Implicitní, přímé paměťové vazby musíte rozpojit a nahradit explicitními klíči, které je třeba dohledávat
FYI, a votom to je. Relační model sjednocuje uložení dat a vztahu mezi nimi do jedné struktury = relace. Nepotřebuješ mít extra strukturu pro data a extra pro vazbu mezi nimi (seznam). A díky tomu si všechny operace zjednodušíš.
protože RDB seznamy ukládat neumí
jelikož základní entitou, se kteoru RDB pracují je relace, tj. množina, je naivní požadovat, aby pracovala se seznamem
„...Nepotřebuješ mít extra strukturu pro data a extra pro vazbu mezi nimi (seznam). A díky tomu si všechny operace zjednodušíš.“
Nezjednodušíte si nic, protože mezitímco dle seznamu klíčů hledáte v indexu dok. DB (collection), v RDB hledáte dle klíče v indexu tabulky, takže to vyjde podobně. A s tím tykáním opatrně.
„relace, tj. množina“
Relace je n-tice, ne množina.
> Objektové nebo grafové databáze jsou v porovnání s relačními databázemi pořád spíš experimentem.
Tohle bych si nedovolil říct. Spíš myslíte Objektově-orientované databáze.
Objektové databáze jsou trošku něco jiného, jsou tu celkem dlouho a jejich základ vznikl dříve než relační databáze.
Za průkopníka můžeme považovat MUMPS (rok 1966), který se i v současnosti hojně používá
> Druhá věc je pak to, že spousta informačních systémů jsou vlastně různé evidence, které se dobře modelují v relačních databázích
Minimálně stejně dobré jsou právě "objektové databáze". Zmiňovaný MUMPS ukládá data do hierarchických struktur.
Používá se ve zdravotnictví a v bankách a jsou vhodné pravě na různé evidence.
V hierarchické databázi navíc není problém emulovat relační i dokumentované databáze. Dají se i grafové, ale už to není tak triviální.
ORM je tu desítky let. Byla to dočasná obezlička. Aplikační logika byla objektová, ale neexistovaly rozumné objektové databáze. Oproti tomu relační databáze tu byly, fungovaly a "měl je každý". Takže se v devadesátých letech začalo prosazovat ORM, které mělo fungovat těch pár let, než se prosadí plně objektové databáze.
Bohužel se za těch 20 let trochu vytratila ta informace, že se jedná o nedokonalou dočasnou berličku, a řada firem a lidí se to snaží tlačit jako plně funkční nástroj. Na druhou stranu ale taky co dělat jiného, když silné objektové databáze stále nemáme. Tak snad se nějaká z nich prosadí a ORM konečně odejde do historie tak, jak bylo plánováno již v minulém tisíciletí, kdy jsem ještě navštěvoval konference.
„ORM nemá prostředky k tomu vytvářet efektivní dotazy. ORM vytváří dotazy podle struktury objektů – zda ten dotaz bude nebude efektivní je pouze věcí náhody.“
To je samozřejmě nesmysl, efektivita dotazů bude tak velká, jak chytré ORM vytvoříte, různých optimalizací se dá navymýšlet spousty, vzhledem k nekompatibilitě relačního modelu s objektovým a různým implementacím je to bezednou studnicí.
To je samozřejmě nesmysl, efektivita dotazů bude tak velká, jak chytré ORM vytvoříte, různých optimalizací se dá navymýšlet spousty, vzhledem k nekompatibilitě relačního modelu s objektovým a různým implementacím je to bezednou studnicí.
Psal jsem o současných implementacích. Ano, je možné uvažovat o ideálním ORM, ale pak je otázka, zda není lepší uvažovat o ideální objektové databázi.
A este jedna vec: "Stránkování je nezajímavá trivialita", podobne ako dnes spomenute JOIN, funcie nad stlpcom, autoincrementalne ID, left/full join. Kolko naivnych "RYCHLYCH" SQL kodov som ja uz videl. Namiesto vyberu celeho agregovaneho objektu vratane relacii dotahovanie jednotlivych podobjektov lebo programator je lenivy pre kazdy pripad robit a UDRZIAVAT specialny dotaz s velkym mnozstvom joinov, radsej to dotahuje jednotlivo aj ked vie ze vsetky tie udaje bude potrebovat. Tam je jadro problemu. A preto hovorim ze dobry programator to bude mat urobene rovnako dobre v ORM ako v SQL ale rychlejsie a prehladnejsie, zly programator to v SQL domrsi hroznym sposobom a moze sa tomu lahko vyhnut pouzitim ORM.
To řešíme tak že Lazy Loading je default a pokud píšeme dotaz který bude vytahovat hodně záznamů kde vidíme že by Lazy Loading byl neefektivní (dotahoval by podřízené záznamy extra ke každému nadřízenému záznamu) tak u konkrétních dotazů vynutíme Eager Loading (dotažení všech podřízených záznamů najednou a roztřídění k nadřízeným záznamům v ORM).
To není pravda. Měl jsem na mysli něco takového:
https://github.com/kennethreitz/records
Dotazy zapisuji v SQL. Žádné definice modelů tam nejsou.Jak reprezentuji výsledky je nepodstatné.
1. Předpokládám, že za NoSql myslíte nerelační.
2. Tvrzení „Jsou situace, kdy se NoSQL databáze mohou hodit.“ považuju za (slušně řečeno) hodně odvážné v situaci, kdy obrovské množství systémů v IT zpracovává objektová data (obchodní systémy) a snaží se je s obrovskými a stále se vracejícími problémy narvat do RDB.
3. Z toho mi vyplývá, že jako já považuji, vy nepovažujete za jeden z největších omylů IT snahy o ukládání objektových dat do relací, ale ORM (či některých jeho nakynutých implementací?), které je jen řešením daného rozhodnutí a za nic nemůže.
O čem se tu potom chcete bavit? Postopadesáté o tom, jak narvat objektová data do RDB a jak se je pak pokusit přečíst?
P. S.: Předpokládám, že tu dost lidí bude prskat, ale rozvrstvení informatické populace je přece známé.
Neexistuje nic jako objektová data, stejně tak relační data - máte jen nějaký způsob, jak reálný svět zpracováváte - můžete mít objektový model, můžete mít relační model.
Aktuálně řeším problém v jedné firmě, kde jsou těžké problémy s aplikací - primárně proto, že je některé věci jsou úplně blbě, jiné roky neřešené. Problémy nejsou v relační databázi, ale v amatérismu lidí, co psali tu aplikaci - je to stejné, jako když dáte opravit auto lemplovi, tak spláčete nad výdělkem.
NoSQL databáze jsou z principu výrazně pomalejší než relační databáze - mají ale jednu výhodu - snadno škálují - takže místo jednoho serveru můžete mít 10, 100 serverů, atd. Pro aplikace typu LinkedIn, Facebook to má jasný přínos - navíc v těchto aplikacích nemáte fakticky nemáte žádnou evidenci - data jsou opravdu skrumáž atributů. Pro mne jsou ale tyto aplikace výjimky potvrzující pravidlo.
U NoSQL snadno zapisujete, snadno děláte updates, můžete relativně snadno zajistit vysokou dostupnost. Ale už spočítat report, který by vyžadoval konzistentní data a vracel konzistentní výsledky je téměř nemožné - a výrazně pomalejší než nad relační databází.
Chcete snad říci, že n-tice dat vypadávájící z průmyslového měřicího systému s minimálními či žádnými vazbami na další entity mají stejnou strukturu jako informační systém společnosti s hustě vzájemně propojenými nehomogenními a dokonce se strukturálně měnícími entitami?!!! Už sama existence složitosti ORM vás usvědčuje z toho, že opět kecáte.
Databáze NoSQL jsou pomalejší pouze v prohledávání dat v důsledku jejich volného uložení, tato nevýhoda se však často stírá vhodným modelem obsahujícím podseznamy souvisejících entit, které si ovšem RDB nemůžou dovolit, protože ukládání seznamů neumějí. Není důvod aby pomaleji hledaly dle klíče. Případné horizontální škálování (které v RDB neuděláte) jste zmínil sám.
„Ale už spočítat report, který by vyžadoval konzistentní data a vracel konzistentní výsledky je téměř nemožné - a výrazně pomalejší než nad relační databází.“ Vy si snad děláte prdel! Jak můžete paušálně prohlásit, že v NoSQL bude něco pomalejší, natož že to nejde ani smysluplně spočítat?!
Jestli se cítíte být relačníkem, přejmenujte článek na „Optimalizujeme model a dotazy RDB“ a vyhněte se systémům s databázemi NoSQL, nováčci se vyhnou tradovaným bludům.
Určitě tu bude hodně nesouhlasu (rozložení IT pořád platí), ale snad to pomůže některým otevřenějším začátečníkům.
Nad dokumentovou databází máme postavený jednoduchý informační systém. Zkušenosti s takovou databází?
- je to pomalé, protože neexistují hromadné operace, například obdoba "delete from table where date < '2016-01-01'
- agregace (select ... group by) - tj. obdoba reportu - se obvykle dá udělat, ale je to často takový opruz, že bych se na to mohl vyprdnout. Běh hotového reportu být pomalejší nemusí.
- databázi máme rozloženou na zhruba deseti počítačích. Jak můžu udělat smysluplný a konzistentní report, když v každém počítači je v databázi něco trošičku jiného a obvykle bývá přístupná sotva polovina počítačů?
Na druhou stranu distribuovaný charakter dat je v našem prostředí fantastická vlastnost, tady se může jít jakákoliv SQL databáze klouzat. S SQL databází bych nikdy nic podobného provozovat nemohl.
Že dostanu reporty z neúplných dat? Příliš mě netrápí, že kolega ve svém vypnutém notebooku v batohu má data, ke kterým nemám přístup. V praxi se ukazuje, že každý dělá ve svém omezeném okruhu dat a reporty ke svým datům má obvykle konzistentní. Každý má na svém počítači něco jiného, časem se data nějakým způsobem utřepou a časem (v rozmezí dnů) stejně získám k datům kolegů přístup i já. Jenom s tím musím počítat.
Nebude chyba v tom, že s dok. DB pracujete jak s relační? Sekvenční procházení seznamů je bude asi vždy pomalejší oproti RDB (výměnou za bezschématovost), ale provádíte-li často hromadnou operaci dle nějaké vlastnosti, máte si udělat podle ní „index“/dictionary/map, pak je rychlost shodná s RDB.
To rozložení po více počítačích jsem nepochopil - to, že dok. DB neřeší konzistenci, neznamená, že se na ni můžete ve vyšší vrstvě vybodnout.
Paušálně to mohu prohlásit z toho důvodu, že NoSQL databáze nemají žádné hromadné operace. Buďto jedete nad indexem, nebo si průběžně udržujete nějaké čítače, nebo zase speciální indexy, z kterých pak čtete data. Pracnost reportingu založeného na Map/Reduce je výrazně větší než použití SQLka.
Už jen to, že Mongo jako analytický nástroj dodává Postgres říká o tom, jak jsou na tom NoSQL databáze co se týče reportingu.
NoSQL databáze jsou zatím relativně nové -- cca 10 let - to vůči relačním db cca 30 rokům musí být znát. Osobně věřím, že za 10 let dojde mezi SQL databázemi a NoSQL databázemi k hromadě výpůjček. V tuhle chvíli je ale potřeba k NoSQL databázím říct i to b.
„NoSQL databáze nemají žádné hromadné operace“
MongoDB: db.getCollection('knihy').find({autor: 'Ocas Ocasovič Ocasov'})
„...jedete nad indexem...“
V dok. a obj. DB se tomu říká seznam.
„Už jen to, že Mongo jako analytický nástroj dodává Postgres říká o tom, jak jsou na tom NoSQL databáze co se týče reportingu.“
Nejsou náhodou zpracovávaná data relační?
„NoSQL databáze jsou zatím relativně nové -- cca 10 let“
Jistě.
„Osobně věřím, že za 10 let dojde mezi SQL databázemi a NoSQL databázemi k hromadě výpůjček.“
Panebože, doufám, že ne!
Tradičně výborný článek od Pavla Stěhuleho. Škoda, že současně s tím root publikuje sérii nekonzistentních a zmatených článků https://blog.root.cz/databaze/postgresql-pl-pgsql-serverove-programovani-02-anonymni-blok/, pro jistotu bez možnost komentářů :-(
Já jsem rád za texty, které Michal Šalko píše. Je to blog, který neprochází jazykovou korekturou - tudíž není na místě mít podobná očekávání jako na článek. Píše o věcech, o kterých já nepíši, protože už je beru jako samozřejmost. Když se ale bavím s většinou vývojářů, tak samozřejmé zdaleka nejsou.
Taky jsem si na tom spalil prsty. Jako myslenka je to dobry. Bohuzel to pouziva malo zakazniku, tudiz to neni poradne otestovany a Oracle to bohuzel nikdy nedotahnul do pouzitelneho stavu.
Pokud by to slo pouzivat, tak by to melo tu vyhodu, ze by to dokazalo vracet vice-dimenzionalni data a tim by odpadlo spoustu round-tripu mezi aplikaci a databazi.
Pekny clanok prinasajuci imho informacie z rannej praxe vacsiny developrov (teda koderov, nie DB specialistov). Kedze i ja som koder, mam otazku k DB ludom.
Ma zmysel pouzivat postgresql pri CQRS (Command Query Responsibility Segregation) pristupe?
CQRS=> Vsetky zapisujuce operacie tlacia data do "zurnalovej"/event tabulky. Stlpce su ID, idAgregatu (napriklad faktury) a event (udalost, napriklad json stlpec). Teda operacie nad fakturami su rychle, lebo je to append only. Ked niekto ide citat nieco, co sa tyka faktur, tak CQRS vravi, ze pre casto pouzivane operacie je dobre mat query model.
Teda napriklad pre operaciu ziskania faktur spolu so sumou, adresou dorucenia a cenou by bola tabulka s idAgregatu (faktury) a jsonom (alebo jednotlivymi stlpcami). Dopyt na read operaciu sa vybavy rychlo. Vpodstate je to len podanie jedneho riadku tabulky ziadatelovi. Toto pekne funguje, len pri castych updatoch velkych dokumentov, sa moze stat, ze sa updatuje json dokument o velkosti niekolko kb. Je to pre postgresql OK, alebo treba v tomto stave uvazovat nad nejakou nosql DB, alebo zmenit pristup k perzistovaniu QM, alebo to riesit inym sposobom? (niektore QM=predpripravene odpovede k agregatom; sa zvyknu drzat v pamati iba a predvypocitavat pri starte app)
PS: Prepojenie eventov a update query modelu je asynchronne a QM je teda "eventualy consistent". Prosim nerieste tento aspekt cqrs pristupu (vpodstate strata transakcnosti na prvy pohlad), ale len otazku. Teda vhodnost/nevhodnost postgresql na ukladanie/updatovanie/citanie "dokumentov" (velkost zvacsa okolo kilobajtu, par vynimiek okolo 100kB).
podle mne je to technika, která má smysl u NoSQL databází, ale u ACID relační databáze to vůbec nemá smysl. NoSQL databáze oproti relačním databázím umí mnohem hůře hromadné operace - přístup k položkám v JSONu je mnohem pomalejší než sekvenční čtení flat záznamů v relační databázi. Pro zrychlení čtení, případně vůbec pro zajištění konzistence se tam používají podobné techniky - a spíš se používá event zpracování (abyste se vyhnul hromadným operacím). V relační databázi je to kontraproduktivní - ledaže byste se snažil simulovat v relační db NoSQL db, což ale mi nedává smysl.
„...NoSQL databáze oproti relačním databázím umí mnohem hůře hromadné operace - přístup k položkám v JSONu je mnohem pomalejší než sekvenční čtení flat záznamů v relační databázi.“
Samozřejmě, ale jen do okamžiku, než budete muset udělat JOIN nebo čtení z další tabulky tam, kde byste v JSONu sáhnul do podseznamu, což je u netriviálních objektů běžné.
Mimoto v RDB probíná vyhledávání v celých indexech tabulky všech entit jednoho typu (často statisíce záznamů), protože RDB (jak jsem zmiňoval) neumí ukládat seznamy, kdežto dokumentová či objektová DB může využít vyhledávání jen v příslušných seznamech omezených množin entit, což může činit rozdíl množství řádů.
To už je o těch konkrétních případech - JOIN je pomalejší, ale JSON zase omezenější - JOINy si můžu potřebovat - JSON mám pouze jeden, a žádnou další kombinaci neudělám. Pokud databázi používám jako storage - pak dokumentové databáze, NoSQL databáze bohatě stačí, a asi se nenarazí na limity. Jakmile se začnou počítat reporty, případně dělat adhoc analýzy, tak buďto mám dynamiku (u bezeschémových databází) nebo rychlost (u SQL) - nelze mít obojí.
To, co popisujete je technika, která se jmenuje Event Sourcing. S CQRS nemá nic společného, kromě toho, že se často pro implementaci CQRS používá.
CQRS je obecně velmi jednoduché. V podstatě pouze rozděluje systém na 2 části:
1. Write (Command) část sloužící pro zpracování operací, které mění stav systému.
2. Read (Query) část sloužící pro operace, které nemění stav systému - čtení a dotazování.
Na obě části jsou často kladeny jiné požadavky co se týče výkonnosti a škálování. Rozdělením je možné je optimalizovat nezávisle na sobě.
Např. U spousty aplikací je výrazně méně Write operací než Read operací.
Je nutné zdůraznit, že CQRS není top level architektura, ale je často vhodná pouze na malou část aplikace.
Event Sourcing se velmi často používá pro implementaci Write (Command) části, ale není to pravidlo.
Co se týče použití PostgreSQL nebo jiné relační databáze, tak jediná odpověď je: "It depends..."
Vždy je potřeba si klást otázky.
Na jakou část chcete relační db použít? Write? Read? Obě?
Jaké množství dat budete zpracovávat?
Jaký výkon požadujete?
Jak budete jednotlivé části škálovat?
Jaké typy dotazů budete klást na Read část?
Relační db pro Write část:
Jedno z doporučení implementace Event Sourcingu zní: "Nepište vlastní Event Store"
Existuje spoustu řešení nad relačními (i jinými) databázemi a fungují dobře až do doby než se dostanete přes určitou hranici počtu událostí.
Lepší je použít specializované řešení, přece jen je to specifický způsob ukládání dat a specializovaný systém toho umí využít. Často také má implementovánu spoustu šikovných funkcí.
Tím nechci říct, že by se nedal napsat dobrý Event Store nad relační db. Jen je potřeba být připravený na možné problémy.
Na malém systému se s nimi často nesetkáte.
Relační db pro read část:
Tady myslím na problémy nenarazíte. Záleží spíše na typech dotazů. Někdy může být výhodnější použít NoSQL databáze, paměť nebo i něco úplně jiného.
Jinak příklad faktur je pouze vymyšlený příklad nebo něco reálného? Nenapadá mě důvod, proč by v běžné aplikaci měly být faktury implementovány pomocí Event Sourcingu.
Priklad faktur bol vymysleny. Dany pristup (teda event sourcing po spravnosti) pouzivame na viacere (ale nie na vsetky) veci v jednej casti systemu na spracovanie dat. Funguje vyborne a vcelku aj skaluje (dajme tomu nad jednym agregatom ~100k eventov mesacne). Na event store zvazujeme pouzitie kafka serveru, ale zatial vykonnostne postacuje aj postgresql tabulka.
Co sa tyka read casti, tak tam dost dodrzujeme to, ze data su ulozene vo formate/forme, v akom sa poskytuju dalej. Ziadne dohladavania/joiny. Nacitanie z postgresql je vzdy nacitanie jedneho riadku (json/text bunky vpodstate) a nasledne bud priamo preposlanie klientovi (dalsia interna aplikacia), alebo jemne upravenie/preformatovanie/osekanie v servise. Tu je samozrejme nutne ten json sparsovat a nasledne opat poskladat, ale povaha problemu dovoluje taketo zdrzanie. Ide skor o prietok a ten je mozne pekne skalovat pri dostatocnom pocte procesorov.
Zaujimalo by ma, ci je nejaka prakticka skusenost porovnavajuca napriklad updatovanie casu posledneho pristupu ku kontu poouzivatela (pouzivatel ako agregat) v QM perzistovanom v DB, kde by bol zvoleny json pristup verzus pristup relacnej databazy (napriklad 25 stlpcov, kde jeden je cas posledneho pristupu). Teda rozdiel vykonu pri updatovani jsonb hodnoty s 25 atributmi, verzus updatovanie jednej bunky v tabulke s 25 stlpcami. Je to horsie ako o jeden rad napriklad?
Dakujem za dodatocne informacie.
Na event store zvazujeme pouzitie kafka serveru, ale zatial vykonnostne postacuje aj postgresql tabulka.
Kafku sice moc neznám, ale nepřijde mi jako vhodné řešení pro Event Store
(ale vím, že ji někteří používají a v dokumentaci byla o Event Sourcingu zmínka)
Problémy, které vidím:
Zkuste se podívat na Event Store
Pro toto existují zvláštní databáze, ale zkušenost s tím nemám. Každopádně hledání dle klíče je základním požadavkem pro dokumentové, key-value i relační DB, se samotným typem DB to tedy příliš nesouvisí, podstatné je, že nejvýhodnější uložení dat je dáno požadovaným použitím.
Jediná použitelná specializovaná databáze pro Event Sourcing (nejen pro něj) je Event Store (o dalších alespoň nevím). Používám ji bez problémů.
Na Lambda meetupu jsem měl na toto téma prezentaci (je tam i odkaz na video)
https://www.meetup.com/Lambda-Meetup-Group/events/220671173/
NEventStore databáze není, je to jen implementace Event Sourcingu nad běžně dostupnými databázemi.
ta disputace Palo versus zbytek sveta (pan Jirsak) mi prinutila k tomu take neco rici.
Predne tedy musim priznat, ze se mi nazory slovenskeho kolegy libi. Zvlaste, kdyz vyslovil nasledujici:
....Pokud by měl přístup k databázi, tak nepochybně indexy správně navrhne" -> toto odporuje tomu co sam hovorite kedze vase konzultacie odhaluju tieto problemy aj v pripade cisteho SQL. Preco tito SQL specialisti nenavrhli dotaz a index spravne? Sam pisete ze sa s tym stale stretavate.....
Pan Stehule na to odpovedel v tom smyslu, ze se s problemy setkava u zacatecniku a .... u ORM. To vyzniva tak, jako kdyby nebylo ORM, tak je vetsina problemu s provozem praktickych aplikaci pod SQL hned pryc.
Tato odpoved se mi uprimne receno nelibi. My starsi budeme mit totiz uz brzy jubileum, bude to zhruba 20 let, co pan Stehule upozornuje na zacatecnicke chyby pri navrhu SQL. A tenkrat jeste zadne ORM systemy nebyly. Ten zavaznejsi fakt jsou ovsem ty desitky milionu dotazu na internetu k tem nejjednodussim problemum pri psani tech SQL prikazu? Ze by to vse bylo ORM. Vsechno jsou to zacatecnici?
Ja se obavam, ze se za temi problemy skryva neco jineho. Je to ta SQL sama, ktera nedovoluje tu delbu prace, o ktere Palo hovori. On nechce byt DB specialista Ma plne bryle svych starosti s pozadavky zakazniku, s aplikacni logikou. A proto s radosti sahne k nejakemu nastroji, ktery mu z DB udela nejaky blacbox, ktery muze pouzivat.
Naproti tomu reseni, ktere navrhuji Jirsakove (a neni to jen on, takovych je velka vetsina z tech, kteri se v IT pohybuji) je, aby vsichni k tem svym specialnim dovednostem jeste pridali tu DB specializaci.
Co kdybychom si po tech 20 letech snazeni pana Stehuleho priznali, ze tudy cesta nevede.
To: vsamfreak (neregistrovaný)
Tato odpoved se mi uprimne receno nelibi. My starsi budeme mit totiz uz brzy jubileum, bude to zhruba 20 let, co pan Stehule upozornuje na zacatecnicke chyby pri navrhu SQL. Co kdybychom si po tech 20 letech snazeni pana Stehuleho priznali, ze tudy cesta nevede.
Jenže tohle není problém jen SQL. Možná je špatně přístup k věci k mnoha různým oblastem - v tom případě budeme rádi, když navrhnete přístup lepší.
Sám za sebe vám můžu jmenovat třeba používání MD5 (na které už mám tak trochu OCD). Můžete jim to vysvětlovat horem spodem od rána do večera, pořád to budou používat.
Nebo třeba ifconfig na linuxu. Tisíckrát omílané téma, přesto se pořád objevují dotazy od začátečníků, kde směle dávají výpisy ifconfig a route. Odkud to berou já nevím.
Takže rozhodně není chyba na straně PS, ten se snaží to zvrátit. Stejně jako někteří ostatní se snažíme zvrátit jiné neřesti.
Je to trochu začarovaný kruh - pro některé lidi je SQL nepochopitelné, a proto jej nikdy nepochopí. Není to procedurální jazyk, typicky to není interaktivní prostředí. To pro některé vývojáře nemusí být jednoduché.
SQL je technologie - sama ničemu nebrání - nebrání dělbě práce - to je nesmysl.
Pokud programuji aplikaci, jejíž důležitou částí je databáze, tak musím rozumět databázím. Těm, které používám. Čím větší databáze, čím důležitější aplikace, tím musím těmto databázím rozumět lépe. Asi byste nechtěl jezdit autem, které navrhovali jen lidé přes design. U databázových aplikací Vám to nevadí?
Znalosti, které potřebujete, se dají naučit za týden. Za den základ. Dejte mi den, a já Vás to naučím.
Zase plácáte: Na RDB není nepochopitelné SQL, ale relační model, který se v životě moc ničemu nepřibližuje. Když se k tomu ve vývoji přidá ještě neexistence trasovacích nástrojů, primitivnost PL/SQL (např. omezené datové struktury, nutnost předávat složitější výsledky přes dočasné tabulky, ...), je programování RDB docela lopotné.
S Vámi se asi neshodnu - relační model - to je to nejstarší datové modelování - účetní knihy, atd.
PL/SQL - je ADA - programovací jazyk, ve kterém se píší kritické řídící systémy - co byste chtěl víc. Je to staticky typovaný jazyk - nemáte tam dynamiku Perlu, Pythonu - ale ani ji tam nechcete mít - chcete mít čitelná data za 10 let, takže dynamika je špatná a nechtěná.
> ... relační model - to je to nejstarší datové modelování ...
Pavle, tady bych si dovolil nesouhlasit. Hierarchický model je o pár let starší. Relační model ho následně drtivě převálcoval a díky tomu byl skoro zapomenutý.
Až v současné době se znovu vrací v podobě některých NoSQL databází. Je celkem vtipné, že se znovu vynalézá kolo a vývojáři se ani neobtěžují podívat, jak se to řešilo dříve.
Tady jsem neměl na mysli IT - ale realitu - někdy od renesance existují účetní knihy, ještě dříve se tesalo do kamene, škrábalo na destičky ...
Samozřejmě, že relační model je jeden z nejmladších - a to že všechny ostatní drtivě převálcoval - na tom není nic složitého - při optimalizaci se dá dobře využít rychlost sekvenčního čtení disků - což u těch starších modelů dost dobře nešlo - nebo to bylo příliš primitivní (Cobol).
Ja som asi dost konzervativny vyvojar a musim povedat, ze ORM nemam rad. Ak to niekto vyzaduje pouzit, tak nemame s tym problem, ale musime upozornit na nevyhody.
Podla mna je ORM iba urcity modny trend, ktory slubuje vela ale realita je ina ...
Je to podobne ako boli v rokoch 1990 rozne 4GL jazyky. Nieco si v tom rychlo napisal a vygenerovalo to zdrojak v 3GL a skompilovalo.
Problemy vzdy nastali pri rieseni chyb a nestandardnych situacii. Tam si musel debugovat ten vygenerovany kod v 3GL, takze v podstate si sa musel okrem 4GL zaoberat aj 3GL. Cele to bolo na hov...
Jedine velmi male vyhody ORM vidim v tom , ze to za mna porobi administrativne veci ako:
try {} catch {}
rs.close();
stmt.close();
conn.close();
zdrojak DAO, ktory vytvorim bude mozno cez ORM o 1/2 kratsi
Ale ake to prinasa nevyhody ?:
* Som zavisly na cudzom a nestandardnom API/frameworku
* Riesenie chyb je komplikovane - t.j. ked mam v JDBC ten retazec s SQL-prikazom, viem ho 1:1 preniest na SQL-konzolu a verifikovat. Pri ORM je to o dost tazsie oddebugovat a vyriesit to.
* Co mam z toho, ze narobim tie DAO cez ORM rychlo a potom budem v nich dlhodobo riesit chyby, preco nedavaju vysledky ako boli pozadovane ?
Je jednoduchsie vysvetlit programatorom, ze maju v JDBC vzdy robit:
rs.close();
conn.close();
ako riesit nasledky pouzitia ORM.
Neviem si predstavit, co by to boli za programatori, keby im JDBC robilo problemy, ze nevedia pochopit trochu SQL.
A uplne sa stotoznujem s vyrokom P. Stehule: "Tím, že je programátor odtržený od databáze, tak nemá ani šanci se databáze naučit - pochopit ji, uchopit."
Chceme, aby programator nic nevedel o databazi ? Ja to tak nechcem! Som toho nazoru, ze ked niekto nieco pouzivam musim tomu aj rozumiet.
To je zase snůška nesmyslů:
> Som zavisly na cudzom a nestandardnom API/frameworku
Takže komunikaci s databází si píšete zvlášť? Nebo používáte "cizí a nestandardní" JDBC? Pokud JDBC, tak čím je cizejší a nestandardnější než třeba Hibernate?
> Riesenie chyb je komplikovane - t.j. ked mam v JDBC ten retazec s SQL-prikazom, viem ho 1:1 preniest na SQL-konzolu a verifikovat. Pri ORM je to o dost tazsie oddebugovat a vyriesit to.
Zkopírovat SQL z debug logu ORM je "kompikované"? I když pro vás možná ano; lecos by to vysvětlovalo.
> Co mam z toho, ze narobim tie DAO cez ORM rychlo a potom budem v nich dlhodobo riesit chyby, preco nedavaju vysledky ako boli pozadovane ?
Pokud píšete DAO s chybami a neumíte je efektivně opravovat, není to problém ORM.
> Tím, že je programátor odtržený od databáze, tak nemá ani šanci se databáze naučit - pochopit ji, uchopit.
A co se programátor naučí a co pochopí o databázi při opakovaném rutinním lopatování dat tam a zpátky? Vůbec nic. ORM framework tyhle nudné a stále stejné části udělá za něj a on se může věnovat těm složitějším věcem. Takže se s ORM frameworkem klidně může naučit víc.
Já dělám projekty, malé i velké, kde se používá ORM framework (Hibernate) a mám i (středně velký), projekt, kde se ORM dělá ručně za použití přes Spring JDBC. A pokaždé když u něj sahám do DAO a musím ty primitivní věci psát ručně si říkám jak jsme byli blbí, že jsme ho na začátku nepostavili nad Hibernate. Na projektech kde Hibernate používáme s tím žádný problém není.
" ORM framework tyhle nudné a stále stejné části udělá za něj"
Prave ze neudela, a vazne chci videt, jak bude nekdo ladit nejaky query, kdyz libovolna zmena v kodu zmeni i ten dotaz a to klidne i drobna zmena pomerne razantne.
Zjevne ty projekty ktere delate jsou pidiprojekty, takze hruba sila to proste nejak utluce.
" ze nevedia pochopit trochu SQL"
kde je hranica medzi 'trochu SQL' a 'vela SQL'?
Ja nechcem aby .NET/Java programator riesil a optimalizoval stored procedure v Oracle - to nie je jeho job.
"Chceme, aby programator nic nevedel o databazi ? Ja to tak nechcem! Som toho nazoru, ze ked niekto nieco pouzivam musim tomu aj rozumiet."
ja nechcem aby .NET/Java programator riesil specifika databazy XYZ verzie a.b.c
chcem aby dostal data a spravil s nimi co ma
"Bohatě bude stačit, když bude znát základní principy, které jsou pro většinu relačních databází stejné a více-méně v čase jsou konstantní."
Zakladne principy pozna ORM velmi dobre - presne na to je to vymyslene. Aby ORM pokrylo genericke, opakovane Select, Insert, Update.
A na specializovane 'ficury' programatorovi zakladne principy prave stacit nebudu.
A ja s tim souhlasim. I kdyz musim priznat, ze jedine "ORM", ktere jsem poznal, je DAL ve web2py a SubSonic v .Net. Nejsem zadny velky odobrnik na SQL, ale dost brzo jsem se dostal do situaci, kde moznosti tech dvou vyse uvedenych nestacily. Staci trochu komplikovanejsi select s nekolika joiny a je to v pytli. A pokud se to tvarilo, ze to je OK, tak stejne bylo potreba kontrolovat, jaky z toho vlastne leze SQL dotaz. Takze za nejdulezitejsi vec v techto dvou nastrojich povazuji moznost napsat surovy SQL dotaz.
Ze to pak vysledek namapuje na nejake objekty, to je prima, to nepopiram. Ale to uz je jen takova tresnicka na dortu. Za nejdulezitejsi povazuji, aby to melo dostatecne vyjadrovaci schopnosti a aby to generovalo optimalni SQL dotazy. Bez toho to nejde.
do urcite velikosti je asi nejlepsi databaze papirova sanonova kartoteka resp. telefonni seznam razeno podle abecedy dle prijmeni :)
vyhledavani sice jen podle prijmeni ale docela rychle :)
Pavel Stehule - kdyz rikate ze ty zaklady jsou na 1 den skoleni to by slo napsat do jednoho clanku ne ?
ja bych to potreboval na konkretnim priklade nejlepe na zaklade analogie s tou papirovou kartotekou ostatne paper dbms napriklad v lekarskych ordinacich stale jedou ...
V těch článcích, co jsem napsal pro root je všechno, stačí si je přečíst.
Pro vysvětlení během jednoho dne potřebuji oční kontakt - každý člověk má trochu jiné znalosti, rozumí (bere) jiné trochu jiné vysvětlení, analogie - je to krásně vidět na tváři, jestli podání informace člověk bere nebo ne. A to, co je důležité se nesmí přeskočit.
Ta papírová kartotéka je ekvivalent databáze - v podstatě tak jak je, je to dokumentová databáze. Na to, aby z toho byla relační databáze musíte ubrat jednu dimenzi - představte si, že nebudete mít karty, ale deníky - několik deníků, kam připisujete informace - to je analogie tabulek. A pak máte speciální karty, které obsahují navigaci do deníků - analogie indexů. Díky tomu, že informace se zapisují jenom ve 2D - resp 1D záznamů, tak máte extrémně jednoduchý stabilní formát, který se velice snadno a velice rychle zpracovává strojově.
Nejprve bych rád poděkoval za pěkný a erudovaný článek. Jen mě celkem podráždila věta "Co mne zaráží, je neaktivita vývojářů – přidat index je práce na deset minut, a zrychlení aplikace může být neuvěřitelné.".
Problém je v tom, že onen vývojář často aplikaci neprovozuje a ostatně by to tak i mělo správně být. Může samozřejmě udělat syntetické testy a navrhnout nějakou základní sadu indexů, určitě by neměly chybět indexy na referenční integritu apod., ale od finálního indexování je tu databázový administrátor. Od vývojáře se ani nedá očekávat stejná úroveň zkušeností s laděním výkonu, jako od administrátora. Optimálně by ale měli spolupracovat.
Kolik firem má databázového administrátora?
Vím, že se vývojáři nedostanou na produkci, a tam by se většinou dostat neměli - ale měli by být nastavené procesy tak, aby se potřebné informace dostaly k vývojářům zpátky, a vývojáři by je měli požadovat. Bez toho se databáze nemůžou dělat pořádně.
Koneckonců o tom bude další díl -tímto dílem jsem si jen připravoval půdu.
Musím říct, že teď jste mne docela překvapil. DB adminy měli zatím všichni moji zákazníci, většinou jich měli několik. A co si nevydupu, to zásadně nemám (myšleno performance data), navíc pokud nejde vysloveně o havarijní stav, tak je s každou i triviální změnou či žádostí o data potřeba projít schvalovacím procesem a počkat na nějakou formu servisního okna. Když nemám u zákazníka vybudované dobré vztahy, může jít klidně i o půl roku. V případě prostého indexu by se to asi podařilo ukecat i bez dobrých vztahů, ale pořád se pohybujeme v reakční době v řádu týdnů. Pokud to nepřijde jako žádost o schválení vytvoření nového indexu od aktivního admina, tak je to většinou v háji.
S dbadminy se setkávám u velkých firem s klasickým IT (jinak je často outsourcovaný) a u Oracle. U OS databází je to těžká výjimka (případně se za dbadmina považuje člověk, který má práva, ale většinou nemá znalosti). Na základní provoz těchto databází většinou nepotřebujete žádné znalosti a firmy na to pečou.
Vývojáři málokdy vědí, co chtít. Uživatelé málokdy vědí, co dát. Pak většinou, při prvních problémech se to povede nějak dořešit. Dneska už taky hromada developerů rovnou provozuje aplikace, takže potřebná data by mohli mít kdykoliv, kdyby je chtěli.
Jenze vyvoj neni ladeni. Neco jinyho je, kdyz firma pouziva nejaky specificky postup, a na ten se ladi vykon databaze, a neco jinyho, kdyz v databazi nejsou ani indexy na klicich.
Pro predstavu, v systemu je prehled dat, kterej otevre kazdej uzivatel tisickrat denne. Prehled se nad dostatecne velkou databazi otevira klidne i minuty vs mene nez sekundu. To nema nic spolecnyho s nejakym ladenim, to je neschopnost vyvojare.
Nemluve o tom, ze s blbe navrzenou databazi ani ty indexy nic nenadelaj. Krasnej priklad je treba to, ze system generuje logy v takovym mnoztvi, ze je nestiha ani odmazavat - za dobu smazani jednoho zaznamu jich vytvori 10.
Já bych taky rád Pavlovi poděkoval za zajímavé články a za snahu pomoci i někomu dalšímu.
Sice jsem s db už delší dobu nic (pracovně) nedělal, vždycky si rád přečtu každý jeho článek.
Jednak si tím alespoň trochu refreshnu, co jsem kdysi uměl, a jednak se rád dozvím, "co a jak", "co a jak ne-e" a "co je nového".
Takže ještě jednou - díky.
(a ať se daří)
„...ale od finálního indexování je tu databázový administrátor...“
Týjo, tak asi tomu moc nerozumím, ale měl jsem za to, že návrh databáze je součástí systému a vývojář by měl vědět, co s tou DB bude dělat, a tedy kde se index vyplatí a kde je na hovno. Aby do toho drbal nějaký chlápek jen podle toho, že se mu zdá, že někde něco jede pomalu, mi přijde docela drsné...