PHP.EE FOORUM   
Nimi:   Pass:   Mäleta mind! 
   Teemad | php.ee esilehele | registreeri | Märgi kõik teemad loetuks | #php.ee Skype vestlus | RSS
UUS TEEMA  OTSI  Lehekülgi: 1
raske juhus mysqliga
Postitaja: onu heino 2013-03-19 15:47:14
On 3 mysql tabelit, mis seovad omavahel artiklid ja teemad (üks artikkel on seotud mitme teemaga):

ARTIKLID:
ID | nimi
-------
1 | esimene
2 | teine
3 | kolmas

TEEMAD
tid | lisanimi
------------
1 | loodus
2 | teadus
3 | kunst
4 | muusika
5 | poliitika

SEOSED
art_id|teema_id
---------------
1 | 1
1 | 2
2 | 1
2 | 2
2 | 3
2 | 4
3 | 2
3 | 4


Seega nt artikkel 1 ("esimene") on seotud teemadega "loodus" (1) ja "teadus" (2).

Kui ma otsin artikleid, mis on seotud AINULT loodusteemaga, siis teen päringu

SELECT id,nimi FROM ARTIKLID AS A, SEOSED AS S
WHERE A.id=S.art_id AND S.teema_id = 1

ja saan artiklid nr 1 ja 2


Kui vaja artikleid, mis seotud kas loodus- VÕI teadusteemaga, siis

SELECT id,nimi FROM ARTIKLID AS A, SEOSED AS S
WHERE A.id=S.art_id AND S.teema_id IN (1,2)

saan artiklid 1,2,3


KÜSIMUS: Kuidas ma saaks kätte kõik artiklid mis on seotud KÕIKIDE otsitavate teemadega? Näiteks tahan teada artiklit, mis on seotud teemadega 1,2,3 - see oleks siis ainult artikkel nr 2. Aitaks ka see, kui saaks kõikide teemadega seotud artiklid ettepoole sorteerida.

Teemasid on tegelikult 40 ringis, artikleid ca 10 000, seega tahaks ühe mõistliku päringuga soovitud artiklid kätte saada :)

Hetkel on ainus kole idee, et panen iga artikli juurde kirja tema teemade numbrid nt VARCHAR väljale "teemad" komadega eraldatult ja siis saan päringu teha ainult artiklite tabeli põhjal:
WHERE teemad LIKE ',1,' AND teemad LIKE ',2,'
jne...

Tänud, kui kaasa mõtlete, mul on ilmselt juhe kinni jooksnud :)
RE: raske juhus mysqliga
Postitaja: ise php 2013-03-19 15:52:36
Kas ongi nii halb mõte? Seoste tabel ehk üldse liiast.
RE: raske juhus mysqliga
Postitaja: onu heino 2013-03-19 16:31:10
Halb tundub see mõte sellepärast, et kui ma tahan nt loendada ära kui mitu artiklit iga teemaga on seotud, siis teen praegu lihtsalt ühe päringu:
SELECT COUNT(*) as kokku, teema_id FROM SEOSED GROUP BY teema_id

Kui teemad oleks artiklite tabelis VARCHAR väljal, siis peaksin ma tsüklis kõik teemad läbi käima ja küsima iga teema kohta eraldi
SELECT COUNT(*) FROM ARTIKLID WHERE teemad LIKE '%,' . $teema_id . ',%'

Ja seoste massiline lisamine ja eemaldamine on kah sel juhul aeglasem... muidugi teisalt jääb artikli avamisel ära lisapäring, mis küsib milliste teemade alla ta kuulub. Nokk kinni, saba lahti.

Ootaks veel arvamusi :)
RE: raske juhus mysqliga
Postitaja: atw 2013-03-19 16:56:09
LIKE on otsetee sohu. Sa saad selle asemel sama tabeli mitu korda siduda:
... FROM ARTIKLID AS A, SEOSED AS S1, SEOSED S2, SEOSED S3 WHERE ...


Kohenda WHERE osa ka vastavaks: WHERE (A.id=S1.art_id AND S1.teema_id IN (1,2)) AND (A.id=S2.art_id AND S2.teema_id IN (1,2)) AND ...

Viimati muudetud: 19-03-2013 16:57:55
Muutja: atw
Põhjus:

RE: raske juhus mysqliga
Postitaja: Lost in scope 2013-03-19 18:43:44
TSITEERITUD:
Halb tundub see mõte sellepärast, et kui ma tahan nt loendada ära kui mitu artiklit iga teemaga on seotud, siis teen praegu lihtsalt ühe päringu:
SELECT COUNT(*) as kokku, teema_id FROM SEOSED GROUP BY teema_id

Kui teemad oleks artiklite tabelis VARCHAR väljal, siis peaksin ma tsüklis kõik teemad läbi käima ja küsima iga teema kohta eraldi
SELECT COUNT(*) FROM ARTIKLID WHERE teemad LIKE '%,' . $teema_id . ',%'

Ja seoste massiline lisamine ja eemaldamine on kah sel juhul aeglasem... muidugi teisalt jääb artikli avamisel ära lisapäring, mis küsib milliste teemade alla ta kuulub. Nokk kinni, saba lahti.

Ootaks veel arvamusi :)

Vota aluseks Oma seoste table, ja joini sinna kylge Oma reaalsed tabelid.
RE: raske juhus mysqliga
Postitaja: gaal_ 2013-03-19 18:56:20
Ei ole reaalselt üle kontrollinud, aga vast idee saad :

SELECT art_id , COUNT(teema_id)
FROM SEOSED
GROUP BY art_id
HAVING COUNT(teema_id) = 5
RE: raske juhus mysqliga
Postitaja: onu heino 2013-03-19 23:30:22
TSITEERITUD:

... FROM ARTIKLID AS A, SEOSED AS S1, SEOSED S2, SEOSED S3 WHERE ...



Ok, kuigi minu mysql 5.0.51 ei lubanud numbritega aliaseid panna, seega panin lihtsalt tähed ... AS B, ... AS C jne


TSITEERITUD:

Kohenda WHERE osa ka vastavaks: WHERE (A.id=S1.art_id AND S1.teema_id IN (1,2)) AND (A.id=S2.art_id AND S2.teema_id IN (1,2)) AND ...



Njah, idee tundus hea, aga pärast sellist päringut:

SELECT id, nimi FROM artiklid AS A, seosed AS B, seosed AS C, seosed AS D, seosed AS E WHERE
A.id=B.art_id AND B.teema_id IN (5708,5203,5103,59) AND
A.id=C.art_id AND C.teema_id IN (5708,5203,5103,59) AND
A.id=D.art_id AND D.teema_id IN (5708,5203,5103,59) AND
A.id=E.art_id AND E.teema_id IN (5708,5203,5103,59)

teatas mysql pärast pooleminutilist ragistamist "MySQL client ran out of memory" ja sellist teadet ma pole varem veel välja võlunud :(
Artiklite tabelis 16 000 kirjet (28MB), seoste tabelis 90 000 kirjet (6MB). Homme katsetan teisi võimalusi.
RE: raske juhus mysqliga
Postitaja: blaa 2013-03-20 00:01:32
TSITEERITUD:

SELECT art_id , COUNT(teema_id)
FROM SEOSED
GROUP BY art_id
HAVING COUNT(teema_id) = 5

ja WHERE teema_id IN (1,2,3,6,9)

võiks toimida küll suht probleemideta
RE: raske juhus mysqliga
Postitaja: Lost in scope 2013-03-20 03:51:04
Jummel, aiage ikka asjad keeruliseks. Muuda motlemist. Sinu seoste tabel Hoiab kogu vajaminevat infot.
RE: raske juhus mysqliga
Postitaja: onu heino 2013-03-20 11:06:06
TSITEERITUD:
Ei ole reaalselt üle kontrollinud, aga vast idee saad :
SELECT art_id , COUNT(teema_id)
FROM SEOSED
GROUP BY art_id
HAVING COUNT(teema_id) = 5


Jah, see põhimõtteliselt toimib, kuigi päring on veel tiba aeglane (0.5 sek kanti).

Suured tänud :)
RE: raske juhus mysqliga
Postitaja: blaa 2013-03-20 15:12:24
TSITEERITUD:

Jah, see põhimõtteliselt toimib, kuigi päring on veel tiba aeglane (0.5 sek kanti).

indekseerid seoste tabeli veerud ära

Leheküljed: 1

©2002-2013 Martin Rebane & PHP.ee kaasautorid
  0.0868570804596