Zobrazit příspěvky

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


Příspěvky - Filip Jirsák

Stran: 1 ... 147 148 [149] 150 151 ... 375
2221
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 14. 10. 2019, 20:57:14 »
:) jenže to jsme pořád u toho samého. Pokud si "SELECT * FROM tbl1 LEFT JOIN tbl2" vyčleníte do VIEW, můžete pak s tím samým VIEW pracovat všemi způsoby. Třeba tím, že do WHERE doplníte allowed > 0, nebo že tbl2.id_data IS NULL.

Je pochopitelně dost účelné mít jedno VIEW a pracovat s ním jen v podmínce.
Když jsem psal o tom CROSS JOINu všech tabulek, myslel jsem to ironicky. To nebyl návod, že se k tomu máte snažit přiblížit…

Já osobně dělám pohledy na data, která dávají nějaký smysl. Pokud dává smysl spojit tbl1 s existujícími řádky v tbl2, udělám si na to pohled. Pokud dává smysl ty tabulky spojit, ale ignorovat neexistenci záznamů v tbl2 a prostě místo nich doplnit NULL hodnoty, udělám si na to pohled. Pokud dávají smysl oba dva přístupy, udělám dva pohledy. Vy za každý vytvořený pohled platíte, nebo proč je pro vás tak důležité, že je ten pohled jeden a ne dva? Navíc se ty dva pohledy používají v různých situacích, takže se mi to krásně oddělí. Dost možná ty pohledy budou mít i jiné sloupce nebo dokonce připojené jiné další tabulky. Kdyby to vše nacpal do jednoho pohledu, budu muset navíc v aplikaci k tomu jednomu způsobu použití muset všude přidávat podmínku (proč? přesně k tomu přece mají sloužit pohledy).Nedej bože, abych u jednoho způsobu použití potřeboval něco změnit – jiné sloupečky, připojit další tabulku… Pak stejně budu muset projít celou aplikaci, najít všechna místa, kde se ten pohled používá, zjistit, že je to způsob použití 1 nebo 2 a pak to budu moci konečně slavnostně rozdělit na dva různé pohledy.

Obzvlášť zábavné to vaše řešení bude tehdy, když optimalizátor nezvládne nad tím vaším view udělat predicate push a vy donutíte databázi přečíst celou velkou tabulku, ze které by vám normálně INNER JOIN vybral pár záznamů podle indexu.

2222
Na jaké produkci? Já nejsem produkční studio!
„Produkce“ je v IT slangové označení pro „produkční prostředí“, nebo také „ostré prostředí“ – prostředí, kde aplikace běží „na ostro“, připojují se k ní reální uživatelé, má reálná data atd. Tedy např. i ta vaše aplikace na free webhostingu. Vedle toho pak mohou existovat různá nedůležitá nebo méně důležitá prostředí – vývojová, testovací, integrační, akceptační apod.

Zrovna problémy s konkurenčním přístupem se často vyskytují až od určitého množství současně pracujících uživatelů. Pokud řešíte webhosting zdarma, asi nebudete mít testovací prostředí, kde byste věrohodně simuloval souběžnou práci většího množství uživatelů. Takže na problémy se špatně napsaným konkurenčním přístupem můžete narazit až na ostrém serveru – až se vám začnou ztrácet data nebo se vám datový soubor poškodí.

Jak jsem psal, databázi určitě použiju, to jsem si už vyjasnil, ale rozhodně ne na ptákoviny jako je registrace a loginy, to zvládnu přes soubory […] Tady jednu kravinu abych programoval dva tři měsíce.
Pokud si pro prkotiny jako registrace a loginy budete programovat vlastní databázi, opravdu vám to bude trvat dva tři měsíce, klidně i déle. Pokud se na tom budete metodou pokusu a omylu učit, jak se pracuje se soubory při konkurenčním přístupu a jak se zamykají, bude vám to trvat podstatně déle, než tři měsíce. A možná nakonec zjistíte, že když budete zamykat celé soubory, už s malým množstvím uživatelů na freehostingu narazíte na limity v počtu souběžně otevřených souborů nebo doby zpracování skriptu.

A k tomu hostingu zdarma – slušný webhosting seženete už okolo 50 Kč za měsíc. Už jenom psaním těch podivuhodných testů jste propálil tolik času, že byste za to tu aplikaci provozoval několik let.

2223
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 14. 10. 2019, 17:03:03 »
A pak někdo do toho WHERE dá takovouhle podmínku:
Kód: [Vybrat]
SELECT * FROM tbl1 LEFT OUTER JOIN tbl2 USING (id_data) WHERE tbl2.allowed IS NULL

Pokud dáte podmínku WHERE allowed > 0, pak Vám to tyto záznamy přirozeně nevrátí.
Ta podmínka je o dva komentáře výš, sám jste ji ve svém předchozím komentáři citoval. Mám pro vás tip – když píšete komentář, na stránce níž jsou předchozí komentáře v diskusi. Abyste ze sebe neudělal hlupáka, bývalo by stačilo odrolovat o jednu obrazovku dolů.

Jedná se o (primární / vzdálený) klíč. Ten může mít buďto hodnotu a dojde k joinu, nebo nedojde k joinu a pak záznam neexistuje. NULL v klíči má jasně daný význam. U ostatních sloupců, mimo klíčů platí to, co píšete.
Pro neexistenci záznamu platí to samé, co pro NULL. Není to stejná hodnota, jako kterákoli jiná, je speciální –ostatně i proto se při OUTER JOINu neexistující záznamy mapují právě na NULL, což je jiná speciální hodnota. Pokud chcete v SELECTu říct, že vás neexistující záznamy nezajímají, uděláte to právě pomocí INNER JOINu. Tím si zajistíte, že se ty neexistující záznamy ve výsledné sadě ani neobjeví, tím pádem není nutné je mapovat na NULL a tím pádem ani nemusíte NULL hodnotu řešit.

2224
Flock sice spolehlivý je, ale nezaručuje že mezi otevřením a flockem se k souboru, nedostane jiný proces.
To je naprosto normální, takhle se budou chovat všechny synchronizační mechanismy. Vždy je to založené na tom, že se pokusíte udělat nějakou exkluzivní akci, vyhodnotíte výsledek a zjistíte, zda se podařila, nebo zda perníček loupe i někdo jiný a musíte chvilku počkat a zkusit to znovu.

flock neselhal ani jednou, vždy byl výsledek true.
Když chcete jako programátor řešit paralelní přístup k datům, tohle nemůžete nikdy napsat. To, že se vám nepodařilo nějaký souběh nasimulovat, vůbec neznamená, že nenastane hned při prvním spuštění na produkci.

A co takhle zkusit vyrobit jiný typ zámku, který by byl spolehlivější.
Dám vám dobrou radu. Nepokoušejte se vymýšlet vlastní zámky, v tuto chvíli na to nemáte znalosti. Použijte nějakou běžně používanou databázi, která už má tyhle nízkoúrovňové věci vyřešené. Tam můžete studovat třeba to, jak fungují ACID transakce, jak jsou od sebe izolované – a na základě toho si začnete pomalu budovat představu o tom, co se může dít, když se stejnými daty pracuje několik programů nebo vláken souběžně.

Takže až vyřešíš problémy se zamykáním souborů, přejdi na databázi.
Takhle to nebude fungovat, jedině opačně – nejprve se naučit používat prostředky databáze, které jsou jednodušší, a teprve pak se případně dostat k souborům.

2225
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 14. 10. 2019, 16:37:48 »
Ano, ale přesně o to jde, aby mohl udělat. Tedy vyselektovat si záznamy, ke kterým není právo "allowed" explicitně dané.
Mně na tom teda poněkud vadí, že je ten dotaz špatně. Chtěl jsem záznamy, které v tbl2 existují a mají tam allowed IS NULL, ale vrátilo mi to i záznamy, které v tbl2 vůbec neexistují.

Jako další příklad toho, co může dávat smysl je dotaz:
SELECT  * FROM tbl1 LEFT OUTER JOIN tbl2 USING (id_data) WHERE tbl2.id_data IS NULL OR tbl2.allowed = 0
Pokud často píšete dotazy, ve kterých neexistence záznamu nebo NULL hodnota má stejný význam, jako nějaká jiná hodnota, tedy vyskytují se vám tam konstrukce … IS NULL OR … , je to známka toho, že máte špatně navrženou strukturu databáze. NULL není jedna z mnoha hodnot, NULL je speciální hodnota, výjimečná – proto se s ní nepracuje pomocí běžných operátorů = nebo !=, ale má speciální operátory; proto je „nakažlivá“ a když se objeví u běžných operátorů, je na výstupu zase NULL

2226
Myslel jsem to tak, jak se píše v tom odkazu, tzn. že mezi fopen a flock se může dostat jiný proces.
To ale neznamená, že flock() není atomický.

Pokud bych to tedy měl říci přesně, tak flock() je atomická funkce, ale ke svému využití potřebuje fopen(), a spojení fopen()+flock() atomické není.
To, že volání dvou funkcí po sobě není atomické, je naprostý základ. Bez pochopení téhle věci je zbytečné pokoušet se programovat cokoli se zámky nebo řešit nějakou atomicitu.

2227
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 14. 10. 2019, 10:09:28 »
Co prosím? Já tvrdím, že správně napsaný skelet dotazu je takový, kde se podmínka "metá" jen do WHERE a nemusí se nic dalšího měnit. Takový skelet lze zobecnit do VIEW a pak pracovat jen nad ním.

A pak někdo do toho WHERE dá takovouhle podmínku:
Kód: [Vybrat]
SELECT * FROM tbl1 LEFT OUTER JOIN tbl2 USING (id_data) WHERE tbl2.allowed IS NULL

Případně to udělá nad tím view – ideálně, když k tabulce ani nebude mít přístup. To už pak tu vaši chybu s použitím chybného JOINu ani v SELECTu neopraví. I když ve výsledku by to asi bylo dobře – konečně by opravil ten váš JOIN v pohledu na správný INNER JOIN.

2228
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 14. 10. 2019, 09:27:49 »
Aha, tak zde je ta chyba, kterou děláte. V tomto případě žádnou podmínku navíc nepotřebujete. Stačí bohatě
SELECT * FROM tbl1 LEFT OUTER JOIN tbl2 USING (id_data) WHERE tbl2.allowed > 0.

Pokud nedojde k joinu, pak nebude ani splněná podmínka tbl2.allowed > 0.
Aha, takže to vaše „dotaz má být co nejvíce univerzální“ znamená, že tam ty podmínky pokaždé budete psát úplně od začátku. Čím dál lepší.

2229
Myslím, že flock není atomický - https://www.reddit.com/r/PHP/comments/9ec4tz/a_locking_file_cache_in_php/e6cqg19/
Mohl byste to rozepsat? Atomicita znamená, že se daná funkce provede celá nebo vůbec a že nikdo nemůže vidět nějaký vnitřní mezistav té funkce. V případě zámků atomicita znamená, že na souboru nějaký zámek je nebo není – nemůže nastat stav, že by tam zámek byl tak trochu. Atomicita se ale samozřejmě posuzuje z hlediska jedné funkce – to, že se něco může stát před voláním flock() nemá na atomicitu funkce flock() vliv.

2230
Čím si vysvětluješ, že ani flock nepomůže k zajištění atomicity?
Připadá mi, že se snažíte testovat nějaké bufferování nebo co, ale přitom máte zmatek v tom, co je atomicita a jak se používají zámky. Zámky nezajišťují atomicitu – zajistí jenom to, že ze/do souboru může současně číst/zapisovat jenom jeden proces. Nezajistí ale, že ten zápis bude atomický. Navíc vůbec nepředpokládáte, že získání zámku může selhat, ani že může selhat otevření souboru – myslím, že zrovna v těchto případech je to dost odvážný předpoklad.

2231
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 14. 10. 2019, 07:45:42 »
Požadavek byl na to vyhledat záznamy v tbl1, které mají v tbl2 odpovídající záznam a tbl2.allowed > 0.
Požadavek byl jiný, přečtěte si to v prvním příspěvku.

Tedy INNER JOIN i OUTER JOIN navrátí v tomto případě stejný výsledek.
Takhle napsané to vypadá, že oba JOINy se stejnou podmínkou vrátí stejný výsledek. Jenže to není pravda, u OUTER JOINu musíte do filtrovacích podmínek přidat i tu podmínku, která z něj udělá INNER JOIN. Obecně samozřejmě každý INNER JOIN jde napsat pomocí OUTER JOINu tím, že přidáte další podmínky. Obšem jak bylo vidět v této diskusi, není to vždy snadné…

2232
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 13. 10. 2019, 12:07:57 »
Pře je pouze o tom, jestli je dobré přemýšlet trochu dopředu a tvořit s k takovému přemýšlení návyk.
Nikoli, tohle je pouze vaše demagogie. Na tom, že je potřeba přemýšlet trochu dopředu, se shodneme. Neshodneme se na tom, co máme ve předu očekávat.

Chápu kam míříte, ale zkoušíte to trochu demagogicky. Hlavní entitou dotazu je tbl1, z ní se čerpají informace. V tbl2 je pouze přívěsek, který existovat může a nemusí. Takže nemůžete z tbl2 najednou udělat hlavní entitu.
Že je tbl1 hlavní entitou dotazu se z uvedené databázové struktury pozná jak? Když budu mít tabulku entit a vedle ní číselník, v té tabulce entit záznamy mohou existovat a nemusí, zatímco číselník bude vždy úplný.

2233
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 13. 10. 2019, 10:58:53 »
Jen je to špatně navržené.
Na tomhle dotazu se evidentně neshodneme. Jak by tedy podle vás vypadal správně navržený SELECT pro tohle zadání?

Chci všechny záznamy z tbl2, které mají allowed > 0, a k nim připojit odpovídající záznam z tbl1. Pro každý záznam z tbl2 existuje záznam v tbl1.

2234
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 12. 10. 2019, 12:21:36 »
Asi to neumím napsat, abyste mě pochopil. Nemyslím strukturu dotazu, ale strukturu databáze. Ta byla popsána tak, že v tbl2 může a nemusí záznam existovat.
Já to chápu, problém vidím spíš v tom, že píšete obecně o jakési struktuře databáze, ale nenapsal jste, co konkrétně to znamená. Jak mají vypadat tabulky, jaké na nich mají být FOREIGN KEYS nebo jiná omezení?

Navíc to pokládám za nesmyslné, SELECT popisuje výsledná data, ne strukturu databáze. Může dávat smysl nad jednou dvojicí tabulek dělat INNER JOIN i OUTER JOIN, protože to má pokaždé jiný význam – i když struktura tabulek bude pořád stejná.

Jsou situace, kdy máte obecně definováno, že záznam musí existovat. Např. na dokladu uvedený odběratel (tabulka odběratelů však slouží více účelům), nebo vazba na číselníky (opět využívané z více míst). Tam je INNER JOIN na místě.
Nezapomněl jste na to, že INNER JOIN je symetrický a nerozlišuje levou a pravou tabulku? Co kdyby tazatel přeformuloval svůj požadavek na: „Chci všechny záznamy z tbl2, které mají allowed > 0, a k nim připojit odpovídající záznam z tbl1. Pro každý záznam z tbl2 existuje záznam v tbl1.“ Struktura tabulek zůstává stejná. Výsledná sada záznamů zůstává stejná. Množiny správných SQL dotazů pro obě varianty formulace zadání jsou identické. Jenom podle vašich pravidel je najednou správně INNER JOIN. Přitom zároveň tvrdíte, že rozhodnutí, zda INNER nebo OUTER JOIN závisí na struktuře tabulek, ne na sémantice dotazu (myslím toho formulovaného přirozeným jazykem, ne SQL).

Pokud tedy tazatel napsal, že v tbl2 nemusí záznam být - pak je tato skutečnost nějak významná (něco vyjadřuje).
Pokud by ta skutečnost byla významná, napsal by explicitně, jak se má zacházet s neexistujícími záznamy v tbl2. Racchek to ale napsal jako chápavý student – sám to nepovažoval za důležité, ale uvědomil si, že se v oblasti neorientuje natolik dobře, aby to dokázal sám posoudit. Proto uvedl i tuhle informaci, o které si myslel, že je nadbytečná (proto ji neformuloval úplně přesně). Uvedl ji jen pro jistotu, kdyby to náhodou mělo vliv, aby s tím mohli znalejší lidé pracovat a upozornit ho, že na tom záleží.

Pokud tento stav zakryjete INNER JOINEM, můžete zaplakat nad výdělkem. Bohatě stačí, aby chtěl Racchek vybrat záznamy které mají allowed=0 NEBO nemají odpovídající záznam, a už je v háji a bude přepisovat nejen podmínku, ale i JOINY.
Ano, když se změní pravidla spojování, musí se přepsat JOINy. Když bude chtít tbl1 spojit s tabulkou tbl3, bude také muset přepsat JOIN. Výhoda je, že jsou pravidla pro spojování uvedena jinde, než podmínky, takže se to navzájem neplete.

SQL je velmi chytře navržené, ne nadarmo jsou HAVING, WHERE a ORDER BY až na konci - v nich se máte rejpat. Co je nad nimi má být co nejvíc zobecněné.
Ano, SQL je chytře navržené, proto odděluje spojovací podmínky od filtrovacích. Akorát vy se bůhvíproč snažíte spojovací podmínku nacpat do filtrovacích, i když to tazatel v původním dotazu velmi viditelně oddělil. Resp. Racchek dotaz formuloval tak, že ani nic jiného, než INNER JOIN nepředpokládal – dokonce ani první diskutující nenapadlo, že by to mohlo být i jinak. Teprve pak se někdo začal zabývat tím dovětkem, že v tbl2 záznamy nemusí existovat, a začal řešit, zda to je nebo není důležité. Racchek tenhle dovětek mezi podmínkami vůbec neuváděl, evidentně to tedy nevnímal jako podmínku, ale jako přirozený důsledek spojení.

Dotaz je zobecněný, pokud JOINovací podmínky máte u JOINu a ne ve WHERE. Když nacpete JOINovací podmínku do WHERE, musíte na to myslet při každé změně WHERE, pořád si musíte hlídat, abyste tu podmínku do WHERE připojil správně. Dotaz je zobecněný tehdy, pokud ve WHERE necháte opravdu jen filtrovací podmínky. Když jsem potřeboval spojit tbl1 se záznamy z tbl2, které mají kategorie=1 (právě takhle bylo formulované zadání – že se spojuje s podmnožinou druhé tabulky), dal jsem i tu podmínku na kategorie=1 do JOINu. Aby všechny spojovací podmínky byly u JOINu a já nemusel hlídat, že je správně přilepuju ke každému možnému WHERE. Dokonce možná z toho JOINu následně vznikl pohled, tím už si nejsem jistý.

2235
Vývoj / Re:MySQL - podmíněný SELECT přes dvě tabulky
« kdy: 12. 10. 2019, 11:21:39 »
Ne. Struktura dat je dána databází (její zamýšlenou interpretací). Struktura se nemění dotaz od dotazu. Ve správném návrhu by měla být vyjádřena i správně postavenými FOREIGN KEYS.
Opakuji ještě jednou – tady je struktura dat taková, že se zabýváme jenom záznamy existujícími v tbl2.

Existence záznamu je tacitní podmínkou dotazu. Pokud musí existovat allowed > 0, implikuje to existenci záznamu v tbl2.
Děláte přesně to, před čím jste varoval – snažíte se JOIN převádět na WHERE. Tyhle tacitní podmínky právě popisují způsob spojování tabulek. Proto se v SQL dotazu píšou zvlášť a je na ně speciální syntaxe – JOIN.


Vy jste mu zodpovědel dotaz jen pro jeho jeden speciální případ, ale už jste vůbec nepřemýšlel, že v praxi se podmínky parametrizují.
Právě naopak, já jsem popsal takový dotaz, kde jsou ve WHERE všechny podmínky a není tam nic jiného, než podmínky. Ty si může tazatel parametrizovat a upravovat jak je libo, a nemusí pořád myslet na to, že tam musí přidávat ještě spojovací podmínku – protože tu má správně uvedenou u JOINu.

Panu kolegovi, který se učí, a který potřebuje vytvořit správné návyky, jste poradil pěknou blbost, která mu jednou zkomplikuje život.
Nezlobte se na mne, ale blbosti tu píšete vy. Neustále naznačujete, že INNER JOIN by se měl používat jenom tam, kde obě tabulky obsahují identickou sadu entit, akorát ke každé jedné entitě nesou jinou sadu vlastností. Že se INNER JOIN vůbec nemá implementačně lišit od OUTER JOINu, nýbrž že je to jenom komentář pro databázového specialistu, který mu říká „obě tabulky mají stejný počet záznamů, které si navzájem odpovídají“, resp. „vlastně by to měla být jen jedna tabulka, ale z nějakého důvodu je rozdělená na dvě“. V obou tabulkách by tedy mělo být nastavené FOREIGN KEY na tu druhou tabulku. Pokud by byl INNER JOIN přes více tabulek, muselo by to platit pro všechny a FOREIGN KEY by zřejmě měly mít každá s každou.

Pak by mne ale zajímalo, jak odůvodníte, proč jsou ty záznamy ve více tabulkách, proč to není jedna tabulka.

Pouze ale jeden z těchto dotazů je sémanticky správně.
Ano, ten první. Všimněte si, že je to přesný přepis zadání: „z tbl1.id_data vybrat pouze to, co v tbl2 je jako allowed >0“. Když si tu českou větu přeložíte do angličtiny, máte už ten SQL dotaz vlastně hotový.

Stran: 1 ... 147 148 [149] 150 151 ... 375