ugrás a tartalomhoz

Összetett keresés MySQL-ben

KundK · 2007. Nov. 23. (P), 15.17
Sziasztok!

A következő problémára keresek elsősorban MySQL megoldást.

Van három táblám:
1. pict (pict_id, pict_name)
2. tag (tag_id, tag_name)
3. rel (tag_id, pict_id)
A 3. tábla egy N-N kapcsolatot definiál, tehát minden tag-hez több pict tartozhat és minden pict-hez több tag.
Ez idáig teljesen mindennapi.

Szeretnék olyan lekérdezést gyártani, ami a rel táblából kiszedi az összes olyan pict-et, ami egy tag halmaz összes eleméhez tartozik (AND kapcsolat).
Meg tudom ezt egy (legalábbis konstans) lekérdezéssel oldani? Ciklussal persze egyértelmű, de az jelentősen növelheti a futásidőt még tárolt eljárás esetén is.
Ha további táblák bevezetése segíthet a munkámon, akkor lehetséges a bevezetésük.

köszi
zsolt
 
1

in, group, having

vbence · 2007. Nov. 24. (Szo), 11.48
Tételezzük fel, hogy a akeresett tagek id-i: 23, 24, 25 és 33 ami összesen 4 darab

SELECT pict_id, count(pict_id) AS szam FROM rel WHERE tag_id IN (23, 24, 25, 33) GROUP BY pict_id HAVING szam=4;
Kikeressük az összes tagelést, ami a keresett tagekre vonatkozik, majd group-oljuk őket pict_id szerint, ahol 4 darab van, az mindegyik tagbe beleesett. Picit lassú, de más megoldás most nem jut eszembe.
2

többtáblás

vbence · 2007. Nov. 24. (Szo), 16.15
Egy másik megoldás alias-alapon:
select a.pict_id from rel as a, rel as b, rel as c, rel as d where b.pict_id=a.pict_id and c.pict_id=a.pict_id and d.pict_id=a.pict_id and a.tag_id=23 and b.tag_id=24 and c.tag_id=25 and d.tag_id=33
Kérdés, hogy melyik a gyorsabb... ki kell próbálni. Ami mindenképpen ajánlott: indexeld be atáblát, azt, hogy pontosan mi szerint indexelj egy nagyon bunkó módszerrel elég pontosan ki lehet találni: hozzál létre indexeket keresztül-kasul:

create index search1 on rel (pict_id);
create index search2 on rel (tag_id);
create index search3 on rel (pict_id, tag_id);
create index search4 on rel (tag_id, pict_id);
...aztán az EXPLAIN SELECT ... megmondja, hogy melyik indexeket használja, a többit törölheted, mert csak a helyet foglalják (és lassítják a beszúrást).

Kipróbálhatod a fenti aliasos példát join-al is, bár nem hinném, hogy lényeges különbség van, de azért ki tudja...