Portál AbcLinuxu, 20. dubna 2024 00:28


Nástroje: Začni sledovat (3) ?Zašle upozornění na váš email při vložení nového komentáře.

Vložit další komentář
xsubway avatar 14.3.2010 15:45 xsubway | skóre: 13 | blog: litera_scripta_manet
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Odpovědět | Sbalit | Link | Blokovat | Admin
Sympatický projekt a stránky (napsané ve skvělé Lion wiki). Díky ;)
14.3.2010 16:08 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Odpovědět | Sbalit | Link | Blokovat | Admin
Je smutné, že ještě v roce 2010 někdo řeší přístup k databázi hackem s escapováním hodnot místo použití prepared statements, např. přes MySQLi.
14.3.2010 16:14 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Dovolím si tvrdit, že v MySQL nemají prepared statements příliš velký smysl:
  • Pro jeden dotaz je pouziti prepared statements pomalejsi nez jejich nepouziti
  • Pokud potrebujete vykonat stejny dotaz vicekrat, jen s odlisnymi parametry, pak mate z 95% pripadu spatne navrzenou aplikaci/dotazy.
  • I v tech 5% pripadu je v MySQL vykonnostni benefit prepared statements dost maly
14.3.2010 16:19 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Předpokládám, že první MySQL mělo být PHP a druhá odrážka pak vychází z předpokladu, že si PHP dotazy nenakešuje (pořád ještě to může udělat server).

Zabránění SQL injection (tedy pokud si někdo stejně nenacpe uživatelský vstup i do prepared statements) mi připadá jako dostatečně dobrý důvod pro použití prepared statements.
14.3.2010 16:31 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Předpokládám, že první MySQL mělo být PHP

Tohle nechápu. První dvě odrážky jsou obecné a platí pro prepared statements na všech databázích. Třetí platí čistě pro MySQL, protože výhody prepared statements dostatečně nerealizuje. PHP s tím nemá nic společného.

že si PHP dotazy nenakešuje (pořád ještě to může udělat server)

Tohle opět nechápu - na co vám bude, když si dotaz nacachuje PHP? (ať už s nebo bez prepared statements)

Pokud spouštíte řadu dotazů
SELECT * FROM users WHERE id = 1
SELECT * FROM users WHERE id = 2
SELECT * FROM users WHERE id = 3
SELECT * FROM users WHERE id = 4
SELECT * FROM users WHERE id = 5
...
tak vám cachování v PHP na nic není, serveru to samozřejmě v tomto triviálním případě pomůže, ale síťové komunikaci se nevyhnete.

Zabránění SQL injection (tedy pokud si někdo stejně nenacpe uživatelský vstup i do prepared statements) mi připadá jako dostatečně dobrý důvod pro použití prepared statements.

Query2 samozřejmě poloautomaticky řeší SQL injection (oním escapováním). Na rozdíl ale od prepared statements dokáže vložit i už escapovaný řetězec (ano, i to je občas potřeba). S použitím prepared statements byste musel řetězec jaksi odescapovat ...
14.3.2010 16:41 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Prepared statements nemusí být pomalejší – záleží na tom, co s nimi knihovna dělá. Druhá odrážka je v tom případě nesmysl – každá aplikace samozřejmě používá opakovaně ty samé dotazy jenom s jinými parametry. Serveru nakešovaný dotaz pomůže třeba takovou „maličkostí“, že může použít již hotový prováděcí plán a nemusí jej znova vytvářet.
Query2 samozřejmě poloautomaticky řeší SQL injection (oním escapováním). Na rozdíl ale od prepared statements dokáže vložit i už escapovaný řetězec (ano, i to je občas potřeba). S použitím prepared statements byste musel řetězec jaksi odescapovat ...
To je právě ono, někde se escapuje, někde se na to zapomene, někde se to udělá dvakrát… Proto to považuju za hack, ne za řešení.
14.3.2010 16:56 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Prepared statements nemusí být pomalejší – záleží na tom, co s nimi knihovna dělá.

Principiálně pomalejší být nemusí, ale v praxi pomalejší jsou.

Druhá odrážka je v tom případě nesmysl – každá aplikace samozřejmě používá opakovaně ty samé dotazy jenom s jinými parametry.

Mezi instancemi requestu souhlasím, v rámci jednoho requestu málokdy. Pokud vím, že něco budu potřebovat hodně často, udělám většinou jeden větší dotaz a mám to mnohem rychleji než s prepared statements. Samozřejmě to ale nejde (nebo z nějakého důvodu není vhodné) vždycky.

Serveru nakešovaný dotaz pomůže třeba takovou „maličkostí“, že může použít již hotový prováděcí plán a nemusí jej znova vytvářet.

No jistě, o tom není sporu. Problém ovšem je, že konkrétně MySQL této „maličkosti“ nedokáže až tak dobře využít. Co jsem slyšel, tak třeba v Oracle jsou prepared statements skoro nutnost, protože u triviálních dotazů sežere až 90% času ověřování přístupových práv a vytváření onoho prováděcího plánu.

To je právě ono, někde se escapuje, někde se na to zapomene, někde se to udělá dvakrát… Proto to považuju za hack, ne za řešení.

V Query2 je možný SQL injection úplně stejně jako u prepared statements:
// SQL injection není možný
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param($user_id);

$q->query("SELECT * FROM users WHERE id = %i", $user_id);

// Možný SQL injection
$stmt = $db->prepare("SELECT * FROM users WHERE id = $user_id");

$q->query("SELECT * FROM users WHERE id = $user_id");
Pokud se držíte standardního psaní dotazů (tedy data přes modifikátory), SQL injection v Query2 není možný.
14.3.2010 17:12 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Principiálně pomalejší být nemusí, ale v praxi pomalejší jsou.
To se ale týká jen MySQL, podobně jako to, že problém s vytvářením prováděcího plánu.
Mezi instancemi requestu souhlasím, v rámci jednoho requestu málokdy.
Proto jsem psal, že se to asi týká jen PHP. Jinak si aplikace samozřejmě může pamatovat připravený dotaz libovolně dlouho.
Pokud se držíte standardního psaní dotazů (tedy data přes modifikátory), SQL injection v Query2 není možný.
Pokud někde nepoužíváte escapování mimo tuto knihovnu. Pak ale tahle knihovna stejně jen obchází to, že prepared statements jsou (prý) v MySQLi pomalejší(což je taky divné, logicky znovupoužitelnost měla vést naopak ke zrychlení).
14.3.2010 17:19 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
To se ale týká jen MySQL, podobně jako to, že problém s vytvářením prováděcího plánu.

No jasně, ale Query2 podporuje jen MySQL, takže ostatní DB nás nezajímají.

Pak ale tahle knihovna stejně jen obchází to, že prepared statements jsou (prý) v MySQLi pomalejší(což je taky divné, logicky znovupoužitelnost měla vést naopak ke zrychlení).

To určitě ne. Query2 má mnohem větší záběr, ale na to si přečtěte tento článek nebo manuál na webu.

což je taky divné, logicky znovupoužitelnost měla vést naopak ke zrychlení

Jsem z vás jelen :D Vždyť jsme si už několikrát řekli, že při spuštění jednoho dotazu jsou prepared statements v MySQL pomalejší, při více dotazích mírně rychlejší než varianta bez prepared statements.
14.3.2010 17:32 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Abych to shrnul – i v roce 2010 se v PHP běžně u SQL dotazů používá escapování, z čehož vznikají problémy a zmatky (předčasné escapování, žádné či vícenásobné escapování). Do řešení, kterým jsou prepared statements, se moc nikdo nehrne, protože o tom za prvé mnoho lidí neví, a za druhé jsou údajně pomalejší (což je tedy zvláštní implementace). A to je na tom to smutné – že místo opravdového řešení se neustále dokola řeší, jak ten slepenec escapování alespoň trochu zkrotit. Máte pravdu, že pak je knihovna Query2 lepší než nic.
14.3.2010 17:40 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Jen na okraj: Query2 by šlo přepsat tak, aby využívalo prepared statements - a to dokonce transparentně, bez změny syntaxe a vědomí uživatele. Bylo by ale potřeba cachovat dotazy/statements a část kódu by se zkomplikovala a do toho se mi nechce - na Query2 se mi hodně líbí, že zdroják je jednoduchý a snadno pochopitelný. Když zvážím pro a proti, tak mi vychází, že se mi to nevyplatí ...
xkucf03 avatar 14.3.2010 17:52 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Smutné to je. I když se PHP postupně zlepšuje, bastliči přesto pokračují ve svých zajetých kolejích, jak se to naučili kdysi. S jistou dávkou nostalgie jsem si otevřel jednu školní aplikaci, kterou jsem psal před třemi lety – už tehdy bylo možné používat parametrizované dotazy (a dokonce takovou vymoženost jako je nezávislost na SŘDB – skoro jako JDBC v Javě – PDO v PHP).
function sqlDotaz($dotaz, $parametry = null) {
	try {
		$dotaz = $db->prepare($dotaz);
	
		if ($parametry != null) {
			for($i = 0; $i < count($parametry); $i++) {
				$dotaz->bindParam($i+1, $parametry[$i]);
			}
		}
	
		$dotaz->execute();
		$r = $dotaz->fetchAll();
	
		return $r;
	} catch (PDOException $e) {
		logujChybu("sqlDotaz($dotaz)");		
	}
}
Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
14.3.2010 19:20 Jiří Kocman
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Tak s tímhle názorem naprosto souhlasím. V Roce 2010 si dělat vlastní layer k DB, který je ještě závislý na konkrétní databázi... to asi člověk nemá nic lepšího na práci. Dnes je na světě PDO (už od PHP5.1) a v PHP6 to bude preferovaný způsob práce s databází. Podporuje vše potřebné a nedělá rozdíl mezi DB.

A co se týká rychlosti prepared statements. Ano pro MySQL jsou pro běžné query pomelejší, ale tak minimálně, že to nemá cenu řešit... Příklad 3000 dotazů nad stejnou (50MB) tabulkou:
------------- mysql ---------------
elapsed time: 1.03722381592
------------- mysql pdo ---------------
elapsed time: 1.04643011093
elapsed time prepared, parsing: 1.07211589813
elapsed time prepared, one time parse: 1.03426194191
------------- mysqli ---------------
elapsed time: 1.3649790287
elapsed time prepared, parsing: 1.40571093559
elapsed time prepared, one time parse: 0.898549079895
Ty rozdíly nejsou nijak extrémní... MySQLI je hodně rychlé pokud se jedná o opakované dotazy, jinak je docela pomalé - no, nejpomalejší ze všech možností přístupu k MySQL...

A teď příklad kdy prepared statements opravdu něco znamenají:
-------------oracle pdo ---------------
elapsed time with flushed shared pool: 3.47801780701
elapsed time with shared pool: 0.90004491806
elapsed time prepared flushed shared pool, parse each: 0.939059972763
elapsed time prepared, parsing: 0.884253025055
elapsed time prepared, one time parse: 0.42867898941
Pro jistotu jsem udělal 3000 dotazů s vyprázdněným shared poolem a s již naplněným - rozdíl 2,5s. Pokud následně použiju prepared statement, rychlost už je jen o cca 0,02s lepší, nicměně, bez prep. stmt. mám v paměti 3000 nacachovaných exekučních plánů, s prep. statementem jen 1 - tzn. 3000x menší paměťová náročnost.
14.3.2010 19:25 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Dnes je na světě PDO (už od PHP5.1) a v PHP6 to bude preferovaný způsob práce s databází. Podporuje vše potřebné a nedělá rozdíl mezi DB.

To je váš pohled. Mně to, co PDO nabízí, rozhodně nestačí. Nezávislost na DB je iluze, pokud nepoužíváte pouze triviální dotazy (na to je stejně lepší ORM).
14.3.2010 19:41 spaze
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Nezávislost na DB je iluze, pokud nepoužíváte pouze triviální dotazy (na to je stejně lepší ORM).
PDO má stejný interface (metody pro dotazy, fetch apod) ať už použiju jakoukoliv databázi. Tvorbu SQL pak nechává na lidech, takže nějakou nezávislost na DB nabízí. Jak říkají sami autoři je to "data-access abstraction layer", ne "database abstraction layer". Je v tom takový drobný rozdíl.
14.3.2010 19:48 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Podle mě nemá smysl se snažit psát přenositelné SQL - je to omezující, náročné a chybové. V konečném důsledku můžete spouštět jen ty nejtriviálnější dotazy - a celá moc a flexibilita SQL jde k šípku.

Pokud potřebujete fungovat na více databázích, pak je asi vhodné použít ORM - je dost pohodlné a bude produkovat úplně stejně efektivní dotazy jako přenositelné SQL.

U PDO je to vidět třeba u polí: vzhledem k tomu, že neexistuje mezi DB shoda o polích, nejde v PDO tohle: "... WHERE IN ?", array(1, 2, 3).

okbob avatar 14.3.2010 19:58 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Lze, ale nikoliv pro MySQL.

Vlastní API je samozřejmě pro Vás výhodou - člověk si napíše kód, tak jak mu vyhovuje - ale to už je problém v trochu větší firmě, případně v kódu, na jehož údržbě se vystřídá víc lidí.
14.3.2010 20:07 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Lze, ale nikoliv pro MySQL.

Bohužel nevím, na co reagujete :/

Vlastní API je samozřejmě pro Vás výhodou - člověk si napíše kód, tak jak mu vyhovuje - ale to už je problém v trochu větší firmě, případně v kódu, na jehož údržbě se vystřídá víc lidí.

Trochu problém je v tom, že samotné mysql_, mysqli a PDO jsou značně funkčně nedostatečné, takže nějakou knihovnu jste většinou nucen použít.

Jinak vlastní databázový layer si píše překvapivě velké množství lidí (a tím pádem i firem). Problém je většinou v tom, že jsou z velké většiny nekvalitní.

Query2 jsem uveřejnil i z toho důvodu, abych se donutil kód projít, okomentovat, udělat unit testy a dokumentaci, aby programátoři, kteří přijdou po mě tolik netrpěli ...
okbob avatar 14.3.2010 20:19 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Např. pro pg můžete vytvořit prepared statement ve tvaru

SELECT * FROM tab WHERE neco = ANY(string_to_array(:1,','))

To, že si firmy píši vlastní API pro přístup k DB vychází z faktu, že PHP dlouho neměl kloudné unifikované API - a nyní v tom pokračují. Nic jiného to neznamená.
14.3.2010 20:28 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Aha.

K dokonalosti to ale i tak má daleko, protože před předáním pole do PDO jej musíte převést na řetězec.

Toto navíc není aplikovatelné u pole řetězců. Pokud bude nějaký řetězec z pole obsahovat nastavený delimiter, tak jste v háji.
Daniel Kvasnička ml. avatar 18.3.2010 08:30 Daniel Kvasnička ml. | skóre: 52 | blog: The Joys and Sorrows of Being an IT Freak | Ostrava
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
PDO má stejný interface (metody pro dotazy, fetch apod) ať už použiju jakoukoliv databázi. Tvorbu SQL pak nechává na lidech, takže nějakou nezávislost na DB nabízí.
Pokud pisete cokoliv trosku vetsiho (tim fakt nemyslim vlastni blog nebo neco podobneho), nemate sanci se vyhnout psani vlastnich SQL dotazu. A kdyz uz je treba je psat, je snaha psat je prenositelne zbytecna. Nebudete prece delat kompromisy v rychlosti a vykonu proto, ze byste mozna hypoteticky mohl chtit casem zmenit databazi...?
FSF: “screw you for not wanting the stuff we produce”, People: “screw you for not producing the stuff we want."
18.3.2010 08:41 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Přece vůbec nejde o přenositelné SQL dotazy, ale o přenostitelnou knihovnu. Napíšete dva různé SQL dotazy pro dvě databáze, ale způsob zakládání spojení, načítání výsledků, ošetření chyb atd. bude v obou případech stejné.
Daniel Kvasnička ml. avatar 21.3.2010 23:17 Daniel Kvasnička ml. | skóre: 52 | blog: The Joys and Sorrows of Being an IT Freak | Ostrava
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Ctu to po sobe poradne az ted... :-) Vidim, ze jsem brojil proti necemu, co muj predrecnik nenapsal ;-)
FSF: “screw you for not wanting the stuff we produce”, People: “screw you for not producing the stuff we want."
xkucf03 avatar 18.3.2010 11:16 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL

Používáš JDBC?

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Daniel Kvasnička ml. avatar 21.3.2010 23:21 Daniel Kvasnička ml. | skóre: 52 | blog: The Joys and Sorrows of Being an IT Freak | Ostrava
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Jiste :-) (i kdyz posledni dobou uz silne zprostredkovane -- JDBC pouziva spis EclipseLink v GlassFishi, ktery ja si pak taham pres JNDI do Springu)

Viz. vyse, videl jsem v tom prispevku co tam nebylo... ;-)
FSF: “screw you for not wanting the stuff we produce”, People: “screw you for not producing the stuff we want."
default avatar 22.3.2010 09:26 default | skóre: 22 | Madrid
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Já už JDBC pomalu opouštím a přecházím přímo na Oracle Driver. Ty tanečky třeba okolo LOBů nebo XMLTYPEs mě už tak trošku přestávají bavit. Né že by to nefungovalo. To ono jó. Ale je to víc kódu, takže i víc chyb.
18.3.2010 22:57 Käyttäjä 11133 | skóre: 58 | blog: Ajattelee menneisyyttä
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Ale co, když někdo zprasí aplikaci neoptimálníma SQL dotazama, vždycky se dá koupit dedikovaný HP Superdome :)
default avatar 19.3.2010 09:30 default | skóre: 22 | Madrid
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
A nebo celou tu aplikaci přepsat do PL/SQL a na původní implementaci se vykašlat. To taky dost pomáhá. :-D
okbob avatar 14.3.2010 19:52 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
V čem PDO souvisí se složitostí dotazu? To jsou naprosto rozdílné věci. Souhlasím s Vámi, že konkrétní SQL dotazy budou pro různé databáze určitým spůsobem různé, ale samotné rozhraní pro přístup k databázím může být unifikované - vůbec v tom nevidím problém - existuje tu JDBC, ODBC, ADO, ADO.NET, DBO ... V podstatě jediné téma, které se z unifikované oblasti vymyká, jsou hromadné exporty, importy - ale ty se dají poměrně jednoduše izolovat.

Hlavní problém PHP programátorů ohledně databází je, že optimalizují, to co optimalizovat umí, a zapomínají na optimalizaci toho, co je nutné optimalizovat - optimalizace execu zdaleka není hrdlem - tím je zpracování dotazu na straně serveru - problémem může být hloupě navržený dotaz, generování desítek dotazů bez dostatečných predikátů, race conditions, chybějící indexy, hloupé stránkování, chybějící cacheování, nevyužívání kurzorů - to jsou všechno místa, kde aplikace nabírají vteřiny - optimalizovat body, kde se hraje o milisekundy je marnost nad marnost. Resp. nezkušenost - když jsem začínál s Visual Basicem a MSSQL, tak jsem se choval stejně naivně - optimalizovali jsme smyčky, kde se plnil recordsety, ale vůbec jsme neřešili prováděcí plány.

14.3.2010 20:02 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Re: Query2 - minimalistický layer v PHP pro MySQL

V čem PDO souvisí se složitostí dotazu? To jsou naprosto rozdílné věci. Souhlasím s Vámi, že konkrétní SQL dotazy budou pro různé databáze určitým spůsobem různé, ale samotné rozhraní pro přístup k databázím může být unifikované - vůbec v tom nevidím problém - existuje tu JDBC, ODBC, ADO, ADO.NET, DBO ... V podstatě jediné téma, které se z unifikované oblasti vymyká, jsou hromadné exporty, importy - ale ty se dají poměrně jednoduše izolovat.

Jistě, spaze už tu psal rozdíl mezi "data-access abstraction layer" a "database abstraction layer".

Mně jen přijde, že pokud budu chtít portovat aplikaci třeba na Postgres, která bude používat Query2, tak poslední, co mě bude trápit je to, že Query2 nepodporuje Postgres.

Implementaci Query2 pro Postgres udělám (když to přeženu) za hodinu tím, že všechny výskyty mysql_* nahradím za pg_*.

Co mě bude trápit budou samotné dotazy.

Hlavní problém PHP programátorů ohledně databází je, že optimalizují, to co optimalizovat umí, a zapomínají na optimalizaci toho, co je nutné optimalizovat - optimalizace execu zdaleka není hrdlem - tím je zpracování dotazu na straně serveru - problémem může být hloupě navržený dotaz, generování desítek dotazů bez dostatečných predikátů, race conditions, chybějící indexy, hloupé stránkování, chybějící cacheování, nevyužívání kurzorů - to jsou všechno místa, kde aplikace nabírají vteřiny - optimalizovat body, kde se hraje o milisekundy je marnost nad marnost. Resp. nezkušenost - když jsem začínál s Visual Basicem a MSSQL, tak jsem se choval stejně naivně - optimalizovali jsme smyčky, kde se plnil recordsety, ale vůbec jsme neřešili prováděcí plány.

Jistě, a tohle vás donutí psát databázově závislé (netriviální) SQL.
okbob avatar 14.3.2010 20:14 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Při programování nejde jen o samotný kód, ale i o určitou štábní kulturu - což se projevuje např. i v tom, že se preferují určitá API. Je to i o používání standardních API, používání vlastních API pouze tehdy, když mají jasný a výrazný výkonnostní přínos.

Jistě, a tohle vás donutí psát databázově závislé (netriviální) SQL.

SQL databáze jsou jaksi optimalizované na zpracování netriviálních SQL. To umí rychle a efektivně - na triviální věci nepotřebujete SQL db - na to je lepší memcache.

Jinak každý si může psát, co chce - pro zácvik v PHP to může být docela dobré. V praxi bych si ovšem takový kód třeba já nepřevzal.
14.3.2010 20:20 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
SQL databáze jsou jaksi optimalizované na zpracování netriviálních SQL. To umí rychle a efektivně - na triviální věci nepotřebujete SQL db - na to je lepší memcache.

Přesně tak. Jenže tahle argumentace jen podporuje můj názor, že data-access abstraction je poměrně málo významné, protože pokud už píšete aplikace s důrazem na výkon, tak je její portování na jinou databázi velmi, velmi obtížné (layer, nelayer). Pokud nepotřebujete výkon, nepotřebujete ani SQL.
okbob avatar 14.3.2010 20:40 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
programoval jste někdy v týmu?
14.3.2010 20:48 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Ano (pravda, ne moc velkém), proč?
okbob avatar 14.3.2010 20:51 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
není to znát
14.3.2010 20:52 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Můžete to trochu rozvést?
okbob avatar 14.3.2010 21:01 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Už to tu padlo, každý programátor si musí projít kolečkem, kdy si píše vlastní knihovny, GUI. Když pracujete v týmu, tak pak zjistíte, že každý má vlastní, ale pro Vás jsou cizí, a nakonec se většinou shodnete právě jen na těch standardních (pokud existují).
14.3.2010 19:47 spaze
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
jinak je docela pomalé - no, nejpomalejší ze všech možností přístupu k MySQL...
Tady bude záležet na použitým driveru. Dneska existuje mysqlnd (MySQL native driver), kterej nahrazuje libmysql a teoreticky a snad i prakticky je rychlejší, než používání libmysql. Tenhle driver mohou používat všechny extenze ext/mysql, ext/mysqli i PDO_MYSQL.
xkucf03 avatar 14.3.2010 17:00 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Odpovědět | Sbalit | Link | Blokovat | Admin
Občas se totiž stává, že vstup už máme escapovaný a znovu to dělat přirozeně nechceme.

Tohle nechápu. Jak se to může stát. To je chyba, ne?
Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
14.3.2010 17:06 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Tohle nechápu. Jak se to může stát. To je chyba, ne?

Obecně to chyba je, ale nemusí být vždy tvoje.

Např. při zapnutém magic_quotes_gpc (které jde vypnout jen v php.ini) máš veškeré data v $_GET, $_POST a $_COOKIE escapované. Často je špatný návrh programu, který escapuje data dřív než by měl (tedy až těsně před dotazem). A tak dále. V praxi se s tím setkávám bohužel docela často :(
xkucf03 avatar 14.3.2010 17:41 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Proto se mají data escapovat těsně před tím, než by mohla škodit – tzn. HTML/XML těsně před vypsáním na stránku a SQL apostrofy a spol těsně před vložením do SQL dotazu (i když to je stejně nepodstatné, protože se prostě mají používat parametrizované dotazy a ne lepit SQL z kousků textu).
při zapnutém magic_quotes_gpc
Tohle je jedna z největších prasáren v PHP, naprosto chybný návrh.
Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
14.3.2010 17:44 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
No jistě, ale tyto věci někdy prostě nejste schopen ovlivnit a musíte se přizpůsobit.

Jinak magic_quotes bude v PHP6 odstraněno (které ale vyjde až za pár let :/).
okbob avatar 14.3.2010 20:02 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
To je docela patologická filozofie.

Díky ní je PHP sra... a o MySQL lze říci to samé. Jakmile se začne ustupovat, špatně to končí. Programování je řemeslo jako každé jiné, a musí se dělat pořádně.
14.3.2010 20:11 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Rozvedu to trochu víc.

Ve svých skriptech kontroluji, jestli je magic_quotes_gpc zapnuté a pokud ano, všechen vstup odescapuju. Takže na to tyhle neescapovací modifikátory nepotřebuji.

Ale pokud máte používat kód, kterému nerozumíte a vrací vám už escapovaný výstup, hrdinství není na místě ...
okbob avatar 14.3.2010 20:39 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Chápu to, ale coby inženýr se cukám. Takže napřed PHP enkóduje hodnoty na vstupu - vy je dekódujete zpět, načež když je budete posílat do db, tak je znova zakódujete - jako jó, ale je to smutný.
14.3.2010 20:40 LesTR | skóre: 17 | Plzeň
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Ve svých skriptech kontroluji, jestli je magic_quotes_gpc zapnuté a pokud ano, všechen vstup odescapuju.

Coz je prave to zbytecne ustupovani, diky kteremu budou v php ci na beznych hostinzich takoveto (omluvte prosim to slovo) sra*ky.

Vas hosting neumoznuje vypnout magic_quotes_gpc? Ok, takze nashle. Takoveto fusery nema cenu dale podporovat

Save The World - http://www.worldcommunitygrid.org/ LesTR
14.3.2010 20:47 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
To je takový akademický přístup. V praxi tím ale přijdete o uživatele/zákazníky.
okbob avatar 14.3.2010 20:56 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Přijdu o mizerné zákazníky, a budu mít víc času na ty dobré (a když zrovna nejsou, tak budu mít čas na sebevzdělávání :)). Nehledě na to, že většina zákazníků ocení aktivní a profesionální přístup.
14.3.2010 20:59 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Soudit zákazníky podle hostingu je IMHO trochu dětinské. Když jsem si já vybíral svůj hosting, možnost nastavení takových věcí jsem taky nezkoumal.

Jinak zákazníkovi je většinou jedno, proč to nefunguje. Důležité pro ně je pouze to, že to nefunguje.
okbob avatar 14.3.2010 21:04 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Nesoudím zákazníka podle hostingu, ale podle toho, co ode mne požaduje, a do čeho mne tlačí. Občas je nutné bastlit - ale to si nechám vysvětlit a nechám si to zaplatit. Něco jiného je ovšem, když Vás zákazník nutí bastlit z vlastní umíněnosti.
14.3.2010 21:08 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Ok. Nemyslel jsem ani tak případ, kdy programujete na zakázku, ale spíš když prodáváte hotovou self-hosted aplikaci řádově stovkám a více zákazníkům. Pak nemáte čas ani vůli přesvědčovat každého z nich.
14.3.2010 21:18 LesTR | skóre: 17 | Plzeň
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Pak nemáte čas ani vůli přesvědčovat každého z nich.

Spravne, od toho jsou ale pozadavky na kterych system bezi, ktere si otestuje a rekne ze na tomto proste nepobezi a vysvetli uzivateli proc.

Neresme prosim porad dokola nezmary php verze 4 a niz.

Save The World - http://www.worldcommunitygrid.org/ LesTR
14.3.2010 21:34 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Pak se ale těžko vysvětluje, proč jsou příjmy poloviční. Jen kvůli boji za čistotu PHP ...
14.3.2010 21:40 LesTR | skóre: 17 | Plzeň
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Pak se ale těžko vysvětluje, proč jsou příjmy poloviční. Jen kvůli boji za čistotu PHP ...

Pak se ale tezko vysvetluje, proc je php tak zprasene. Jen kvuli neschopnosti vysvetlit potrebu zmeny a podlozit ji argumenty

Save The World - http://www.worldcommunitygrid.org/ LesTR
14.3.2010 21:47 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Já jen prostě nechápu, proč přicházet o potenciální zákazníky kvůli třem řádkům kódu navíc ...
okbob avatar 14.3.2010 21:42 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Já jsem zažil přesně opačnou situaci - znal jsem firmu, kde se snažili každému vyhovět. Do jisté míry platí přímá úměra - čím je zákazník větší prudič, tím více času mu musíte věnovat a obyčejně tím méně se mu chce za služby platit. Ta firma se položila - nezbyly jí prostředky na to, aby se věnovala bonitním zákazníkům.

Nemusíte bojovat za čistotu PHP. Určitě jsou k dispozici desítky slušných hostingů, takže stačí deklarovat požadavky a zbytek ať si vyřeší zákazník. O zákazníky byste přicházel, kdyby neexistovala nabídka, možnost výběru. Taková situace tu ovšem není.
14.3.2010 21:05 LesTR | skóre: 17 | Plzeň
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Soudit zákazníky podle hostingu je IMHO trochu dětinské.

To tu ale nikdo netvrdi.

Kazdy rozumny zakaznik si necha vysvetlit, ze tento hosting ne, protoze ... Pokud mu to ale neumite vysvetlit a sve nazory si obhajit, je problem jinde.

Save The World - http://www.worldcommunitygrid.org/ LesTR
14.3.2010 21:09 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Viz reakce výše, měl jsem na mysli jinou cílovou skupině zákazníků.
14.3.2010 20:33 LesTR | skóre: 17 | Plzeň
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Odpovědět | Sbalit | Link | Blokovat | Admin

Opravdu si myslite, ze nekdo bude chtit pouzivat knihovnu, ktera neni otagovana a ani o branche se ji taky vubec nezda? Pekne ze nabizite neco lidem, co ani sam nepovazujete za stabilni : )

Jinak k layeru:

Omlouvam se za trochu kriticky prispevek, je ale pravda, ze kazdy php programator si musi napsat to sve kolo v podobe databazove knihovny, parseru pro html kod, redakcniho systemu atp. Sam sem si tim prosel : )

A perlicka na zaver, jak je na tom knihovna v porovnani s pdo_mysql co se rychlosti a pametove narocnosti tyce? Ja myslim ze uz dopredu je vysledek znam.

A ted jeste posledni "rejp" do prepare statements, co bude rychlejsi, kdyz cele pole projdu a data oslashuji v php, nebo to necham na db, ktera to vi beztak imho lepe?

Ja vim, dej jim prst a sezerou te celeho

Save The World - http://www.worldcommunitygrid.org/ LesTR
14.3.2010 20:45 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Opravdu si myslite, ze nekdo bude chtit pouzivat knihovnu, ktera neni otagovana a ani o branche se ji taky vubec nezda? Pekne ze nabizite neco lidem, co ani sam nepovazujete za stabilni : )

Toto je první veřejná verze - tagování ani branchování nebylo jednoduše dosud potřeba ;-)

Zend_Db neni jen pro takoveto lepeni dotazu, umoznuje mimo jine i active row pattern.

Na to je Zend_Db_Table. A nic takového implementovat nechci ...

Nechapu proc se nepouzivaji prepare statements, diskuze je o tom dlouha ale duvod k tomu nikde. Pry pomalost ...

Jednoduše není potřeba. O kontrolu dat se stará Query2 jinak a jediná další výhoda je potenciální zvýšení výkonu - což u MySQL neplatí.

To ze volam commit dat neznamena, ze chci nastavit SET AUTOCOMMIT na 1, proc mi to knihovna diktuje?

Jelikož MySQL nepodporuje zanořené transakce, na co vám bude dobré mít AUTOCOMMIT na nule?

Chvalim za pouziti spravne fce pro escapovani - mysql_real_escape_string nikde uz ale nevidim volani mysql_client_encoding, bez ktereho je i mysql_real_escape_string za urcitych okolnosti derava.

Přiznám se, že o děravosti při nenastavení encoding jsem ještě neslyšel, pokusím se to nastudovat. Díky.

Jak uvolnim alokovanou pamet vysledku? Tzn mysql_free_result. Nikde jsem to nenasel

Volá se při destrukci objektu Query2Result.

Unbuffered query?

Toto Query2 nepodporuje. Můžete uvést nějaký příklad použití? AFAIK není možné volat další dotaz dokud nedojde k odfetchování všech výsledků, takže rychlostní ani paměťový benefit nevidím.

Pokud chci pouze pocet bez limitu, muzu pouzit modifikator pro select SQL_FOUND_ROWS, jde toto provest s Query2?

Jistě, úplně stejně jako byste to udělal třeba pomocí mysql_query()

A perlicka na zaver, jak je na tom knihovna v porovnani s pdo_mysql co se rychlosti a pametove narocnosti tyce? Ja myslim ze uz dopredu je vysledek znam.

Samozřejmě hůř, je to totiž knihovna vyšší úrovně. Query2 ale upravuje SQL jen velmi málo (de facto jen substituce modifikátorů), takže myslím, že rozdíl nebude relevantní.

A ted jeste posledni "rejp" do prepare statements, co bude rychlejsi, kdyz cele pole projdu a data oslashuji v php, nebo to necham na db, ktera to vi beztak imho lepe?

IMHO rozdíl v rychlosti escapování nebude relevantní.
14.3.2010 21:15 LesTR | skóre: 17 | Plzeň
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Toto je první veřejná verze - tagování ani branchování nebylo jednoduše dosud potřeba ;-)

I tak mi to prijde takove ... Osobne nic co neotaguji nepovazuji za stabilni a pokud to nekdo pouzije, je to jen na jeho riziko a ja to vyslovne nedoporucuji. Co kdyz si usmyslim, ze tady ty parametry metody jsou pro me zbytecne, tak je odstranim?

Jednoduše není potřeba. O kontrolu dat se stará Query2 jinak a jediná další výhoda je potenciální zvýšení výkonu - což u MySQL neplatí.

Otazkou je, jestli dostatecne a jestli ten mytus o rychlosti porad plati. Mysql uz davno neni ve verzi 4.1

Jelikož MySQL nepodporuje zanořené transakce, na co vám bude dobré mít AUTOCOMMIT na nule?

Otazka znela proc ho dava na 1, imho je to zbytecne, jen dalsi sitova komunikace navic

Volá se při destrukci objektu Query2Result.

Coz imho neni spravne

Unbuffered query?

Toto Query2 nepodporuje. Můžete uvést nějaký příklad použití? AFAIK není možné volat další dotaz dokud nedojde k odfetchování všech výsledků, takže rychlostní ani paměťový benefit nevidím.

Napr vsechny dotazy typu INSERT/UPDATE/DELETE, kde me zajima pouze true/false vysledku?

Samozřejmě hůř, je to totiž knihovna vyšší úrovně. Query2 ale upravuje SQL jen velmi málo (de facto jen substituce modifikátorů), takže myslím, že rozdíl nebude relevantní.

A ted k otazce, co Vam chybi na std. pdo, ze musite psat toto kolecko?

IMHO rozdíl v rychlosti escapování nebude relevantní.

na malem poctu bindovanych promennych urcite, na vetsich bych si tak jisty nebyl, natoz u napr. text/blob sloupce

Nerikam, ze psat si vlastni layer je spatne, naopak clovek se toho hodne nauci, vesmes ale nakonec dojde k zaveru, ze std. reseni je lepsi a efektivnejsi :D

Save The World - http://www.worldcommunitygrid.org/ LesTR
14.3.2010 21:32 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Otazkou je, jestli dostatecne a jestli ten mytus o rychlosti porad plati. Mysql uz davno neni ve verzi 4.1

Ano, dostatečně. Mýtus o rychlosti stále platí, až platit přestane, popřemýšlím o reimplementaci pomocí prepared statements (nebylo by potřeba měnit API).

Otazka znela proc ho dava na 1, imho je to zbytecne, jen dalsi sitova komunikace navic

Hmm, nevěděl jsem, že MySQL po commit nebo rollback nastavuje autocommit na předchozí hodnotu. Díky.

Napr vsechny dotazy typu INSERT/UPDATE/DELETE, kde me zajima pouze true/false vysledku?

Budiž. Řešit to ale nebudu.

Coz imho neni spravne

Co je tedy podle tebe správně?

A ted k otazce, co Vam chybi na std. pdo, ze musite psat toto kolecko?

Nemožnost pracovat s poli, IMHO šílený zápis INSERT INTO ... ON DUPLICATE KEYS UPDATE, a "hackovací"/manuální dynamické sestavování dotazů.

na malem poctu bindovanych promennych urcite, na vetsich bych si tak jisty nebyl, natoz u napr. text/blob sloupce

Zapomínáte na fakt, že mysql_real_escape_string/addslashes je taky implementované v C.

Nerikam, ze psat si vlastni layer je spatne, naopak clovek se toho hodne nauci, vesmes ale nakonec dojde k zaveru, ze std. reseni je lepsi a efektivnejsi :D

Pro mě je jejich jediná výhoda standardnost :-/
14.3.2010 23:11 Jiří Kocman
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Unbuffered query?

Toto Query2 nepodporuje. Můžete uvést nějaký příklad použití? AFAIK není možné volat další dotaz dokud nedojde k odfetchování všech výsledků, takže rychlostní ani paměťový benefit nevidím.

Unbuffered query je přece skvělá věc. Jednak je rychlejší, druhak paměťově nenáročná. Unbuffered query vrací z DB na klienta řádky když je najde, a nikde si je nedrží. Dotaz tak může být v mnoha případech dokončen rychleji. Například Oracle má mechanizmy, které vrací X prvních řádků maximálně rychle a zbylé řádky klidně i mnohonásobně pomaleji. Pokud pro takovýto dotaz ale použiju buffered query, výsledek budu mít k dispozici až to dokončí databáze celé, nikoli postupně jak je databáze naléza.. mimochodem Oracle s PHP oci (pdo v php pro oracle ještě není tak potuněná) ani bufferované query nepodporuje, protože je to výkonnostní problém. Ano, nejsem schopen použít NUM ROWS, ale to obvykle nepotřebuji. A nevidět paměťový benefit? V paměti se nedrží celý result set. Mimochodem pokud jsem správně informován unbuffered query je třeba automaticky používaná v PDO a buffered se musí explicitně vyžádat. Proč tomu tak asi je?

A ještě k prepared statementům. Představte si že máte memory limit třeba 10M a potřebujete do databáze uložit 10M soubor, do proměnné ho načíst nemůžete, to vám PHP spadne na memory limitu. Jak to tedy uděláte bez prepared statements? A podotýkám, neřeším tu proč ukládat takový soubor do databáze, ale jak to udělat... \Pořád jsou prepared statements k ničemu?

Nebo se zeptám jak budete fetchovat výsledky uložených procedur a všechny jejich výstupní parametry (nemluvím teď záměrně o návratové hodnotě funkce, ale o out parametrech procedur, případně i funkcí).

Mimochodem pokud dnes MySQL neudržuje cache exekučních plánů - což by brutálně urychlilo chod s prepared statements - tak to neznamená že to zítra nemůže fungovat. Ovšem pokud někdo neznalý, netuší k čemu je to dobré a všude vidí masírku že je to k ničemu... pak přejde na "velkou" databázi a nestačí se divit co všechno dělá špatně.
14.3.2010 23:28 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
S tou paměťovou náročností to byl sek, přiznávám.

A ještě k prepared statementům. Představte si že máte memory limit třeba 10M a potřebujete do databáze uložit 10M soubor, do proměnné ho načíst nemůžete, to vám PHP spadne na memory limitu. Jak to tedy uděláte bez prepared statements? A podotýkám, neřeším tu proč ukládat takový soubor do databáze, ale jak to udělat... \Pořád jsou prepared statements k ničemu?

Nikdo netvrdí, že prepared statements jsou na nic. Mimochodem, jak dokážete poslat parametr (soubor) serveru bez toho, abyste ho nemusel najednou načíst do paměti? Streamem?

Mimochodem pokud dnes MySQL neudržuje cache exekučních plánů - což by brutálně urychlilo chod s prepared statements - tak to neznamená že to zítra nemůže fungovat. Ovšem pokud někdo neznalý, netuší k čemu je to dobré a všude vidí masírku že je to k ničemu... pak přejde na "velkou" databázi a nestačí se divit co všechno dělá špatně.

Opět, nikdo netvrdí, že prepared statements jsou k ničemu. Jinak, pokud se prepared statements skutečně takto zrychlí, není problém knihovnu reimplementovat pro práci s prepared statements beze změny API.
xkucf03 avatar 14.3.2010 23:42 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Mimochodem, jak dokážete poslat parametr (soubor) serveru bez toho, abyste ho nemusel najednou načíst do paměti? Streamem?
jj, např. v Javě by to mělo jít takhle:
File file = new File("myimage.gif");
FileInputStream fis = new FileInputStream(file);
PreparedStatement ps = conn.prepareStatement("INSERT INTO images VALUES (?, ?)");
ps.setString(1, file.getName());
ps.setBinaryStream(2, fis, (int)file.length());
ps.executeUpdate();
ps.close();
fis.close();
viz Processing Binary Data in JDBC.
Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
14.3.2010 23:56 Jiří Kocman
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Vrátím se k unbuffered query. Náročnost na paměť bude v PHP stejná, zde jde ale o náročnost pro databázi. Nebufferovaným výsledkem jde třeba iterovat pouze dopředu, nelze tedy zavolat například mysql_data_seek. Nelze použít mysql_num_rows. Nicméně pro drtivou většinu použití je unbuffered query správná volba, jen málokdy potřebujeme resultset iterovat vícekrát nebo se v něm specificky pohybovat. A jak už jsem podotkl, některé databáze buffered query ani nepoužívají. Výhodou je pak ta rychlost, klient dostane první výsledek dříve a aplikace s ním může pracovat zatímco databáze dohledává další výsledky dotazu.

Mimochodem, jak dokážete poslat parametr (soubor) serveru bez toho, abyste ho nemusel najednou načíst do paměti? Streamem?

Přesně tak stream se předá jako parametr...

$fp = fopen($_FILES['file']['tmp_name'], 'rb'); $stmt->bindParam(':mujLob', $fp, PDO::PARAM_LOB);

Toto bez PP možné není. Samozřejmě že PDO podporuje nejen fopen, ale všechny stream API. A například Oracle OCI nepotřebuje ani stream a stačí mu předat filename, se kterým si pak oracle client poradí sám.

Opět, nikdo netvrdí, že prepared statements jsou k ničemu. Jinak, pokud se prepared statements skutečně takto zrychlí, není problém knihovnu reimplementovat pro práci s prepared statements beze změny API.

Proč to tedy neudělat rovnou, například jako parametr při inicializaci "USE_PREPARED_STATEMENTS" a pokud bude nastaven, budou použity. Někdo je třeba používat chce kvůli 100% bezpečnosti nebo kvůli rychlosti při opakovaných query (zde je přínos měřitelný i na MySQL).
15.3.2010 00:13 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Vrátím se k unbuffered query. Náročnost na paměť bude v PHP stejná, zde jde ale o náročnost pro databázi. Nebufferovaným výsledkem jde třeba iterovat pouze dopředu, nelze tedy zavolat například mysql_data_seek. Nelze použít mysql_num_rows. Nicméně pro drtivou většinu použití je unbuffered query správná volba, jen málokdy potřebujeme resultset iterovat vícekrát nebo se v něm specificky pohybovat. A jak už jsem podotkl, některé databáze buffered query ani nepoužívají. Výhodou je pak ta rychlost, klient dostane první výsledek dříve a aplikace s ním může pracovat zatímco databáze dohledává další výsledky dotazu.

Popřemýšlím o tom. Původně jsem unbuffered query zavrhl kvůli nemožnosti seekovat v resultsetu, což mi nesedělo do iterator interface (šlo o rewind resultsetu).

Asi nechám buffered query jako default (programátor IMHO předpokládá funkčnost num rows) a vytvořím novou uquery(). Pokud už unbuffered query programátor použije, pak ví, co dělá a zná důsledky.

Proč to tedy neudělat rovnou, například jako parametr při inicializaci "USE_PREPARED_STATEMENTS" a pokud bude nastaven, budou použity. Někdo je třeba používat chce kvůli 100% bezpečnosti nebo kvůli rychlosti při opakovaných query (zde je přínos měřitelný i na MySQL).

Mám rád malé a jednoduché věci. Pokud bych implementoval oboje, knihovna by už tak malá a jednoduchá nebyla.

Upřímně řečeno jsem nikdy ani neuvažoval, že bych použil prepared statements, protože základním (interním) požadavkem pro knihovnu bylo to, abych dokázal využít již existující spojení vytvořené pomocí mysql_connect(). Proto bylo MySQLi předem vyloučeno ze hry.
15.3.2010 00:14 Jiří Kocman
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Ještě si dovolím další report k další chybě, kterou jsem kritizoval i u DIBI a Query2 ji obsahuje taky, no nebo spíše implementace nepočítá jedním ze způsobů zápisů IN. A jelikož Query2 má dělat pořádně kompozici dotazu, tak je to vada podstatná a sice:

$q->query("SELECT * FROM users WHERE login %in ORDER BY %t", array("Eva", "Filip", "Jakub"), "lo'gi`n");

Je sice hezké že pro IN můžu použít array se seznamem hodnot. ale pojďme se podívat na nějaký dotaz:

SELECT * FROM tabulka WHERE pozdrav = "Ahoj" OR osloveni = "Ahoj"

Je to triviální dotaz, ten se dá napsat i takto:

SELECT * FROM tabulka WHERE "Ahoj" IN (pozdrav, osloveni)

Tzn. v IN nemám hodnoty, ale názvy sloupců. Tento zápis se zcela běžně používá a osobně ho považuji za přehlednější. Bohužel Query2 nebo DIBI a předpokládám že i query ze Zend_Db udělají to, že vstupní pole automaticky považují za seznam hodnot a proto hodnoty uzavírají do uvozovek, což pak samozřejmě znamená že takový dotaz fungovat nebude... Výhoda kompozice dotazů tak dostává na frak. A nezbývá než to napsat "natvrdo".

15.3.2010 00:21 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Query2 toto dokáže, ale ne moc elegantně:
$q->query("SELECT * FROM tabulka WHERE "Ahoj" %in", array(
	new Query2Statement("pozdrav"),
	new Query2Statement("osloveni")
));
Query2Statement je triviální třída vytvořená přesně na toto. Problém je v tom, že v onom poli nemáme moc způsobů jak knihovně říct, jak data interpretovat. Dal by se použít nový modifikátor, ale toto funguje obecně pro všechny modifikátory s argumenty - poli.
15.3.2010 01:24 Kvakor
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Obdobnou syntaxy zápísu má i fulltextové hledání, jen místo IN je tam MATCH (sloupce) AGAINST výraz. A nejspíš jde najít spoustu dalších případů, kde je problém rozlišit escapování názvů sloupců (popř. tabulek) a hodnot (např. když dopředu nevíte, jaké sloupce bude potřeba nebo v které tabulce data jsou).

Zatím jsem viděl jen jedno řešení, kde veškeré předávané parametry byly objekty, které samy věděly, jestli jsou název nebo hodnota, takže se korektně před použitím samy oescapovávaly (hodnoty v normálních apostrofech, názvy v otočených), ale osobně se mi to zdá poněkud težkopádné. Spíš by se mi líbila ona druhá možnost mít přímo v řetězci samostatné modifikátory pro názvy a pro hodnoty, jenže to znamená napsat si vlastní funkci na zparsování řetězce, poněvač PHP bohužel nemá u printfoidních funkcí definovatelné callbacky pro vlastní modifikátory.
Josef Kufner avatar 15.3.2010 12:53 Josef Kufner | skóre: 70
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
A co to vzít nadvakrát? %s pro identifikátor, %%s pro hodnoty. Při prvním průchodu se dosadí identifikátory, které neobsahují %, takže to nerozbijou a v druhém už bude místo %%s jen %s, takže se můžou v klidu dosadit hodnoty...
Hello world ! Segmentation fault (core dumped)
xkucf03 avatar 15.3.2010 17:40 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Vždyť identifikátory (třeba názvy sloupců) taky můžou obsahovat znak % :-D
SELECT 'fuj' AS "To je ale 100% prasárna";
(vyzkoušej)
Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
default avatar 15.3.2010 18:08 default | skóre: 22 | Madrid
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
"To je ale 100% prasárna";
Mně to jako prasárna nepřipadá. Třeba pro reporty je skvělý, nemusíš hákovat nějaký formátování. Prostě ti z SQL*Plus rovnou vypadne přehledná tabulka s lidsky čitelným nadpisem. :-)
xkucf03 avatar 15.3.2010 18:23 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše Čeština a další věci v identifikátorech SQL.
jj, tímhle způsobem to taky občas použiji, ale zrovna obvyklé to není – třeba tabulky bych si takhle nepojmenoval, ne že by to nefungovalo (funguje), ale je dost nepraktické nad tím pak psát SQL dotazy (člověk musí pořád používat uvozovky). Smysl to má asi jen pro ty „reporty“, protože v normálních tabulkách aplikace člověk spíš použije nějaký „klíč“, který se pak prožene lokalizací.
Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
default avatar 15.3.2010 19:59 default | skóre: 22 | Madrid
Rozbalit Rozbalit vše Re: Čeština a další věci v identifikátorech SQL.
HaHa. V normálních aplikacích! Leží mi na stole projekt, který má jmennou konvenci. Nesmí se používat nic než tabulky a možná úložné procedury. Tabulky se musí jmenovat T_######## a sloupce v nich C_######## kde # je zástupce pro číslo. :-D
vlastikroot avatar 15.3.2010 20:02 vlastikroot | skóre: 24 | blog: vlastikovo | Milevsko
Rozbalit Rozbalit vše Re: Čeština a další věci v identifikátorech SQL.
LOL, to je něco jako učiná ochrana proti pohodlnému vývoji?
We will destroys the Christian's legion ... and the cross, will be inverted
default avatar 15.3.2010 20:19 default | skóre: 22 | Madrid
Rozbalit Rozbalit vše Re: Čeština a další věci v identifikátorech SQL.
Víc detailů si radši nechám pro sebe (příliš vysoký výskyt sprostých slov). Jen namátkou:
  • Můžete nám v rychlosti vysvětlit, co to jsou User-defined Types? (Oracle DBA)
  • Co to je End-of-Line character? (Integration Specialist)
  • Co to je Control-M, Cron scheduler…? (Integration Specialist)
Myslím, že je vše jasné. :-D :-D :-D
15.3.2010 21:09 12345 | skóre: 41 | blog:
Rozbalit Rozbalit vše Re: Čeština a další věci v identifikátorech SQL.
Ideální kandidát na The Daily WTF Code Snippet Of the Day! Nechceš tam nějakou ukázku poslat? :-)
default avatar 16.3.2010 09:11 default | skóre: 22 | Madrid
Rozbalit Rozbalit vše Re: Čeština a další věci v identifikátorech SQL.
Dobrý nápad. Určitě něco vyberu. Materiálu bude dostatek.

Nejvíc kuriózní na tom je, že se tímto způsobem vyvíjí v roce 2010. :-D
Josef Kufner avatar 15.3.2010 20:59 Josef Kufner | skóre: 70
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
No dobře, tak pokud takle, tak tam prostě nacpeš jeden str_replace navíc...
function printf_escape($str) { return str_replace('%', '%%', $str); }
mysql_query(vsprintf(vsprintf($query, array_map('printf_escape', $cols)), $vals))
... k neprůstřelnosti tomu ale chybí ještě doplňování uvozovek a escapování obsahu $cols a $vals.
Hello world ! Segmentation fault (core dumped)
okbob avatar 15.3.2010 08:54 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Unbuffered queries mají neskutečně velký význam, pokud potřebujete pracovat s velkým objemem dat. Což není úplně běžné - ale při určitých exportech se to hodí. S klasickým dotazem jde klient do kolen - čeká se až server naplní buffer - při unbuffered se velké objemy zvládají v pohodě.
14.3.2010 21:34 LesTR | skóre: 17 | Plzeň
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Pokud chci pouze pocet bez limitu, muzu pouzit modifikator pro select SQL_FOUND_ROWS, jde toto provest s Query2?

Jistě, úplně stejně jako byste to udělal třeba pomocí mysql_query()

Koukam do zdrojaku a na kazdy sloupec se aplikuje pomoci array_map volani metody escape. Zkouset jsem to tedy nezkousel, ale logicky mi z toho vychazi, ze mi to SQL_FOUND_ROWS oslashuje, coz zkonci leda tak na nenalezenem sloupci. Mozna jsem ale nejaky hack predtim prehledl.

Save The World - http://www.worldcommunitygrid.org/ LesTR
14.3.2010 21:44 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Sorry, ale cos napsal je mimo.

1) Metoda escape je vlastně pouze mysql_real_escape_string(), která ti z SQL_FOUND_ROWS udělá co? SQL_FOUND_ROWS ;-) To, co by teoreticky mohlo způsobit problém je obklopení uvozovkami.

2) Metoda, kterou popisuješ, se používá jen při práci s poli, SQL_FOUND_ROWS nemá v poli smysl (pole se používají pro INSERT, UPDATE, IN atp.)

3) Podobné věci, které už v poli smysl mají (např. NOW()) se řeší pomocí třídy Query2Statement. Je to sice hack, ale jednoduše to udělat nejde.

Příklad:

$q->query("SELECT SQL_FOUND_ROWS FROM users")->fetchOne();
14.3.2010 21:50 LesTR | skóre: 17 | Plzeň
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Sorry, ale cos napsal je mimo.
Po tomto vysvetleni si sypu popel na hlavu
Save The World - http://www.worldcommunitygrid.org/ LesTR
15.3.2010 02:04 Kvakor
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Chvalim za pouziti spravne fce pro escapovani - mysql_real_escape_string nikde uz ale nevidim volani mysql_client_encoding, bez ktereho je i mysql_real_escape_string za urcitych okolnosti derava.

Přiznám se, že o děravosti při nenastavení encoding jsem ještě neslyšel, pokusím se to nastudovat. Díky.
Pokud klient, běžící v jednobytovém kódování (např. Win CP-1250, ISO 8859-2 ...), neví, že zpracovává řetězec s vícebytovými znaky, může pustit ven řetězec, který je z pohledu klienta naprosto korekntní, ale z pohledu serveru používajícího vícebytového kódování (např. UTF-8), už ne - stačí vpašovat na vhodné místo vhodný znak (např. s hodnotou nad 127), který při převodu do vícebytového kódování "pozře" přidané escapování. Sice na SQL injection by to asi nestačilo, ale na rozhození query, chybovou hlášku a případné znefukčnení stránky to stačí.
15.3.2010 00:43 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Odpovědět | Sbalit | Link | Blokovat | Admin
Od vydání verze 1.0.0 jsem našel dva bugy: Zítra vydám opravnou verzi.
15.3.2010 08:09 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
To je přesně důvod, proč nemám rád obcházení problému escapováním znaků. Query2 údajně řeší SQL injection „jiným způsobem“ (escapováním), ale hned tam máte v escapování dvě chyby (tu výše zmíněnou a tu s nenastaveným kódováním).
15.3.2010 16:05 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Upřesním:

první problém nezpůsobí SQL injection, protože se escapuje víc, než by mělo.

trochu jsem pogoogloval a zjistil co se týče druhého problému tohle: Problém nenastává při "nenastavení" znakové sady, ale naopak při nastavení znakové sady (dynamicky, tedy třeba pomocí SET CHARACTER SET), ale neinformování klienta o této změně. Dovolím si tvrdit, že v případě knihoven typu Query2 je tohle zodpovědností programátora, já mu k tomu můžu maximálně poskytnout API metodu (jde to i teď, protože resource je přístupné i zvenku).

mysql_real_escape_string je zranitelné pouze tehdy, když na serveru je defaultně nastavené kódování s délkou znaku konstantně jednoho bytu a změní se dynamicky na vícebytové kódování.

Důležitou informací ale je, že UTF-8 zranitelné není.

Pro české uživatele to znamená, že informovat klienta je nutné jen při použití (u nás) obskurních kódování.

Zdroj: http://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared-Statements.html

Jinak obě níže zmíněné chyby jsou opraveny ve verzi 1.0.1
15.3.2010 17:12 mrzout | skóre: 11 | blog: mrzutej
Rozbalit Rozbalit vše licence
Odpovědět | Sbalit | Link | Blokovat | Admin
MySQL je pod duální licencí, přičemž ta volná byla GPL. A aplikace z ní odvozené tedy musejí být také pod GPL. Narozdíl od těch, které jsou psány multiplatfomně.

Z toho usuzuji, že budete mít problém ve své zvolené licenci.

Ale já nejsem právník, jen bych si to být vámi ještě s někým zkonzultoval.
Hlasuj pro zavedení OpenID na Abclinuxu!
15.3.2010 17:22 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: licence
Query2 nevypadá na aplikaci odvozenou od MySQL.
Josef Kufner avatar 15.3.2010 21:08 Josef Kufner | skóre: 70
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Odpovědět | Sbalit | Link | Blokovat | Admin
A umí to také skládání dotazu po jednotlivých částech? Tedy aby se nemusel slepovat řetězec, ale hezky se to někam naházelo jak to zrovna přijde pod ruku a pak se to teprve urovnalo... něco jako:
$q = new Q();
$q->add_from('from T as t');
$q->add_select('x');

if ($id) {
  $q->add_where('t.id = '.$id);
}

if ($add_name) {
  $q->add_left_join('N as n', 't.id = n.id');
  $q->add_select('n.name');
}

$q->execute();
Takováhle věc se mi osvědčila už mnohokrát a drasticky to zjednodušuje tvorbu SQL dotazů. Navíc ani nemusí řešit spojení k DB, stačí aby výstupem byl vlastní dotaz.
Hello world ! Segmentation fault (core dumped)
15.3.2010 21:16 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Ano, tohle byla jedna z motivací pro vytvoření Query2.

Stará se o to Query2Builder a máte pravdu, nepotřebuje k tomu ani spojení k DB (nevytváří ale taky hotový SQL dotaz, ale vstup pro metodu query() hlavní třídy Query2).

Výše jsou uvedeny i příklady, na stránkách je jich víc. V tomto Query2Builderu je možné využívat modifikátory a umí třeba i zanořené WHERE ...

BTW, jak jste dosáhnul toho obarveného kódu?
xkucf03 avatar 15.3.2010 21:43 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše neprocedurální
Chudák SQL, takový pěkný neprocedurální jazyk a takhle procedurálně ho prasit.
Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
15.3.2010 21:46 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: neprocedurální
Pokud potřebujete tvořit dotaz dynamicky, budete prasit daleko, daleko víc (nepoužijete-li něco takovéhoto).
xkucf03 avatar 15.3.2010 21:50 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše Re: neprocedurální
Potřeba tvořit dotazy dynamicky je často zapříčiněna špatným datovým modelem.
Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
15.3.2010 21:58 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: neprocedurální
Příklad z praxe: máte tabulku s X sloupci. Potřebujete ji zobrazit uživateli a nabídnout mu X filtrů pro obsah daných buněk a možnost řadit podle kteréhokoli sloupce. Jaký datový model navrhujete, nechcete-li dotaz vytvářet dynamicky?
16.3.2010 07:57 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: neprocedurální
Seznam nebo pole v programu. Pokud bude uživatel vytvářet dotaz sám, bude to jedině nad nějakou malou tabulkou, a tu může mít aplikace klidně v paměti, je zbytečné tím trápit databázi. Pořád je to ale jen špatný návrh aplikace – proč uživateli dávat X filtrů a možnost řadit podle jakéhokoli sloupce, proč mu rovnou nedáte SQL konzoli?
16.3.2010 09:10 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: neprocedurální
Uživatel je sekretářka používající tabulku, která o SQL nikdy neslyšela a nejspíš ani slyšet nechce. Nehledě na to, že slečně sekretářce nemůžu dát přístup do konzole z bezpečnostních důvodů ...

Celkově na váš příspěvek jen čumím a říkám si jen WTF.
16.3.2010 09:13 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: neprocedurální
Co bude v tom případě dělat s univerzálními filtry?
16.3.2010 09:16 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: neprocedurální
Coby, používat je. Netvrdím, že filtr zákazník potřebuje na všech sloupcích, ale často na většině (nebo třeba jen na jednom, je to jedno). Co mám pak dělat, vytvořit X variant dotazů nebo jeden jednoduse slepit?
okbob avatar 16.3.2010 09:30 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: neprocedurální
prostě klasika - toho se nezbavíme. Pozvali mne k aplikaci, která se vlekla a hrozně se divili, když jsem jim vyházel filtry typu:
sloupec like '%slovo1% or sloupec like '%slovo2%' or sloupec like '%slovo3%' + 30x
16.3.2010 09:46 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: neprocedurální
prostě klasika - toho se nezbavíme.

Pak ale nechápu tu kritiku.
okbob avatar 16.3.2010 10:34 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: neprocedurální
To nebyla odpověď - to byl nářek :)
default avatar 16.3.2010 11:53 default | skóre: 22 | Madrid
Rozbalit Rozbalit vše Re: neprocedurální
Jo, něco podobnýho tu mám taky. Akorát to má navíc dvakrát DISTINCT. :-D

Nebo jiná perlička byl anti-join tabulky a WINDOW nad ní definovanou analytickou funkcí. Hoši nemohli pochopit, proč že náročnost dotazu roste miliónkrát s každým novým řádkem. Prý proto, že u sloupců s datovým typem DATE nalze použít index. :-D

Obecně miluju tyhlety týpky, který nedaj SELECT z duálu, ale "je to chyba Oracle".

Nebo notorická klasika:
  • NVL(sloupec, '')
  • COALESCE(sloupec1, sloupec2, '')
O tom, že pro čísla je nejlepší datový typ VARCHAR2 už ani nemluvím. Pak je to samý TO_CHAR(), TO_NUMBER() a že je to pomalý. :-D A navíc se to porád sere, protože maj bordel v datech. :-D

Nebo XML. To jsou taky dobrý stórky. Borec to lepí řetězci jak Pat a Mat. Pak v testech zjistil, že některý znaky by bylo lepší mít v XML Entitách, tak doprasil vnořený REPLACEy... :-D

To prostě není už ani na to The Daily WTF. To je prostě smutný.

A nebo dneska jsem zjistil, že jediný správný způsob na konfiguraci Javích webových aplikací jsou -D parametry aplikáče. :-D :-D :-D
16.3.2010 10:25 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: neprocedurální
Udělat aplikaci, která umožní pracovat s daty přirozeným způsobem – ne jen fasádu přes SQL dotazy.
16.3.2010 10:34 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: neprocedurální
Otázkou pak zase je, proč znovu vynalézat kolo, když SQL dotazem to uděláme snadněji, rychleji a s velkou pravděpodobností i mnohem efektivněji.
Heron avatar 16.3.2010 10:44 Heron | skóre: 53 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: neprocedurální

No to právě ne. Jak už tě upozornili ostatní, tohle řešení má (v budoucnu bude mít) velké výkonnostní problémy, jelikož na to není to schéma připraveno. De facto by jsi musel přidat index na každý sloupec a jejich kombinace. Jak pak dopadne insert asi netřeba připomínat.

Ta sekretářka chce pracovat s daty, nikoliv ovšem přímo s databázovým serverem. Je nejlepší pro ni připravit aplikaci, kde si nakliká co potřebuje a app si pak efektivně s pokecá s DB serverem.
xkucf03 avatar 16.3.2010 11:22 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše Re: neprocedurální
Je nejlepší pro ni připravit aplikaci, kde si nakliká co potřebuje a app si pak efektivně s pokecá s DB serverem.
Asi tak nějak. Chce to hlubší analýzu. Potřebou uživatele totiž není „filtrovat data z tabulky podle X různých kritérií“* – jeho potřebou je vyřešit nějaký „byznys“ problém. Takže je potřeba si udělat analýzu procesů** a zjistit, jaké je vlastně zadání. A pokud se dojde k tomu, že uživatel opravdu potřebuje ten multidimenzionální pohled na data a dolovat z nich předem neznámé skutečnosti, pak je to úloha pro ten OLAP, jak tu psal Pavel.

*) což si myslí programátor

**) přičemž se pravděpodobně zjistí, že spousta činností je prováděna naprosto zbytečně jen proto, že se to tak „vždycky dělalo“ (jenže tehdy ještě nebyly počítače a všechno se strkalo do šanonů a psalo se na stroji). Aneb přínos IT není v tom, že elektronizujeme staré procesy, ale že se pokusíme navrhnout nové, které využívají možností IT a jsou díky tomu efektivnější.
Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
okbob avatar 16.3.2010 10:58 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: neprocedurální
představte si, že se nemění obsah - jen pořadí řádků - což může být výsledkem kliknutí na záhlaví tabulky. Veškerá data máte lokálně - v recordsetu, v gridu tabulky, v cache. Pak změna řazení může být okázkou okamžiku, když bude implementována na klientu - kdežto dotaz na server znamená opakované provedení dotazu - při vytíženém SQL serveru potřebná data už nemusí být v cache, navíc tu je opakovaný přenos po síti.

Samozřejmě, že hodně záleží na tom jak hloupého nebo chytrého klienta máte, a jaké možnosti máte v byznys vrstvě. Pro jednoho nebo dva uživatele na serveru tyhle úvahy nemají velkou váhu, pro dvacet už se projeví určité rozdíly - a když chcete napsat aplikaci se kterou naráz pracuje víc než 100 lidí je nutné na to myslet. Jakákoliv cache hodně pomůže.
16.3.2010 12:42 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: neprocedurální
Problem je pak s nemoznosti invalidovat cache. Jak zjistit, jestli se zadny z nafetchovanych a najoinovanych radku od posledniho spusteni dotazu nezmenil? Musi se to resit treba tlacitkem "znovu nahrat", ktery provede kompletni reload misto jen zmeny razeni starych dat ...
okbob avatar 16.3.2010 12:57 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: neprocedurální
To není problém - většina serverů podporuje notifikaci.
xkucf03 avatar 16.3.2010 13:16 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše Re: neprocedurální
Když už jsi to nakousnul – půjde někdy v PostgreSQL posílat jakou součást zprávy nějaká data? Podle toho, jak vypadá JDBC ovladač, tak API je na to už částečně připravené – metoda getParameter(). Ale píše se tam:
Returns additional information from the notifying process. Currently, this feature is unimplemented and always returns an empty String.
Pak by bylo možné např. posílat triggerem zprávu o tom, že se změnil nebo přibyl záznam s určitým ID (pak je ještě otázka jak do toho napasovat data, kde máme složený PK – asi přes OID).

A taky: půjde někdy v JDBC čekat na události? Aby nebylo nutné se cyklicky dotazovat, zda už nějaká zpráva přišla. Zatím jsem totiž v dokumentaci našel:
A key limitation of the JDBC driver is that it cannot receive asynchronous notifications and must poll the backend to check if any notifications were issued.
V céčkové knihovně čekat na událost lze (i když způsobem, který mi přijde trochu dost nízkoúrovňový).

P.S. tak už jsem to našel v TODO – funkce přidání dat do zprávy by měla být už hotová :-)
Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
okbob avatar 16.3.2010 13:54 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: neprocedurální
V devítce lze určit kanál a zprávu

http://developer.postgresql.org/pgdocs/postgres/sql-notify.html

Pavel
16.3.2010 13:56 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: neprocedurální
Resi to skutecne ten problem? Mam SELECT s x JOINy a x WHERE. Dokazete efektivne rozhodnout, zda se vysledek tohoto dotazu nezmenil? Tedy napr., ze pridany radek do jedne z joinovanych tabulek (ne)splnuje joinovaci kriteria a podminky ve WHERE? Nebo naopak ze upraveny radek uz tyto kriteria nesplnuje?

Ja jsem to pochopil tak, ze NOTIFY se spousti rucne, napr. v triggeru. IMHO tohle z triggeru efektivne urcit nedokazete ...
okbob avatar 17.3.2010 06:14 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: neprocedurální
Pokud v dotazu měníte pouze ORDER BY, tak obsah musí být stejný - pouze v jiném pořadí. Trigger se spouští vždy nad konkrétní tabulkou - tudíž dokážete posílat notifikace - změnil jsem tabulku X. Na klientu pak postačí vymazat příslušnou cache - a další dotaz již pak jde na server. Pokud se pak klienti ozvou v krátkosti s požadavkem na stejná nebo podobná data, tak potřebáná data budou v cache - případně lze synchronizovat zpracování SQL příkazů a pro více klientů se načítají data naráz. Je to samozřejmě špička - ale ve skutečnosti mnohem menší, protože většina dat může být v cache.
16.3.2010 11:39 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: neprocedurální
Ale vy jste psal, že sekretářka nezná SQL. Určitě nejde jen o ten jazyk, ale i o přemýšlení v tabulkách, sloupcích a relacích.

Já neříkám, že to nemáte dělat SQL dotazem – ale ten SQL dotaz má vytvořit programátor a ne sekretářka.
16.3.2010 12:34 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: neprocedurální
No jiste. Programator vytvori sadu SQL dotazu, sekretarka si muze vybrat (nastavi filtr, vybere podle ceho se ma tabulka radit).
16.3.2010 12:37 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: neprocedurální
... ktery z nich pouzije.
16.3.2010 12:41 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: neprocedurální
K tomu už ale není potřeba dynamické skládání dotazů, že?
16.3.2010 12:51 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: neprocedurální
To samozrejme neni, jen to dramaticky usnadnuje:
$allowed_orderby = array("id" => 1, "name" => 1, "phone_number" => 1, "salary" => 1, "citizen_of" => 1);

if(!isset($allowed_orderby[$orderby]))
	$orderby = "id"; // default

$q->query("SELECT * FROM users ORDER BY %t", $orderby);
místo:
$queries = array(
	"id" => "SELECT * FROM users ORDER BY id",
	"name" => "SELECT * FROM users ORDER BY name",
	"phone_number" => "SELECT * FROM users ORDER BY phone_number",
	"salary" => "SELECT * FROM users ORDER BY salary",
	"citizen_of" => "SELECT * FROM users ORDER BY citizen_of",
);

if(!isset($queries[$orderby]))
	$orderby = "id"; // default

$q->query($queries[$orderby]);
Tohle je samozřejmě triviální příklad, s počtem "proměnných" roste počet konečných dotazů exponenciálně.
16.3.2010 13:35 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: neprocedurální
Podle mne je jedno, zda použiju mapu dotazů, uloženou proceduru, nahrazování parametru v řetězci nebo sečtení řetězců, jsou to jen různé zápisy téhož. Ale pod skládáním dotazů si představuju něco jiného.
16.3.2010 13:43 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: neprocedurální
Ano, prave ze je to jedno. Tim se to asi vysvetluje.

Co jste si tedy vy predstavil pod pojmem "skladani dotazu"?
16.3.2010 13:54 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: neprocedurální
To, že se bude měnit struktura dotazu – které tabulky se používají, podmínky apod.
16.3.2010 13:59 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: neprocedurální
To uz ale treba u jednoducheho filtru musite (JOIN na jinou tabulku navic, WHERE navic).
16.3.2010 14:20 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: neprocedurální
V případě, kdy je to použito rozumně, to stejně vede na omezenou množinu dotazů. Je pak jedno, zda opakující se části z těchto dotazů vytknete na jedno místo.
16.3.2010 14:23 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: neprocedurální
Ano, presne. V teto diskusi jsem mel na mysli jen skladani dotazu s omezenou mnozinou dotazu (myslel jsem, ze priklad v blogpostu byl dostatecne vymluvny ...).
16.3.2010 14:31 Filip Jirsák | skóre: 68 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: neprocedurální
Příklad v blogpostu podle mne vede na úplně jiný způsob skládání. Já mluvím o takovém „skládání“, které znamená jen vytknutí společných částí více dotazů. K tomu nepotřebujete žádnou knihovnu. To co máte jako příklad v blogpostu vy vede spíš k tomu, že si uživatel uplácá takřka libovolný dotaz – a to je špatně. Samozřejmě, záleží jak to programátor použije – ale pokud to použije jen pro dotazy, které mám na mysli, je to kanón na vrabce.
okbob avatar 16.3.2010 08:13 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: neprocedurální
A vy jako programátor si ověřujete, že všechny dynamicky generované dotazy jsou efektivní a nezablokují Vám db, že máte všude, kde je potřeba index, a nemáte jej tam, kde potřeba není?

Pokud pracujete s malými tabulkami, cca do 10 000 řádků, tak můžete pracovat tak jak navrhujete. S větším objemem dat byste napsal aplikaci, kdy jeden uživatel zadá debilní SQL příkaz a všichni další na serveru čekají až se uvolní sběrnice.

Pokud potřebujete absolutní dynamiku ohledně dotazů - pak je nutné použít OLAP databázi. Jinak vytvoříte bazmek, který je nepredikovatelně pomalý na nejnadupanějším hw.

Jiná možnost je vrátit uživateli určitou tabulku, a pak umožnit uživateli si nad touto tabulkou hrát - aniž by se zatěžoval server - pokud by ta tabulka byla cca do 1000 řádků, tak to zvládne i php bez problémů.

Při návrhu jakékoliv více-uživatelské aplikace je potřeba:
  • aplikace nesmí generovat pomalé dotazy
  • minimalizovat komunikaci mezi klientem a serverem (rozumný počet dotazu, rozumný objem výsledné tabulky
U dynamických dotazů nevím dopředu jak bude rychlý, a nevím ani jak bude velký výsledek. Takže dynamické dotazy ano, ale pouze pro triviální jednouživatelské aplikace.
15.3.2010 22:27 Ladicek | skóre: 28 | blog: variace | Havlíčkův brod
Rozbalit Rozbalit vše Re: neprocedurální
To je v zásadě veliký blábol vycházející z iracionálního přesvědčení, že deklarativní programování může fungovat. Kognitivní disonance par excellence.
Ještě na tom nejsem tak špatně, abych četl Viewegha.
17.3.2010 00:01 zulu
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Odpovědět | Sbalit | Link | Blokovat | Admin
Takže pokud to někdo nevěděl, tak tady se dozvěděl. Že Eddie a Filip jsou blázni.
17.3.2010 00:06 AHAHA | skóre: 7 | blog: ZZZ
Rozbalit Rozbalit vše Re: Query2 - minimalistický layer v PHP pro MySQL
Nevím, jestli to má nějaký smysl, ale zkusím to: proč?

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.