Autor | Zpráva | ||
---|---|---|---|
regy Profil |
#1 · Zasláno: 29. 5. 2012, 18:25:44
Ahoj,
nenapadlo mě žádné řešení, jak by následující věc šla vyřešit jedním dotazem. Proto prosím vás zkušenější o nastínění. mám např. tabulky: knihy ID | NAZEV ----------------- 1 | První knížka 2 | Druhá knížka knihyvlastnosti ATRIBUT | HODNOTA --------------------- pocetstran1 | 250 pocetstran2 | 79 cenaknizky1 | 20 Kč cenaknizky2 | 30 Kč Potřeboval bych výstup: ID | NAZEV | STRANY | CENA ---------------------------------- 1 | První knížka | 250 | 20 Kč 2 | Druhá knížka | 79 | 30 Kč Zkoušel jsem něco jako: SELECT knihy.id, knihy.nazev, knihyvlastnosti.atribut, knihyvlastnosti.hodnota FROM knihy, knihyvlastnosti WHERE (knihyvlastnosti.atribut = CONCAT('pocetstran', knihy.id ) OR text.id = CONCAT('cenaknizky', knihy.id )) To mi ale vrátí pro každou knihu dva řádky. Není tedy možnost, jak tyto řádky spojit do jednoho, když vždy budu vědět počet atributů v tabulce knihyvlastnosi? Pokud ne, spojím to pak v PHP, kdyby byla ale cesta i v mysql, bylo by to elegantní. Díky! |
||
pcmanik Profil |
Na spajanie sa pouziva GROUP BY.
Mas zle navrhnutu tu strednu tabulku, malo by to byt neico na sposob: id_knihy, pocet_stran, cena Potom ziskas vystup jednoducho SELECT id, nazev, pocet_stran, cena WHERE id = id_knihy |
||
Tori Profil |
#3 · Zasláno: 29. 5. 2012, 18:53:33
DB mi připadá nevhodně navržená, počet stran a cena jsou vlastnosti buď knihy, nebo konkrétního vydání, patří tedy k němu. Podle toho, jestli chcete rozlišovat různá vydání nebo ne, může být návrh buď:
-- tabulka knihy -- id knihy (int, auto increment, primární klíč) id autora (int, klíč) název (varchar) počet stran (smallint) cena (smallint) ... případně jazyk, URL obrázku titulní strany atd. -- tabulka knihy -- id knihy (int, auto increment, primární klíč) id autora (int, klíč) název (varchar) -- tabulka vydani -- id vydání (int, auto increment, primární klíč) id knihy (int, klíč) počet stran (smallint) cena (smallint) ... případně jazyk, URL obrázku titulní strany atd. |
||
regy Profil |
#4 · Zasláno: 29. 5. 2012, 19:01:05
pcmanik:
Díky, group by znám, ale nevím jak to spojit, aby mi nevypadla jedna z hodnot. pcmanik, Tori: Je to modelový příklad, v původním návrhu tato databáze smysl má. Díky za snahu, ptal jsem se jak získat požadovaný výsledek z těchto tabulek a ne jak přenavrhnout databázi ;-). |
||
Tori Profil |
regy:
„v původním návrhu tato databáze smysl má“ Ale aspoň by se měly oddělit název vlastnosti a ID knihy do dvou sloupců, takhle si komplikujete SQL dotazy i zpracování výsledků. Pokud tedy takto, tak bych nepoužila GROUP BY, ale jen ORDER BY knihy.id a zpracovala to až v PHP. Buď jedním dotazem načíst vše, anebo prvním dotazem jen data z tabulky knihy a druhým dohledat vlastnosti podle ID. Koukněte se na článek Srovnání dotazů do závislých tabulek.
edit: Jsem ten předchozí příspěvek napsala asi příliš kategoricky, tak pardon. |
||
regy Profil |
Tori:
Přesně nad tím, zda jsem neměl už na začátku rozdělit jakýsi prefix a id dané skupiny parametrů, jsem se po Tvojí reakci také zmyslel. Vzhledem k tomu, že do databáze míří ale většinou dotaz na konkrétní záznam a ne třeba jen na všechny LIKE "pocetstran%", asi to nevadí. Používám tuto tabulku v celém systému na veškeré texty, které jsou multijazykové. Použil jsme jednu tabulku na všechny překládané texty hlavně kvůli budoucímu návrhu vyhledávání, které skoro na všech webech, které jsi ho řeší sami, nehledá ve všech částech webu, ale třeba jen v článcích apod. To, jestli to bylo šťastné řešení po čase nakonec zjistím sám. Pro menší weby do stovek článků nebo různých stránek (což je většina zakázek) je toto řešení elegantní a rs nemusí mít sto tabulek, jako některé redakční systémy. Děkuju za článek. Myslím, že dotazy ze začátku podceňuje hodně lidí. Já na to také přišel až u webu se 100MB databázemi :-). edit: Mou předchozí odpověď jsem zase já napsal příliš arogantně a povýšeně. Omlouvám se dámě ;-). |
||
nototo Profil * |
#7 · Zasláno: 29. 5. 2012, 23:21:58
SELECT knihy.id, knihy.nazev, strany, cena FROM knihy JOIN (SELECT REPLACE(atribut, 'pocetstran', '') AS id, hodnota AS strany FROM knihyvlastnosti) AS temp1 ON temp1.id = knihy.id JOIN (SELECT REPLACE(atribut, 'cenaknizky', '') AS id, hodnota AS cena FROM knihyvlastnosti) AS temp2 ON temp2.id = knihy.id WHERE knihy.id = 1 zkus tohle .. vypadá to hrozně, ale mohlo by to fungovat :) |
||
regy Profil |
#8 · Zasláno: 30. 5. 2012, 23:59:53
nototo:
Děkuju, funguje. Když jsem ale viděl, že i bez dat to trvá 4x déle než dotaz vracející 2 řádky pro jeden záznam, asi to ošetřím v php. Ale děkuju za rošíření obzorů! |
||
Kajman Profil |
#9 · Zasláno: 31. 5. 2012, 00:10:12
regy:
Ale o tom je to přesvědčování v celém vlákně. Když budete mít ten primární klíč jako kombinaci těch dvou sloupců nesplácnutých do sebe, tak budete mít aplikaci svižnější. |
||
regy Profil |
#10 · Zasláno: 31. 5. 2012, 00:16:46
Kajman:
Jo jo, máte pravdu, zase mi to pak ale zesložití dotazy na všech ostatních místech. Tušení, že ať zvolím tak, či onak, později by se mi více hodila druhá varianta, ve mě zároveň ale vyvolává tendence nechat to tak, jak to je. Každopádně děkuju všem za náměty, stále je co zlepšovat ;-). Dá se tedy říct, že zabere hodně času příkaz replace oproti contact? Díky |
||
Kajman Profil |
#11 · Zasláno: 31. 5. 2012, 00:18:40
regy:
„ale zesložití dotazy na všech ostatních místech“ Kdepak, oprava je na chviličku, žádné složitosti nejsou potřeba (oproti tomuto hrůznému řešení ;) |
||
Tori Profil |
#12 · Zasláno: 31. 5. 2012, 00:21:26
regy:
V nějakých jiných tabulkách máte taky uložené jako cizí klíč ten složený zápis "atributID"? |
||
regy Profil |
Kajman:
No ale na tabulku jsou napojeny i všechny ostatní dotazy, které hledají nějaký text pro vypsání a pro ty je tento návrh akorát, protže vždy hledají konkrétní záznam (podmínka je tedy vždy atribut = "neco$promenna"). Až teď jsem narazil. Zkusil jsem smazat replace a přidat contact do podmínky, ale rychlost je pořád stejná :-(. Edit: běží mi na tom celý redakční systém, teď dělám jen modul pro katalog produktů Tori: V jiných tabulkách ne, jen v téhle, ale dotazuje se na to ze spoustu míst, kde bych to musel opravovat jen kvůli jendomu modulu. Ale asi jste mě všichni udolali. Asi to má smysl. |
||
nototo Profil * |
#14 · Zasláno: 31. 5. 2012, 08:14:22
Smysl to určitě má. Potom se vyhneš přesně takovýhmle šílenostem a hrůzným řešením, které Ti teď vznikají díky špatnému návrhu struktury databáze.
|
||
regy Profil |
#15 · Zasláno: 31. 5. 2012, 10:15:38
nototo:
Uvidíme. Změnu jsem provedl, ale zatím se změna projevila jen tak, že se mi zvětšil index :-). |
||
Časová prodleva: 12 let
|
0