» »

Normalizirana struktura - query

Normalizirana struktura - query

BRBR ::

master
id
1
2
3
..


detail
id   data
1    A 
1    B
2    A
...


Kako naj izvem kater id ima lastnost A in B ?

WarpedGone ::

EXISTS
Zbogom in hvala za vse ribe

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?

Zgodovina sprememb…

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')
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) ?
select id,count(data) from detail
where data in (A,B)
group by id
having count(id) = 2


baza MySQL.

Zgodovina sprememb…

  • spremenil: BRBR ()

t3hn0 ::

COUNT ti prešteje rezultate, za izpis si lahko dodas kar sam ID
^.^

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.

BRBR ::

To vse jasno, ampak

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.
Zbogom in hvala za vse ribe

BRBR ::

kot rečeno zgoraj:

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.
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.

WarpedGone ::

Normalizacija je v nasprotju s hitrim delovanjem.
Zbogom in hvala za vse ribe

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.

Zgodovina sprememb…

WarpedGone ::

Vir?
10 let prakse na oracle bazi.
Zbogom in hvala za vse ribe

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:


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 ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

SQL pomoč

Oddelek: Programiranje
132412 (1826) miko22
»

sql, negacija ..

Oddelek: Programiranje
6723 (618) BRBR
»

MySQL pomoc

Oddelek: Izdelava spletišč
171873 (1129) slosi
»

[Sql] Poizvedba

Oddelek: Programiranje
111835 (1486) ales85
»

MYSQL vprašanje

Oddelek: Programiranje
131810 (1425) MrBrdo

Več podobnih tem