Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Idee/Lösungsansatz gesucht

5 views
Skip to first unread message

Harald Stowasser

unread,
Aug 19, 2010, 6:20:26 AM8/19/10
to
Stefan Gläßer schrieb:
> Hallo,
>
> ich habe hier eine Datenbank (MySQL) mit ca. 10000 Artikeln. Diese
> Artikel sind durch verschiedene Attribute gekennzeichnet (Größe,
> Farbe, Hersteller, Preis etc.pp.).
>
> Ich möchte gerne eine komfortable Suchmöglichkeit basteln, mit der ich
> durch den gesamten Warenbestand navigieren kann und dabei meine
> Suchgebnisse immer weiter verfeinern kann. Eben so, wie man es von den
> großen alá Amazon oder eBay eben kennt.
>
> Mir fehlt jetzt nur noch die zündende Idee, wie man das ganze sinnvoll
> implementiert, so dass es auch bei möglichst 1.000.000 Artikeln noch
> gut funktioniert. Die Datenbank liegt in 3. Normalform vor, es sind
> also sämtliche Attribute über 1:n und m:n Beziehungen "ausgelagert".

Logische Verknüpfungen in M:N Tabellen kannst du auf 2 Arten realisieren:

*AND by X-Join*
SELECT a.user_id
FROM user_attribut a, user_attribut b
WHERE a.attribut_id=2 AND b.attribut_id=5
AND a.user_id=b.user_id

*AND by having*
SELECT user_id,count(user_id) as anz
FROM user_attribut
WHERE attribut_id in(2,5)
GROUP BY user_id HAVING anz=2

Wobei zu sagen währe das ein X-Join meist schneller ist, und auch noch
andere logische Verknüpfungen zulässt.

Allerdings bei 1.000.000 Artikeln währe es Ratsam noch eine weitere
Einschränkung in die M:N-Tabelle einzubauen. (Etwa eine Kategorie). Da
bei hoher Selektivität der Attribute, die Abfragen schon etwas dauern
können.
Effiziente Indiezes sind hier natürlich sehr wichtig.

> Kann mir jemand ein evlt. ein paar brauchbare Lösungsansätze liefern?
> Oder auch ein paar SuMa(Google)-Links?

Eine richtiges Suchmaschinen-Framework währe z.B. Lucene. Mit der
php-Implementation, welche im ZEND-Framework enthalten ist, habe ich
aber schlechte Erfahrungen. Diese hatte unter php 5.2 erhebliche
Speicherprobleme. Und war schon mit einem relativ geringen Datenbestand
nicht mehr benutzbar.

Allerdings ist die Originale Java-Implementation davon sehr zu empfehlen.


Achtung! Ich setzte hier einen Xpost und Fup nach dclpd, da das ganze
IMHO dort besser aufgehoben ist.


Grüße,
Harald

Claus Reibenstein

unread,
Aug 19, 2010, 7:36:29 AM8/19/10
to
Harald Stowasser schrieb:

> SELECT a.user_id
> FROM user_attribut a, user_attribut b
> WHERE a.attribut_id=2 AND b.attribut_id=5
> AND a.user_id=b.user_id

Ich bevorzuge mittlerweile "echte" JOINs:

SELECT a.user_id
FROM user_attribut a JOIN user_attribut b ON a.user_id = b.user_id
WHERE a.attribut_id = 2 AND b.attribut_id = 5

> SELECT user_id,count(user_id) as anz
> FROM user_attribut
> WHERE attribut_id in(2,5)
> GROUP BY user_id HAVING anz=2

Das geht auch ohne das teure HAVING:

SELECT user_id, COUNT(user_id) AS anz
FROM user_attribut
WHERE attribut_id IN (2,5) AND COUNT(user_id) = 2

Allerdings frage ich mich gerade, was das alles mit PHP zu tun hat.

Gruß. Claus

Stefan Dreyer

unread,
Aug 19, 2010, 8:39:32 AM8/19/10
to
Am 19.08.2010 13:36, schrieb Claus Reibenstein:
> Harald Stowasser schrieb:
>
>> SELECT a.user_id
>> FROM user_attribut a, user_attribut b
>> WHERE a.attribut_id=2 AND b.attribut_id=5
>> AND a.user_id=b.user_id
>
> Ich bevorzuge mittlerweile "echte" JOINs:
>
> SELECT a.user_id
> FROM user_attribut a JOIN user_attribut b ON a.user_id = b.user_id
> WHERE a.attribut_id = 2 AND b.attribut_id = 5

Ich auch, denn ansonsten muss man die Query spätestens dann umbauen,
wenn z.B. ein LEFT JOIN dazu kommt.

>> SELECT user_id,count(user_id) as anz
>> FROM user_attribut
>> WHERE attribut_id in(2,5)
>> GROUP BY user_id HAVING anz=2
>
> Das geht auch ohne das teure HAVING:
>
> SELECT user_id, COUNT(user_id) AS anz
> FROM user_attribut
> WHERE attribut_id IN (2,5) AND COUNT(user_id) = 2

Komisch, ich bekomme da "Invalid use of group function". Selbst mit
angefügtem GROUP BY user_id.

> Allerdings frage ich mich gerade, was das alles mit PHP zu tun hat.

Du musst das im Kontext sehen ;-P

Helmut Chang

unread,
Aug 19, 2010, 9:55:32 AM8/19/10
to
Claus Reibenstein schrieb:

>> SELECT user_id,count(user_id) as anz
>> FROM user_attribut
>> WHERE attribut_id in(2,5)
>> GROUP BY user_id HAVING anz=2
>
> Das geht auch ohne das teure HAVING:
>
> SELECT user_id, COUNT(user_id) AS anz
> FROM user_attribut
> WHERE attribut_id IN (2,5) AND COUNT(user_id) = 2

Nein, eben nicht. IIRC ist das, weil WHERE ausgewertet werden muss,
*bevor* die Ergebnismenge feststeht, wäre ja auch logisch, weil es dazu
benötigt wird, *um* die Ergebnismenge zu ermitteln.

Eine Aggregatfunktion kann aber dann erst auf die Ergebnismenge
angewendet werden. Deswegen gibt es ja HAVING.

Gruß, Helmut

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

Claus Reibenstein

unread,
Aug 19, 2010, 10:11:32 AM8/19/10
to
Helmut Chang schrieb:

> Eine Aggregatfunktion kann aber dann erst auf die Ergebnismenge
> angewendet werden. Deswegen gibt es ja HAVING.

Stimmt. Habe die entsprechende Stelle im Handbuch gefunden:

,----------[MySQL 5.1 Referenzhandbuch, 13.2.7 SELECT]
| Die HAVING-Klausel kann Zusammenfassungsfunktionen referenzieren, was
| der WHERE-Klausel nicht möglich ist
`----------

War mir noch nicht bekannt. Nun ja, wieder was gelernt :-)

Gruß. Claus

0 new messages