Forum » Programiranje » Normalizirana struktura - query
Normalizirana struktura - query
BRBR ::
master
detail
Kako naj izvem kater id ima lastnost A in B ?
id 1 2 3 ..
detail
id data 1 A 1 B 2 A ...
Kako naj izvem kater id ima lastnost A in B ?
technolog ::
SELECT COUNT(DISTINCT data)=2 FROM detail WHERE id=(željeni id)
in dobiš 1 za tiste ki vsebujejo dve lastnosti in 0 za tiste, ki ne. Če hočeš pa preverjat prov za A in B, ne za točno dve, potem je stavek malo počasnješi
SELECT COUNT(DISTINCT data)=2 FROM detail WHERE id=(željeni id) AND data IN (A,B)
Ista stvar tudi tokrat.
@WaepedOne: EXISTS? Kako bi ti to naredil?
in dobiš 1 za tiste ki vsebujejo dve lastnosti in 0 za tiste, ki ne. Če hočeš pa preverjat prov za A in B, ne za točno dve, potem je stavek malo počasnješi
SELECT COUNT(DISTINCT data)=2 FROM detail WHERE id=(željeni id) AND data IN (A,B)
Ista stvar tudi tokrat.
@WaepedOne: EXISTS? Kako bi ti to naredil?
Zgodovina sprememb…
- spremenil: technolog ()
WarpedGone ::
SELECT * FROM master m
where exists (Select 1 FROM detail d WHERE d.id = m.id = d.X = 'A')
and exists (Select 1 FROM detail d WHERE d.id = m.id = d.X = 'B')
where exists (Select 1 FROM detail d WHERE d.id = m.id = d.X = 'A')
and exists (Select 1 FROM detail d WHERE d.id = m.id = d.X = 'B')
Zbogom in hvala za vse ribe
BRBR ::
Od WarpedOne dela, sam problem je da je teh A,B,... x in zna bit to verjetno počasno.
Koda od tehnolog tudi dela, samo ne vrne pravih rezultatov, vedno samo en record. Ne najdem kaj naj bi "COUNT(DISTINCT data)=2", počel,
predvidevam pa da naj bi to bila bližnjica do tegale(kar tud dela in vrne prave rezultate) ?
baza MySQL.
Koda od tehnolog tudi dela, samo ne vrne pravih rezultatov, vedno samo en record. Ne najdem kaj naj bi "COUNT(DISTINCT data)=2", počel,
predvidevam pa da naj bi to bila bližnjica do tegale(kar tud dela in vrne prave rezultate) ?
select id,count(data) from detail where data in (A,B) group by id having count(id) = 2
baza MySQL.
Zgodovina sprememb…
- spremenil: BRBR ()
technolog ::
Ja, moja koda ne deluje, ker sem narobe razumel tvojo nalogco :) Jaz sem misli da rabiš za določen id preverit, če vsebuje A in B, ne pa izpisat vse take IDje. Tole bo šlo:
SELECT id FROM detail WHERE data IN (A,B) GROUP BY id HAVING COUNT(DISTINCT data)=2
Tole je zdele mendezdi prov, lahko je kje kaka sitaktična niansa... Priporočam ti DISTINCT, ker če se ti slučajno kje zgodi, da imaš dva zapisa, ki sta ista, ne bo izbral tega IDja, čeprav bi ga na navodilo naloge moral.
id data
1 B
1 B
1 A
Tukaj je COUNT(data)=3 in COUNT(DISTINCT data)=2.
Je pa tale metoda boljša, če imaš več kot samo A in B, ker pride krajši in bolj pregleden query.
SELECT id FROM detail WHERE data IN (A,B) GROUP BY id HAVING COUNT(DISTINCT data)=2
Tole je zdele mendezdi prov, lahko je kje kaka sitaktična niansa... Priporočam ti DISTINCT, ker če se ti slučajno kje zgodi, da imaš dva zapisa, ki sta ista, ne bo izbral tega IDja, čeprav bi ga na navodilo naloge moral.
id data
1 B
1 B
1 A
Tukaj je COUNT(data)=3 in COUNT(DISTINCT data)=2.
Je pa tale metoda boljša, če imaš več kot samo A in B, ker pride krajši in bolj pregleden query.
BRBR ::
To vse jasno, ampak
OFFTOPIC
zakaj deluje
kot je napisal technolog, pa četudi se je samo za copy/pastal.
in kaj potem rezultat pomeni.
Če je COUNT(DISTINCT data)=2 v having delu mi je kajpak jasno kaj to je.
OFFTOPIC
zakaj deluje
SELECT COUNT(DISTINCT data)=2
kot je napisal technolog, pa četudi se je samo za copy/pastal.
in kaj potem rezultat pomeni.
Če je COUNT(DISTINCT data)=2 v having delu mi je kajpak jasno kaj to je.
Zgodovina sprememb…
- spremenil: BRBR ()
WarpedGone ::
Od WarpedOne dela, sam problem je da je teh A,B,... x in zna bit to verjetno počasno.
1. pravilo: hitrost ni problem dokler ni problem
2. pravilo: jasnost/enostavnost imata prednost pred hitrostjo
Exists je načeloma "počasen", je pa zelo odvisno kaj mora počet. Če je v njem relativno enostaven SQL, ki štarta na indeksirano polje njegova hitrost ni problematična - je praktično enako hiter kot "self-join", ker se zelo podobno izvaja.
Po drugi strani znajo bit tudi DISTINCT pa HAVING nepričakovano počasni, sploh če je mal več outputa in mora komplet rezultat interno keširat v začasnih tabelah kjer stvari sfiltrira in šele nato vrne.
zakaj deluje
SELECT COUNT(DISTINCT data)=2
Tole vrne TRUE/FALSE al pa napako, če konkretna baza tega morda ne prebavi.
Zbogom in hvala za vse ribe
technolog ::
Ni res, ni počasno. Če imaš index na detail.id, je group by po id hiter, data polj je pa itak malo. V bistvu je hitrost ista, kot z exsist stavki, le da če imaš recimo izbor 100 črk nimaš "en mega" velikega query-a.
WarpedGone ::
Ja, mega querry je problematičen z EXISTS, po drugi strani pa tut 100 členov v obliki A IN (1,2,3,...,100) ni višek preglednosti :)
Brez konkretnega primera se lahk preklama do onemoglosti, stuhtala pa ne boma nič pametnega.
Brez konkretnega primera se lahk preklama do onemoglosti, stuhtala pa ne boma nič pametnega.
Zbogom in hvala za vse ribe
BRBR ::
kot rečeno zgoraj:
A,B,... so pri meni cifre tko da je tega lahko neomejeno, trenutno je možnih x of izbora približno tridesetih na 1 id. Id- jev je pa zdaj okol 6000
Sice mi vse obratuje samo je počasno, pa malo študiram kako bi drugače. Distinct ni treba ker mam indexe tko postavljene da duplikatov sploh ne pusti vnest.
sam problem je da je teh A,B,... x ...
A,B,... so pri meni cifre tko da je tega lahko neomejeno, trenutno je možnih x of izbora približno tridesetih na 1 id. Id- jev je pa zdaj okol 6000
Sice mi vse obratuje samo je počasno, pa malo študiram kako bi drugače. Distinct ni treba ker mam indexe tko postavljene da duplikatov sploh ne pusti vnest.
Zgodovina sprememb…
- spremenil: BRBR ()
WarpedGone ::
Počasen je konkreten querry ki ugotavlja ali ima nek ID zahtevane A,B... al kaj drugega?
Ker če je to počasno, potem so možne variante kjer te IDje sestavljaš.
Praviš da so cifre, na nivoju master zapisa lahko dodaš neko polje FLAGS tipa STRING, katero se usklajuje avtomatsko ob insert,delete,update v detail tabelo.
Recimo, če pa nek ID v detail tabeli vrednosti 1,5,7,9 potem je polje flags 1,5,7,9.
In namesto da vsakič posebej češeš detail tabelo nardiš enostavno select * from master where flags = '1,5,7,9'. Tle gor počiš še index in zadeva leti.
Ker če je to počasno, potem so možne variante kjer te IDje sestavljaš.
Praviš da so cifre, na nivoju master zapisa lahko dodaš neko polje FLAGS tipa STRING, katero se usklajuje avtomatsko ob insert,delete,update v detail tabelo.
Recimo, če pa nek ID v detail tabeli vrednosti 1,5,7,9 potem je polje flags 1,5,7,9.
In namesto da vsakič posebej češeš detail tabelo nardiš enostavno select * from master where flags = '1,5,7,9'. Tle gor počiš še index in zadeva leti.
Zbogom in hvala za vse ribe
technolog ::
Tega naj ne bi delal, je v nasprotju s pravili normalizacije. Če že, potem uporabit BIT tip polje.
technolog ::
Ne vem, če lahko podpreš tole z virom...
Ampak - pravila normalizacije se lahko kršijo z res utemeljenimi razlogi :) In še to zgolj 3. in 4. NO.
Ampak - pravila normalizacije se lahko kršijo z res utemeljenimi razlogi :) In še to zgolj 3. in 4. NO.
Zgodovina sprememb…
- spremenil: technolog ()
BRBR ::
WarpedGone je izjavil:
Počasen je konkreten querry ki ugotavlja ali ima nek ID zahtevane A,B... al kaj drugega?
Ker če je to počasno, potem so možne variante kjer te IDje sestavljaš.
Praviš da so cifre, na nivoju master zapisa lahko dodaš neko polje FLAGS tipa STRING, katero se usklajuje avtomatsko ob insert,delete,update v detail tabelo.
Recimo, če pa nek ID v detail tabeli vrednosti 1,5,7,9 potem je polje flags 1,5,7,9.
In namesto da vsakič posebej češeš detail tabelo nardiš enostavno select * from master where flags = '1,5,7,9'. Tle gor počiš še index in zadeva leti.
Ja zdaj mam nekaj takega samo da nimam zadevnega polja , ampak uporabljam group_concat od mysql.
Sicer pa, glede normalizacije
master
id obvezen_podatek_ki_ni_nikoli_null 1 recimo width slike v galeriji 1 2 recimo width slike v galeriji 2 ....
detail - lastnosti objekta na sliki, recimo da so to gobe
id opcijski_podatek 1 na lesu 1 nima beta 2 na lesu ....
v primeru da tole ne bi bilo normalizirano, pol je iskanje simpel (gob, ki so na lesu in brez beta). Vprašanje je le kolk indeksov bi bilo potem treba imet za hitro iskanje.
ker pa je normalizirano pa moram najprej select iz detail (v smislu kot v prejšnjih postih) in nato join nazaj na master, zato da dobim zraven še width od slike
Drgač pa speed je precej odvisen od baze. Kar (specifičemn primer) npr. mssql naredi za tren oka, MySql melje in melje ......
Zgodovina sprememb…
- spremenil: BRBR ()
BRBR ::
evo, eno podvprašanje:
tole vrne natančno to kar hočem se pravi id_galery 1 in 2:
kako naj izključim iz resultseta id_galery 1 zato ker je ta tudi 'green' ?
Lahko joinam nazaj na isto tabelo in dela, ampak a je kaka rešitev brez joina.
id_galery color 1 blue 1 red 1 green 2 blue 2 red
tole vrne natančno to kar hočem se pravi id_galery 1 in 2:
select id_galery,count(id_galery), from galery_optional_inf where color in ('blue','red') group by id_galery having count(color) = 2
kako naj izključim iz resultseta id_galery 1 zato ker je ta tudi 'green' ?
Lahko joinam nazaj na isto tabelo in dela, ampak a je kaka rešitev brez joina.
Zgodovina sprememb…
- spremenil: BRBR ()
frudi ::
select id_galery, count(id_galery) from galery_optional_inf as g where color in ('blue', 'red') and not exists( select null from galery_optional_inf as g1 where g.id_galery = g1.id_galery and g1.color not in ('blue', 'red')) group by id_galery having count(color) = 2
Bo pa query optimizer verjetno zgeneriral enak plan, kot za join; tako je izbira 'not exists' ali join stvar preference, kaj ti je bolj berljivo in razumljivo.
1ACDoHVj3wn7N4EMpGVU4YGLR9HTfkNhTd... in case I've written something useful :)
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | SQL pomočOddelek: Programiranje | 2412 (1826) | miko22 |
» | sql, negacija ..Oddelek: Programiranje | 723 (618) | BRBR |
» | MySQL pomocOddelek: Izdelava spletišč | 1873 (1129) | slosi |
» | [Sql] PoizvedbaOddelek: Programiranje | 1835 (1486) | ales85 |
» | MYSQL vprašanjeOddelek: Programiranje | 1810 (1425) | MrBrdo |