MYSQL SQL-Query Problem

ZeusZeus

Grünschnabel
Hi

ich habe folgendes Problem

ich habe folgende Tabellen

attribute
---------
id
attribut_name

Bsp:
1; haarfarbe;
2; augenfabe;


attribut_optionen
-----------------
id
attribut_id
option_name

Bsp:
1; gruen;
2; schwarz;


...udn weitere zuordnungstabellen

und jetzt gibts eine zuordnungstabelle

person_zu_attibut_und_option
-----------------------------
id
person_id
attribut_id
option_id

Bsp:
1; 1; 1; 1; /klartext - id 1; person 1; haarfarbe; grün;
2; 1; 2; 1; /klartext - id 2; person 1; augenfarbe; grün;
3; 2; 2; 2; /klartext - id 3; person 2; augenfarbe; schwarz;

so und jetzt möchte ich Personen suchen, die zb Haarfabe=schwarz haben.
das geht noch richtig schnell. (5ms)

doch wie kann ich nach mehreren Sachen suchen zb alle Personen die Haarfarbe=grün und Augenfarbe=grün haben?

In meinem Fall habe ich zb 1mio Einträge und die Suche dauert über 2 sek.

SELECT person_id, COUNT(person_id) anzahl
FROM person_zu_attibut_und_option
WHERE
(attribut_id=1 AND option_id=1) OR
(attribut_id=2 AND option_id=1)
GROUP BY person_id
HAVING anzahl=2

die Persormance geht durch das GROUP BY verloren, aber mit AND funktioniert es nicht, SubSelects sind noch langsamer und daher fällt mir nur diese Lösung ein.

Oder gibt es keine Möglichkeit und ich muss bei zb. 60 Attributten 60 Spalten anlegen?

Vielen Dank im Vorraus schon mal für Eure Hilfe.
 
Hi
Also eine kleine Frage

Eine option, nehmen wir die mit option_id=1 (also grün) ist ja immer einem Attribut über attribut_id zugewiesen.
Wie soll also eine Person mit option_id=1 beim Attribut 1 oder 2 haben? Das geht ihrgendwie nicht auf, oder?

Komisch:
SQL:
(attribut_id=1 AND option_id=1) OR 
(attribut_id=2 AND option_id=1)

Naja.. ansonsten ist das Modell einfach falsch (sorry, aber ist so..)
du hast ja eine Person, diese kann mehrere Attribute haben. Also kannst du nicht einen Verweis von Person auf Attribute setzen, sondern umgekehrt

also in etwa so (ich trenne jetzt attribut und option nicht - sehe den Sinn nicht)

tbl_atts
-----------
id
attkey #um welches Attribut es sich handelt 1=Haarfarbe, 2=Augenfarbe
attvalue #der Wert der das Att hat. 1=grün, 2=schwarz
fs_person #Fremdschlüssel zur Person

tbl_person
---------------
id
name
usw


um nun eine Person mitt Haar- und Augenfarbe=grün zu finden brauchst du folgende Abfrage:
SQL:
select name from tbl_person as p
inner join tbl_att as a1 on a1.fs_person=p.id and a1.attkey=1 and a1.attvalue=1
inner join tbl_att as a2 on a2.fs_person=p.id and a2.attkey=2 and a2.attvalue=1

so, ich hoffe dir damit geholfen zu haben

Gruss
jeipack

PS: Vergiss bei den Ids nicht die Indexe zu setzen (vorallem tbl_atts.fs_person und tbl_person.id sind wichtig)
 
Hi erst mal danke,

Die Zuordnung Attribut-Option muss schon sein,

Hier haste schon Recht, das sollte man nicht machen, habe ich auch nicht, die option_id's sind eindeutig, daher ist das hier nicht ganz richtig, habe ja auch nur ein vereinfachtes beispiel gepostet da normalerweise da noch Rechte,... mitspielen
jedoch gibts auch zuordnungen wie Person=1, Attribut=Lieblingsbands, Optionswert=Text...

(attribut_id=1 AND option_id=1) OR
(attribut_id=2 AND option_id=1)

Aber die Idee mit dem Inner Join ist schon mal topp, da braucht die Suche schon mal nur noch 300 ms. Ist halt ein "bissle" komplizierter dann die Suchabfrage zusammenzubauen bei zb. 10+ Suchangaben^^, aber PHP machts ja. Ich teste das mal und schau mal wie es dann mit der Performance aussieht.

(Indexe hab ich mit EXPLAIN schon nachgeschaut, greifen einwandfrei, er geht jetzt noch noch über ca. 9000 von 1mio Einträge bei 3 Suchangaben)

Also von daher schon mal vielen Dank
 

Neue Beiträge

Zurück