ugrás a tartalomhoz

Eltérő termékek egységes kezelése adatbázisban

world-s · 2008. Május. 5. (H), 10.59
Sziasztok!

A segítségeteket szeretném kérni.

Egy olyan adatbázist kellene felépítenem, melyben teljesen eltérő termékeket tudok tárolni.
Olyan mint egy webshop, csak itt nincs egy megfogható termékcsoport.
Pl. tartalmazhatja egy CPU-t, egy házat, egy autót, egy mosógépet, egy üdülést, stb.

Ezeknek a termékeknek ugye igen csak eltérő tulajdonságai vannak, amiket tárolni is szeretnék.

A legfontosabb, hogy gyors legyen a rendszer mind keresésre, mind pedig tallózásra.
Ha pl. beírom, hogy piros, akkor szeretném látni a piros mobiltelefontól a piros autón keresztül a piros sportdzsekin át az összes olyan terméket, ami piros, viszont az is fontos lenne, hogy a termék neve alatt szerepeljen az aktuális termékcsoportra jellemző összes fő tulajdonság úgy, hogy az nem újabb lassú lekérdezések árán legyen csak lehetséges.

Pl.
Nokia 3510i
kártya független
MMS képes
WAP képes

FIAT UNO
1998-as évjárat
300 m3
4 ütemű

ADIDAS dzseki
újszerű állapotú
piros


1.
Alap esetben az lenne a legegyszerűbb, ha csinálnák egy 500 mezős táblát, 380 index-el, és ebben felvennék minden lehetséges tulajdonságot az órajeltől, az alapterületen át a végsebességig. Egy admin táblában meghatároznám, hogy az egyes termékkörök esetén mit kell kitölteni, és a többi tulajdonság NULL-t venne fel.
Ugye ekkor egy keresésnél minden információ rendelkezésre áll, viszont nem feltétlen a legszerencsésebb választás.

2.
A másik lehetőség, hogy az alap tulajdonságokat veszem csak fel (neve, kategória, ára, stb.) és a kiegészítő tulajdonságokat egy másik táblába helyezem el, ahol szerepelne a termék ID-ja a tulajdonság azonosítója (3. tábla) és az érték. Itt mivel igencsak eltérő értékek lehetnek (szám, szöveg, stb.), ezért csak szövegesen tudnám ábrázolni az egyes értékeket ami lassítaná a keresést, illetve ha sok tulajdonságok szeretnék egyszerre figyelni, akkor sok JOIN vagy SELECT lenne.


Mit ajánlanátok?

Előre is köszönöm a segítséget.
Üdv:
Zoli
 
1

Embereknek készül?

Wabbitseason · 2008. Május. 5. (H), 11.35
Érdemes volna úgy is belegondolni ebbe, hogy én, mint user, tényleg akarom-e, hogy ha beírom, hogy "piros", akkor kapjak ötmilliárd találatot piros telefonnal és piros autóval. Miért írnám be azt, hogy "piros" anélkül, hogy azt is megmondanám, hogy mi az, ami érdekel?

Semmiképp se csinálj 500 mezős táblát.

Döntsd el pontosan, hogy mit akarsz, mit akar majd a user, és aszerint normalizáld a tábláidat!
5

Válasz

world-s · 2008. Május. 5. (H), 12.37
Wabbitseason
Ez csak egy példa volt, de nem feltétlenül a legszerencsésebb ezek szerint.

A lényeg, hogy az egyes kategóriákban (ingatlanok, gépkocsik, számítógép alkatrészek, üdülések, stb.) különböző típusú tulajdonságokat kellene tudnom kezelni.
Protezis
Egyre gondoltunk. Pont most írtam ugyanezt csak másik példával.
Viszont jó lenne, ha a termékek lekérdezéskor egyben láthatnám a termékek mellett a termekek_tulajdonsagok összekapcsoló táblában lévő összes – az adott termékhez tartozó - tulajdonságot, ami ugye ott külön soronként szerepel.

Vbence
„termékeket "repülő" tulajdonságokkal” Ez mit jelent nálad? Mi az, hogy „repülő”?
Ha jól értem te azt javaslod, hogy legyenek úgy tárolva az adatok mint ahogy Protezis írta, de készüljön belőle egy globális nagy tábla is a listázás és keresés miatt.
Ezt mikor gyártanád? Amikor egy új rekord kerül a rendszerbe, illetve akkor bővítenéd, ha egy új tulajdonság kerülne felvételre?
Üdv:
Zoli
14

Nem...

vbence · 2008. Május. 5. (H), 21.10
én elsősorban egy táblát hazsnálnék, tehát az egyes számú megolást. Csupán csak azért említettem a kettest, hogy ha az egyest nem talánád túl esztétikusnak, akkor kezelheted puszta CACHE-kélnt is. Frissíteni értelemszerűen akkor kell, amennyire friss adatokat szeretnél a weben látni, tehát mindig, amikor adatok módosulnak, de mégegyszer: ez csak egy lehetőség. Tökéletesen elegendőnek találom az egyes megoldást (500 mező, 380 index stb...)

A repülő tulajdonságoknak azokat nevezem, amik nem szerepelnek minden egyes elemben. (A második megoldásban ezek kerülnek a külön táblába.)
2

Ahogy en csinaltam

Protezis · 2008. Május. 5. (H), 11.38
A kovetkezo tablaim vannak:

- termekek (id, nev, leiras, ...)
- tulajdonsagok (id, nev)
- termekek_tulajdonsagok (id, termek_id, tulajdonsag_id, ertek)

Pl.:

termek:
- 1, Nokia 3510i, jo kis telefon
- 2, ADIDAS dzseki, jo kis dzseki

tulajdonsag:
- 1, kártya független
- 2, MMS képes
- 3, WAP képes
- 4, szin
- 5, allapot

termekek_tulajdonsagok:
- 1, 1, 1, igen
- 2, 1, 2, igen
- 3, 1, 3, igen
- 4, 2, 4, piros
- 5, 2, 5, ujszeru

Ebbe is vihetsz be termekcsoportokat, null-okkal viszont nem kell feltoltened semmit.
Termesztesen a tulajdonsagokat fel kell venni (ez is konnyen megvalosithato), ez azonban kesobb egyre ritkabban jelent problemat.
3

Egytábla

vbence · 2008. Május. 5. (H), 11.58
Prezentáltad a két lehetőséget.

Én az elsőt választanám. Ha tényleg listáznod kell termékeket "repülő" tulajdonságokkal, akkor egyértelműen ez lesz a legjobb megközelítés. Hátránya az, hogy nem esztétikus, és "talán nagyobb".

Overhead? Egyrészt a vinyó hely ára a nullához konvergál. Másrészt a sok fölösleges, NULL tartalmú mező átvitele a DB és a PHP között nem hiszem, hogy sok helyet foglal a socketben. Megjegyzem, ha már szűkítve van termékcsoportra (pl telefon), ahogy az esetek 90%ában lesz is, akkor a lekérdezésbe beleszőheted, hogy a fölösleges mezők ne jöjjenek át.

Ha pedig belegondolunk abba, hogy a tulajdonságok nagy része gyakorlatilag boolean lesz (MMS van/nincs, EDGE van/nincs), így a fölösleges mezők is, egy tinyint pedig lényelgesen kevesebb helyet foglal, mint egy numerikus ID mező (mondjuk egy 32 bites), és egy varchar mező, amit a lehető leghosszabbra kell vegyél beleférjen az az egy-két eset is, amikor litániákat kell írni bele.


Szóval egyértelműen és kategórikusan a mamuttáblát választom. Ha zavar, hogy nem esztétikus, használd az adminisztrációhoz a "szép" megoldást a repülő mezőkkel, és ebből mintegy cache-ként gyártsd le a produkciós környezetben működő nagytáblát.

Egy kis megjegyzés: ne használj text mezőt, amilyen tulajdonság nem fér bele 250 karakterbe, azt amúgy is jobb többfele választani. Egy nem rögzített hosszúságú mező, mint a text eléggé be tudja lassítani a táblát.
4

Nem látom át, mi a koncepció

Török Gábor · 2008. Május. 5. (H), 12.17
Szerintem az a kiindulás nem szerencsés, hogy te egyből relációs adatbázis modellben gondolkodsz, márpedig a leírt kritériumok nem támasztják fel ennek az igényét szerintem. Nem tudom, hogy mit szeretnél pontosan az alkalmazásodtól, de a te fejedben sem alakult ki még egységes koncepció, mert először azt írod, hogy nincs "egy megfogható termékcsoport", utána viszont "aktuális termékcsoportra jellemző" ismérvekről, tallózási lehetőségről beszélsz.
6

Válasz

world-s · 2008. Május. 5. (H), 12.52
Ez egy termékkatalógus lenne.
Ebből adódóan sok féle termék és szolgáltatás szerepel rajta egyidejűleg.

Ha valaki keres egy terméket, szolgáltatást, azt nekem az összes - esetleg szűrés esetén (pl. valaki csak az ingatlan kategóriában keres) - rekord között figyelnem kell.
Természetesen nem csak a termék nevére, és árára szeretnék keresni, hanem bármely tulajdonságra is.
(természetesen itt is jelzem, hogy az szabályozva lesz azért, hogy pl. a videokártyákat nem lehet majd szín szerint keresni).

Ha csak normál keresésről lenne szó, akkor még talán nem is lenne annyira nagy a problémám.
Viszont az elképzelésem az, hogy egy-egy terméket több irányból is meg lehessen találni, kvázi nem előre beégetett kategórialista legyen csak.
Pl.: egy bababútort meg lehessen találni a
- bútor -> bababútorok
és a
- baba és gyerekholmik -> bútorok
struktúrán is. Természetesen most nem az adott példánál ragadjunk le, mert most ebbe is biztos bele lehet kötni.
A lényeg, hogy nekem ehhez szükségem van, hogy az adott szinten egyben lássam, hogy milyen tulajdonságokkal rendelkeznek az adott termékek.

Üdv:
Zoli
7

Szerintem...

Ronyn · 2008. Május. 5. (H), 14.39
oktalanság lenne egy táblába ömleszteni az adatokat(asszem a normalizálás sem ezt ajánlja):D
Egyrészt jo hogy egy táblában "kéznél van" minden,de a példánál maradva,egy 500 mezös táblánál,nem hiszem hogy hatékonyabban lehetne keresni a "piros" tulajdonságra,amely az 500 mezö közül bármelyikben lehet,(pláne ha több tulajdonságra keresel),mint egy több táblás lekérdezésnél.
Még akkor is ha mondjuk a tulajdonságok táblában van 10-15 varchar esetleg text mezö.
Ráadásul a megjelenités sem egyszerübb semmivel,hiszen nem ugyanazok a tulajdonságai vannak két különbözö kategóriának,és nem ugyanannak a tulajdonságnak az értéke lesz a "piros",egy másik termékkategoriában,amely szintén a találatok között fog szerepelni,hiába hogy egy táblábol származik az összes találat.
Persze,hacsak nem egy a táblához hasonlo x száz oszlopos táblázatban iratod ki az adatokat:D
---------
Én még egy olyan megoldást tudnék elképzelni(ami talán legközelebb áll,az egy táblás megoldáshoz),hogy meghatározod a tulajdonságok maximális számát ami bármely termékkategoriában megadható,(ami esetleg nem fér ebbe bele,az megadható egy általános "Leirás" mezöben),és annyi oszlopa lenne a táblának; a tábla oszlopai/mezöi csak egy általános nevet kapnak(pl.:ertek1,ertek2,ertekx),és az adott termékkategoriához tartozó tulajdonságok nevei,egy másik táblában(vagy akár fájlban) lesznek definiálva,igy max 2 tábla kell.
Persze ennek a megoldásnak is vannak korlátai,amik a késöbbi fejlesztés során hátrányt jelenthetnek...
8

Válasz

world-s · 2008. Május. 5. (H), 15.21
Szia!
Természetesen ha lehet, nem egy táblában szeretném tárolni az adatokat, és természetesen nem minden mezőben ugyanaz lenne leírva. Pl. a "pirosat" a szín mezőben keresném.
Ezen kívül nem minden adatra van szükségem mindig, de hogy melyikre az változó.
Ezért kérem a segítségeteket.

Pl.:
Ha azt válassza valaki, hogy babacuccok, akkor nem írhatom egy bútorra ugyanazt, mint egy zoknira (13-mas mértet fiú).
Természetesen azt, hogy mire van szükségem, azt az adott termék besorolása dönti el.

Sajnos kicsit nehéz leírni mit szeretnék.
Ha valaki a "babacuccok -> fiú" között válogat akkor nekem bútorok azon termékeket kell kikeresnem amiknek a tulajdonságai között szerepel, hogy babacucc és azt, hogy fiú. Ez ezt jelenti, hogy a fiú pelenkától (ha van ilyen) a fiú gyerekszobabútorig minden terméket meg kell jelenítenem.

Ha ez a két tulajdonság mind fő tulajdonság szerepelhetne a terméket tartalmazó táblában, akkor egyszerűen ki tudnám olvasni. De ezt ugye nem akarjuk, mert akkor egy hatalmas táblát kapnánk, mert ezen kívül még nagyon sok féle tulajdonság létezik.

Ha külön táblában vannak a tulajdonságok, akkor ki kell válogatnom a babacucc tulajdonságú termékeket amin mondjuk 10.000 db, majd megnézni ezek közül hogy melyik volt ezek közül fiú.

Ha a két táblát JOIN-nal kötöm össze, akkor meg fogom kapni azt, hogy van olyan termék ami babacucc és van olyan ami fiuknak való. Ezek után nekem kell kiválogatnom azt, hogy melyek amik minden tulajdonságnak megfelelnek. Ha még a bútoroknál a méretet, a pelenkánál a nedvszívóságot is ki szeretném írni, akkor az még egy pár JOIN lenne.

Mint említettem nekem "Protezis" megoldása nagyon jó lenne, hisz én is eljutottam eddig, viszont hogyan tudnám úgy összejoinolni a két táblát, hogy a "termekek_tulajdonsagok" táblában lévő étékek mintha mezők jelenjenek meg és így normálisan szűrhetők lennének.

Üdv:
Zoli
9

Erre gondolsz?

Protezis · 2008. Május. 5. (H), 15.39
SELECT ter.nev, ter.szoveg, tul.nev, tertul.ertek FROM termekek ter INNER JOIN termekektulajdonsagok tertul ON ter.id = tertul.termek_id INNER JOIN tulajdonsagok tul ON tertul.tulajdonsag_id = tul.id WHERE tul.nev = "WAP képes" AND tertul.ertek = "igen"
Ez kilistazza a WAP képes termekeket. Ha csoportokba szeded a termekeket (lesz csoport mezoje), akkor a csoportok tablat is hozzajoinolod, es beallitasz meg egy feltetelt a csoportra:
AND csoport.nev = "mobilok"
10

ha esetleg ez...

Protezis · 2008. Május. 5. (H), 16.17
Ha egy adott termek osszes tulajdonsagat ki akarod listazni, akkor ez kell neked:

SELECT tul.nev, tertul.ertek FROM termekek ter INNER JOIN termekektulajdonsagok tertul ON ter.id = tertul.termek_id INNER JOIN tulajdonsagok tul ON tertul.tulajdonsag_id = tul.id WHERE ter.id = 1
, ahol ter.id a termek id-je, amire kivancsi vagy.
11

Válasz

world-s · 2008. Május. 5. (H), 17.01
Köszönöm a gyors segítséget.

Ez nagyon jó.

Viszont az lenne a kérdésem, hogy ez hogyan működik mondjuk 2 vagy 3 szűrt tulajdonság esetén?
SELECT ter.nev, ter.szoveg, tul.nev, tertul.ertek
FROM `!termekek` ter
INNER JOIN `!termekektulajdonsagok` tertul ON ter.id = tertul.termek_id
INNER JOIN `!tulajdonsagok` tul ON tertul.tulajdonsag_id = tul.id
WHERE (
tul.nev = "WAP képes"
AND tertul.ertek = "igen"
)
OR (
tul.nev = "kártya független"
AND tertul.ertek = "igen"
)
Ekkor megkapom a WAP képes és a kártyafüggetlen készülékeket is.
Ezek után nekem kell összemolyolnom, hogy melyek amik mindkettőnek megfelelnek, vagy van rá szintén valami jó megoldás?

Most így elsőre arra gondoltam, hogy megszámolom hányszor szerepel az adott termék, és összevetem azzal, hogy hány tulajdonságra szeretnék szűrni.

Így megkaphatnám, hogy egy adott termék minden kritériumnak megfelel -e.
Valahogy így:

SELECT count( ter.id ) , ter.id, ter.nev, ter.szoveg, tul.nev, tertul.ertek
FROM `!termekek` ter
INNER JOIN `!termekektulajdonsagok` tertul ON ter.id = tertul.termek_id
INNER JOIN `!tulajdonsagok` tul ON tertul.tulajdonsag_id = tul.id
WHERE (
tul.nev = "WAP képes"
AND tertul.ertek = "igen"
)
OR (
tul.nev = "kártya független"
AND tertul.ertek = "igen"
)
GROUP BY ter.id

Nem tudom ennél van -e jobb ellenőrzés, vagy csak a manuális feldolgozás valamint a fenti SQL.

Az SQL-el csak annyi bajom van, hogy azon tulajdonságok esetén ahol nem szeretnék szűrni, hanem csak szükségem van egy adott tulajdonságra, ott ezt hogyan tudom megcsinálni.

Üdv:
Zoli
12

Nem tudom, van -e jobb

Protezis · 2008. Május. 5. (H), 19.13
Hirtelen nem jut jobb eszembe. A tiedbol indultam ki, de a szurest mysql-ben is meg lehet adni:
SELECT COUNT(ter.id) AS megfeleles, ter.nev, ter.szoveg
FROM termekek ter
INNER JOIN termekektulajdonsagok tertul ON ter.id = tertul.termek_id
INNER JOIN tulajdonsagok tul ON tertul.tulajdonsag_id = tul.id
WHERE (tul.nev = "WAP képes" AND tertul.ertek = "igen") OR (tul.nev = "kártya független" AND tertul.ertek = "igen")
GROUP BY ter.id
HAVING megfeleles = 2
, ahol megfeleles a feltetelek szama, amit szerver oldalon nem tul bonyolultan meg tudsz szamolni.

Kivancsi lennek egy jobb megoldasra...

Ha ezeket a termekeket akarod kilistazni (tulajdonsagaikkal egyutt), akkor a fenti lekerdezessel megkapod a megfelelo termekeket, es a korabbi (altalam javasolt) termeklekero query-nek a vegere ezt irod:

WHERE ter.id IN (ide jon az elobbi select ugy, hogy csak az id-ket kered le)
13

Válasz

world-s · 2008. Május. 5. (H), 20.39
Szépen alakul az SQL-ünk... ;)

Tehát kicsit leredukálva a jelenlegi SQL:
SELECT ter.id, ter.nev termek_nev, tul.nev, tertul.ertek FROM `!termekek` ter INNER JOIN `!termekektulajdonsagok` tertul ON ter.id = tertul.termek_id INNER JOIN `!tulajdonsagok` tul ON tertul.tulajdonsag_id = tul.id WHERE ter.id IN (SELECT ter.id
FROM `!termekek` ter   
INNER JOIN `!termekektulajdonsagok` tertul ON ter.id = tertul.termek_id   
INNER JOIN `!tulajdonsagok` tul ON tertul.tulajdonsag_id = tul.id   
WHERE (tul.nev = "WAP képes" AND tertul.ertek = "igen") OR (tul.nev = "kártya független" AND tertul.ertek = "igen")   
GROUP BY ter.id   
HAVING COUNT(ter.id) = 2 ) order by termek_nev
Itt ebben az esetben egyenlőre megkapom minden terméket annyiszor ahány tulajdonságra van szűrve, és ebből kell utána géppel összeállítanom egy olyan tömböt amiben össze vannak rendezve az adatok.

Addig míg kapunk egy jobb meg megoldást add lenne egy mellékel kérdésem:
A "termekektulajdonsagok" táblában hogyan tudok különböző típusú adatokat rögzíteni, hogy az jól indexelhető, és jól szűrhető legyen (pl. szűrés CPU sebességre: 1000-3000GHZ)?
Pl. int, float, bool, enum, text, stb.

Újabb táblákat vonnál be erre, vagy a 'termekektulajdonsagok' táblát különböző típus mezőkkel egészítenéd ki (int, float, text, stb.). Az értéket mindig a megfelelő mezőbe írnád. Az, hogy melyik tulajdonság esetén melyiket kell alkalmazni, azt pedig a 'tulajdonság' tábla egy újabb mezője határozná meg.


Üdv:
Zoli
15

Ez engem is erdekelne

Protezis · 2008. Május. 5. (H), 22.34
:)
16

Concat

world-s · 2008. Május. 5. (H), 23.14
Most néztem a concat funkciót.
Ezzel tudok létrehozni új mezőket és értékeket is beletenni.
Már csak azt kellene elérni, hogy a termékek egyes tulajdonságai mint egy-egy alias-al létrejöjjenek.
Csak még nem tudom hogy csináljam...

Szerkesztve:
Bocs. Most ökörséget írtam azt hiszem. A mezőt az 'AS' hozza létre.. ;)

Üdv:
Zoli
17

Egy újjabb ötlet

world-s · 2008. Május. 6. (K), 10.06
Sziasztok!

Kollegám a tulajdonságok mezőbe való összefoglalásával próbálkozik.
Elég ígéretesen indul.

SELECT ter.nev, 
CASE WHEN tul.nev = "WAP képes"
THEN tertul.ertek
ELSE ""
END wap_kepes, 
CASE WHEN tul.nev = "kártya független"
THEN tertul.ertek
ELSE ""
END kartya_fuggetlen, 
CASE WHEN tul.nev = "MMS képes"
THEN tertul.ertek
ELSE ""
END MMS_kepes
FROM `!termekek` ter
INNER JOIN `!termekektulajdonsagok` tertul ON ter.id = tertul.termek_id
INNER JOIN `!tulajdonsagok` tul ON tertul.tulajdonsag_id = tul.id
WHERE ter.id
IN ( 1 )
Két dolgot kellene megoldani itt:
1. valahogy úgy group by-olni az eredményeket, hogy az értékkel rendelkezők szerepeljenek csak egy sorban.
2. megoldani, hogy a mezőlétrehozás automatikus legyen és nem manuális

Üdv:
Zoli
18

Újjabb kisérlet

world-s · 2008. Május. 6. (K), 10.43
Tovább lett fejlesztve.
Köszönet Imrének.

Igaz még mindig meg kell adni, hogy milyen tulajdonságokra van szükségem, és nem adja vissza az őszeset amit a találatok adnak, de már szépen mezőkké fűzi össze a tulajdonságokat.
SELECT ter.nev, group_concat( CASE WHEN tul.nev = "WAP képes" THEN tertul.ertek ELSE NULL END ) wap_kepes, group_concat( CASE WHEN tul.nev = "kártya független" THEN tertul.ertek ELSE NULL END ) kartya_fuggetlen, group_concat( CASE WHEN tul.nev = "MMS képes" THEN tertul.ertek ELSE NULL END ) MMS_kepes
FROM `!termekek` ter
INNER JOIN `!termekektulajdonsagok` tertul ON ter.id = tertul.termek_id
INNER JOIN `!tulajdonsagok` tul ON tertul.tulajdonsag_id = tul.id
WHERE ter.id
IN (
SELECT ter.id
FROM `!termekek` ter
INNER JOIN `!termekektulajdonsagok` tertul ON ter.id = tertul.termek_id
INNER JOIN `!tulajdonsagok` tul ON tertul.tulajdonsag_id = tul.id
WHERE (
tul.nev = "WAP képes"
AND tertul.ertek = "igen"
)
OR (
tul.nev = "kártya független"
AND tertul.ertek = "igen"
)
GROUP BY ter.id
HAVING COUNT( ter.id ) =2
)
GROUP BY 1 
Már csak ezt kellene megoldani, hogy ne nekem kelljen definiálnom a mezőket, hanem ha valamelyik terméknél találkozik egy új tulajdonsággal, akkor hozza létre az új mezőt.

Üdv:
Zoli
20

"This is madness!"

vbence · 2008. Május. 6. (K), 11.25
Ahogy a 300 című filmben mondták volna... A tulajdonságneveknek szótártáblában a helye, nem pedig szövegként. Lehet, hogy én néztem el vlaamit... Mi is a szöveg előnye?
19

Tag-ek

vbence · 2008. Május. 6. (K), 11.22
Erre való a tagelés! Ha olyan besorolásra van szükséged, ahol lehet átfedés (például egy termék benne van a "babcuccok" és "kovácsoltvas" kategóriákban is), hozz létre egy TAG táblát és egy kapcsolótáblát mellé.
21

Címkézés + 1

Török Gábor · 2008. Május. 6. (K), 11.54
Csatlakozom, én is taggeléssel oldanám meg a problémát, és a relációs adatbázis modellben való gondolkodást hanyagolnám. A tagek alapján meg lehet oldalni a legyűjtéseket (tallózás), a keresésre pedig használd azt az elképzelésed, amit elvileg kitaláltál.
22

???

world-s · 2008. Május. 6. (K), 12.36
Most kicsit összekavarodtam...

Most akkor ti mit is ajánlotok?

Bocs az érthetetlenségemért...

Üdv:
Zoli
23

tagek címkék és egyébb állatfajták

vbence · 2008. Május. 6. (K), 13.31
Tudod.. ha olvastál már blogot (és gyanítom, igen) a postok be vannak sorolva témákba. A lényeg az, hogy egy post több cimke (tag) alatt is szerepelhet. A te tesetben:

tag {id int, word varchar}
termek {id int, ...}
termek_tag {termek int, tag int}

Magyarul van egy szótártáblád a témákkal (cimkékkel), és van egy kapcsolótáblád, ami ezta termékekre aggatja. Egy cimke természetesen csak egyszer szerepel (a tag táblában), az összekapcsolást ("sok a sokhoz" kapcsolat) a termek_tag végzi. (persze olyan elnevezési konvenciókal, amilyet szeretsz).
24

Kérdés

world-s · 2008. Május. 6. (K), 13.53
Így már értem.

Viszont ennál a módszernél is lenne kérdésem.

1. a cimkéket biztos, hogy csoportosítani kell tudnom. Pl. ha színre szeretnék szürni, akkor tudnom kell melyek a cimkék amik színt fejeznek ki.
De ezt még ki is sakkozom talán.

2. mi van azokkal a tulajdonságokkal ami nem igen és nem tipusúak? Gondolok ist mondjuk méret, súj, órajel, stb. Ilyenkor felveszem a 20MHZ , 21MHZ , 22MHZ , 23MHZ , 24MHZ , 25MHZ ..... a 10mm, 11mm, 12mm, stb értékeket külön?

Üdv:
Zoli
25

tag vs keresés

vbence · 2008. Május. 6. (K), 16.30
A cimkézés csak a csoportosításra szolgál. Abszolút semi kapcsolata nincs a többi tulajdonsággal. Először is kell egy szigorúbb osztályozás, ami a kitölthető mezőket (is) befolyásolja (pl. telefon, ágy, autó). A cimkézés nem befolyásolja azt sem, hogy az egytáblás vagy soktáblás megoldást választod. Ez nem a tulajdonságok tárolására szolgál, csak a csoportosításra.
26

Tulajdonság értékek

world-s · 2008. Május. 6. (K), 21.26
Így már értem.

Lenne közben egy újabb kérdésem.

Hogy érdemes az egyes tulajdonságok lehetséges értékeit tárolni.
Ez pl. a termék rögzítéshez és a kereséshez lényeges.

Az én esetemben ettől bővebb az összefüggés (pl. egy gyártó típus egy PC alkatrésznél más, mint egy autó esetén, tehát kategóriánként más lehet az értéktartomány), viszont most leegyszerűsítem az egészet az adott problémára.


tulajdonsag:
- 1, kártya független
- 2, MMS képes
- 3, WAP képes
- 4, szin

tulajdonsag_etrekei:
- 1, 0, nem
- 1, 1, igen
- 1, 2, nincs megadva
- 2, 0, nem
- 2, 1, igen
- 2, 2, nincs megadva
- 3, 0, nem
- 3, 1, igen
- 3, 2, nincs megadva
- 4, 0, nincs megadva
- 4, 1, piros
- 4, 2, zöld
- 4, 3, sárga
- 4, 4, kék
- 4, 5, narancs
- 4, 6, lila
- 4, 7, fehér
- 4, 8, fekete

Ez így jó is lenne.
Viszont ugye nem csak ilyen típusú értékek lehetnek.
Pl. egy súly, egy órajel (ahol van min. és max. érték), vagy szöveges tulajdonság esetén, hogyan lehet ezt szépen tárolni ahol mondjuk a min. és max. szöveghossz van megadva.

Üdv:
Zoli
27

Virtuális mezők

vbence · 2008. Május. 6. (K), 23.12
Itt nem csinálsz mást, mint hogy egy létező adatbázis-funkcionalitást, tehát a mezőket egy absztrakciós szinttel feljebb emeled. Ezeknek a virtuális mezőknek is vannak tipusai. Van például a SET, amikor meghatározott lehetőségek közül választasz ki egyet. Lehet varchar, amit ki lehet töltani, és lehet numerikus típus is, ha rendezni szeretnél rá. (Persze varchar-alapon tárolhatod a numerikust is).

Tehát létre kell hoznod egy módszert, ahogy ezeknek a mezőknek a metaadatait tárolod, és generálod belőle az adminisztrációs formokat. A produkciós környezetben viszont használhatsz egy "lerenderelt" változatot, ahol minden varcharként tárolódik.
28

???

world-s · 2008. Május. 7. (Sze), 09.29
Szia!

Bocsi az újabb értetlenkedésemért, de ezt nem igazán sikerült megértenem mit is mondasz...

Tudnál segíteni a dekódolásában? ;)

Köszi.

Üdv:
Zoli
29

ok

vbence · 2008. Május. 7. (Sze), 10.25
A 26-os commentben írt megoldásod megoldás a SET tipusúmezőkre, tehát ahol kész lehetőségek közül választhatunk. Emellett szükséged lesz olyan tipusú mezőre is, ahova egyszerűen be lehet pötyögni a karaktereket, és talán olyanra, ami speciálisan számok bepötyögésére szolgál. Magyarul: típusokra.

A kész értékeket tárolhatod varcharként, úgyhogy az éles oldalon (az egyes lekérdezésekben) nem lesz feltétlenül szükséged erre a programrészre.
30

Ilyesmi?

world-s · 2008. Május. 7. (Sze), 10.46
Nem tudom jól veszem -e ki, de valami ilyesmir gondolsz?

tulajdonsag:
ID, nev, Type, MinValue, MaxValue, MinLong, MaxLong, Mertekegyseg
- 1, kártya független, set, NULL, NULL, NULL, NULL,
- 2, MMS képes, set, NULL, NULL, NULL, NULL,
- 3, WAP képes, set, NULL, NULL, NULL, NULL,
- 4, Szin, set, NULL, NULL, NULL, NULL,
- 5, Súly, doubel, 0, 12.5, NULL, NULL, kg
- 6, email, text, NULL, NULL, 50, 200,


tulajdonsag_etrekei:
- 1, 0, nem
- 1, 1, igen
- 1, 2, nincs megadva
- 2, 0, nem
- 2, 1, igen
- 2, 2, nincs megadva
- 3, 0, nem
- 3, 1, igen
- 3, 2, nincs megadva
- 4, 0, nincs megadva
- 4, 1, piros
- 4, 2, zöld
- 4, 3, sárga
- 4, 4, kék
- 4, 5, narancs
- 4, 6, lila
- 4, 7, fehér
- 4, 8, fekete
31

igen

vbence · 2008. Május. 7. (Sze), 11.10
pontosan ilyesmire gondolok... Bár egy kis megalkuvást látok a koncepcióban (NULL-ok :)
32

;)

world-s · 2008. Május. 7. (Sze), 12.02
Hurrá....
Ennek örülök.

Akkor lenne egy újabb még ide kapcsolódó kérdésem.

Már tudok szűrni, meg tudom határozni az értéktartományokat.

A kérdésem, hogy egy konkrét terméke esetén hogyan tudom tárolni az eltérő típusú tulajdonságokat?

Alaphelyzetben ez volt.
termekek_tulajdonsagok:

id, termék, ertek
- 1, 1, 1, igen
- 2, 1, 2, igen
- 3, 1, 3, igen
- 4, 2, 4, piros
- 5, 2, 5, ujszeru

Ha az értéket szám típusnak veszem, akkor mondjuk le tudom tárolni mondjuk egy CPU órajelét.
Ha SET típusról van szó, akkor szintén le tudom tárolni a szín sorszámát.
A kérdés, hogy egy szöveges értéket hogy tároljak, vagy egy dátumot, stb.?

Üdv:
Zoli
33

Új megközelítés

world-s · 2008. Május. 7. (Sze), 13.45
Közben kaptam egy újabb megközelítési ötletet is.
1. Mi a véleményetek róla?
2. Meg lehet csinálni, mert nekem hibával eldobja az SQL

Az új megközelítés szintén abból indul ki, hogy vannak a termékek tábla, és vannak benne alap tulajdonságok (id, név, ár, stb.)
Viszont ez a tábla tartalmazna egy olyan mezőt, mely egy hivatkozást tartalmazna egy tulajdonságtáblára.
Az lenne benne, hogy mely tulajdonságtábla kapcsolódik az adott termékhez.

Ez alapján külön el lehet szépen készíteni külön-külön a járművek, telefonok, ingatlanok, stb. tulajdonságait tartalmazó táblákat. Itt megoldódna a típus probléma és egy sor más is.

SELECT * FROM `!termekek` ter INNER JOIN ter.tulajdonsagok_tabla_neve tertul ON ter.id = tertul.term_id WHERE 1
Viszont ez nem működik, mert ugye egy konkrét táblát vár a JOIN és nem egy mezőnevet.

Lehet fordítva kellene nekiindulni. A tulajdonságoktól a termék felé.

Előre is köszönöm a segítségeket.

Üdv:
Zoli
34

Nem szép

zila · 2008. Május. 7. (Sze), 15.35
Ez a megoldás nagyon nem szép :)
1. Ha új termék típus kerül a rendszerbe, új táblát kell létrehozni és a kódhoz is hozzá kell nyúlni az új tábla szerkezetének megfelelő lekérdezések legyártásához (vagy valami ügyes ini/xml file-t kell mellékelned ami alapján automatizálod ezt a lépést, esetleg adatszótárazod a táblát és röptiben kéred le a tábla szerkezetét ami alapján majd dolgozol...
2. Annyiféle szűrő kell, ahányféle tulajdonság táblád van (hiszen mindegyik más szerkezetű)
3. Több lépésben kell a lekérdezéseket legyártanod: elsőként lekérdezed a termékhez tartozó kapocsolódó tábla nevét és ezzel az információval a kezedben kell legyártanod az összekapcsolt lekérdezés(eke)t

Mindenképpen a termékek, tulajdonságok és termék_tulajdonságok kapcsolótábla vonalon maradnék.
35

Válasz.

world-s · 2008. Május. 7. (Sze), 19.27
Hát igen.
Mindennek meg van előnye és hátránya.
1. "új termék típus kerül a rendszerbe, új táblát kell létrehozni" mivel ez ritkán fordul elő, ezért ez még nem lenne gond.
2. Igen. Tudni kell, hogy egy-egy kategória milyen tulajdonságokat tartalmaz, ha nem lehet valahogy automatizálni.
3. Ez is igaz. Először meg kell nézni, hogy mely tulajdonság táblákat kell JOIN-olni(ha lehet kategóriára szűrni, akkor csak egy részét, ha nem, akkor az összest), majd ezek alapján létrehozni a select-et. Feltéve, hogy nem lehet megoldani automatikusan. (ez nem ment nekem)

Viszont előnye, hogy az értékek tárolása így egyszerű. Olyan típusú mezőket hozok létre ami éppen kell.
Persze közben találtam egy olyan bajt is ezzel, hogy ha két tulajdonságtáblában is szerepel olyan hogy "szin", akkor JOIN esetén két külön oszlopban is megjelenhetnek az értékek.
Nem tudom, hogy lehet -e kérni, hogy ezek össze legyenek vonva, vagy az, hogy ha azt keresem, akkor azt mindkét "szin" mezőben keresse, vagy csak úgy, hogy egy OR-al külön-külön le kell kérdeznem.

Viszont ha hagyjuk ezt a módszert, és visszatérünk a kapcsolótáblás megoldásra, akkor még mindig kérdés, hogy a termékekhez hogyan tudom tárolni a különböző típusú értékeket (int, double, date, text, stb.).

Mivel már így is elég sok összefüggés van, így jó lenne mennél egyszerűbben, úgy, hogy tényleg jól kezelhetően és gyorsan lehessen kezelni.

Előre is köszönök minden építő segítséget, gondolatot.

Üdv:
Zoli
37

Adat modell

zila · 2008. Május. 8. (Cs), 09.03
Viszont előnye, hogy az értékek tárolása így egyszerű. Olyan típusú mezőket hozok létre ami éppen kell.

nem értek egyet. Ha van kismillió tulajdonság táblád kismillió féle szerkezetben az nem jó adatmodell. Meg kell keresni a tulajdonságok legkisebb közös halmazát, és azt kell leírni a modellel. Jelen esetben ez annyi, hogy vannak termékeid amelyekhez 1 vagy több tulajdonság tartozik, a tulajdonságoknak van neve, típusa és értéke. A terméknek még vannak egyéb jellemzői (pl. egy vagy több tag tartozhat hozzá, vagy 1 vagy több kategóriában lehet stb). Ez a modell egy kellően elvont leírása a tárolni kívánt adataidnak, tetszőlegesen bővíthető anélkül, hogy hozzá kéne nyúlnod a táblaszerkezethez.

Az értékek tárolása szerintem sokkal egyszerűbb _egy_ olyan táblában aminek a szerkezete fix mint 15 táblában amiknek a szerekezete eltér...

Viszont ha hagyjuk ezt a módszert, és visszatérünk a kapcsolótáblás megoldásra, akkor még mindig kérdés, hogy a termékekhez hogyan tudom tárolni a különböző típusú értékeket (int, double, date, text, stb.).

Egy lehetséges megoldás, hogy leszűkíted a lehetséges típusok körét: szám, szöveg, időbélyeg
Mindent szöveg mezőben tárolsz és a tulajdonság típusa alapján konvertálsz ha kell.

Vagy a termék_tulajdonságok táblában lehet 3 meződ: érték_szám, érték_szöveg és érték_datum a megfelelő sql típussal (értelemszerűen mindegyikből a leghosszabb, hogy beleférjen minden).

üdv,
Zila
39

Így?

world-s · 2008. Május. 8. (Cs), 10.07
Bent itt is hasonlóra jutottunk mint te a második lehetőségre.

Tehát:
termekek_tulajdonsagok:
id, term_id, tul_id, value_number, value_text, value_time
- 1, 1, 1, 2, NULL, NULL
- 2, 1, 2, 2, NULL, NULL
- 3, 1, 3, 2, NULL, NULL
- 3, 1, 9, NULL, 'kis karccolás az oldalán', NULL
- 3, 1, 9, 2.4, NULL, NULL
- 4, 2, 4, 4, NULL, NULL
- 5, 2, 5, NULL, NULL, '2007-11-15 10:12:43'


Tehát tudnom kell a tulajdonság típusát, és a SELECT-ben akkor a mindig a megfelelő tagot kell beírnom.
....
WHERE (   
tul.nev = "WAP képes"  
AND tertul.value_time = "2008-12-12 00:00:00"  
)   
....
Arra van esetleg lehetőség, hogy ne kelljen nekem előre tudnom azt, hogy melyik mezőben van az érték, hisz mivel a tulajdonság tábla úgy is JOIN-olva van, így elméletileg a típust jelző mező is ott rendelkezésre állna mondjuk a : tul.type mezőben.

Tehát ennek az értékét helyetesítse be....
....
WHERE (   
tul.nev = "WAP képes"  
AND tertul./* valahogy 'tul.type' értékével megegyező mezőből */ = "2008-12-12 00:00:00"  
)   
....
Hogyan oldanád meg?

Üdv:
Zoli
40

valahogy így

zila · 2008. Május. 8. (Cs), 11.49
Én mondjuk az első verziót választanám ;-)

De ha a második akkor valahogy így:
SELECT tul.*, 
           CASE  
                 WHEN tul.type = 'number' THEN tertul.value_number
                 WHEN tul.type = 'text' THEN tertul.value_text
                 WHEN tul.type = 'datetime' THEN tertul.value_datetime
                 ELSE null
          END as type_value
FROM tul, tertul
WHERE ...
   AND tul.nev = 'WAP'
HAVING type_value = 'searchcriteria' 
Szerk: ez csak mysql-ben megy, más dbms-eknél csak group by-ban szereplő oszlopokra eszi meg a having-et...
36

koncepcionális problémát érzékelek

amonrpg · 2008. Május. 8. (Cs), 07.00
Az van, hogy szerintem nincs alapkoncepció sem a dolog mögött. Legalábbis a hozzászólások olvasása alatt ez volt a benyomásom.

Mit szeretnél csinálni?
- Szabad szavas keresőt hozzá (a'la gugli)?
- Vagy bepipálható, részletes-keresés őskőkorszaki keresőform-szörnyeteget?

Én javallom az előbbit. Nem kell ezt túlspilázni. Írja be a júzer, hogy mit szeretne látni, te meg a kapcsolótáblán keresztül kiköpöd neki az eredményt. Arról nem is beszélve, hogy könnyedén lehet "ezekre kerestek a legtöbben" featurát csinálni.

Plusz egy vote a tag-tábla-kapcsolótábla-terméktábla hármasra.

Ja, és ne csoportosítsd a tag-eket típus szerint, mert nincs értelme. Azaz, kit érdekel, hogy a piros tag szín? Senkit. A júzer tudja, a rendszerednek meg irreleváns.
38

Válasz

world-s · 2008. Május. 8. (Cs), 09.44
Szia!

Ez nem azért készül, hogy valaki tök hülye dolgokra tudjon rákeresni egy bazi nagy nagy keresőben.
Azért van szükségem a tetszőleges keresésre, hogy én tudjak szűrni a rendszeren velük tetszőleges dologra, ami bármikor változhat. Tehát ne legyen bebetonozva a rendszer.

A koncepció az, hogy az egyes termékek tárolása a rendszerben egy bizonyos struktúra alapján lennének elmentve.( kategória, alkatagorai, termékcsoportra jellemző egyéni tulajdonságokkal. [pl. épületnél a telek méret van, autónál futott kilométer, stb.])

Viszont az ügyfelek nem ezt az előre bebetonozott struktúrát látnák, hanem egy olyat, ami különböző irányokból meg tudja közelíteni a termékeket.

Olyan mintha lenne egy másik kategória struktúra az ügyfeleknek is, ami sok esetben ugyanazt a termékcsoportot fedi le bent.
Tehát nem a felhasználónak kell alkalmazkodni a mi struktúránkhoz, hanem min igazodunk a lehetséges elvárásokhoz. (Ugye ez alap helyzetben fel van töltve lehetséges csomópontokkal, viszont ezt bár mikor rugalmasan kell tudnom bővítenem.)

Minden, az ügyfelek által látott struktúraelem egy szűrő hivatkozást rejt magában.
Ez határozza meg, hogy az adott menüpont milyen termékeket jelenítsen meg.

Talán példával érthetőbb (természetesen megint nem a konkrét példát nézzétek, mert lehet az hülyeségnek tűnhet, de a bekategorizálás már nem az én feladatom lesz):
Pl.
"Ruházat->Gyerekholmi->Zolni" menüpont a tárolt belső adatbázisból a ruházat->zokni kategóriából a gyereknek való tulajdonsággal rendelkező termékeket fogja leszűrni

"Ruházat->Zolni->Gyerekzokni" menüpont szintlén hasonló szűrőket használ mint fent

Vagy:
"Gyerekholmi->Butor->Fiu gyerekbutór" ugyanoda mutat bent, mint a
"Bútor->Gyerekbutorok->Fiu gyerekbútorok" menüpont

Így egy termék olyan mint ha klasszikus esetet több helyen is szerepelne.
A gyerek bútor a gyerekholmiknál, és a bútoroknál is. Ráadásul, ha még ingyen el is vihető, akkor azon kategóriában is.

Tehát ökörségekre nem lehet majd szűrni, de azért akarnám teljesen dinamikusra megcsinálni, hogy a későbbiekben egy adatbázis sor beszúrásával egyszerűen lehessen módosítani anélkül, hogy ez máshol bekavarna.

Viszont amonrpg amit mondtál az is megfogta most pluszban a fantáziám.
Milyen jó lenne, ha az ügyfél le tudná írni azt mondjuk:
"3 éves kisfiamnak kék ágytakarót keresek."

Tudod ennek a megoldását is?
Nagyon örülnék neki...

[Úgy tudom, hogy elméletileg vannak ilyen rendszerek, vagy rendszer kísérletek amik egy ilyen szövegből ki tudják szedni a hasznos információkat, és abból konkrét paramétereket és értékeket tudnak készíteni.]

Üdv:
Zoli
41

Na igen

zila · 2008. Május. 8. (Cs), 12.28
Milyen jó lenne, ha az ügyfél le tudná írni azt mondjuk:
"3 éves kisfiamnak kék ágytakarót keresek."

Tudod ennek a megoldását is?
Nagyon örülnék neki...


Ennek szerintem még a google is örülne :)
Mondjuk ilyen kereséseket már lehet futtatni: ágytakaró kék kor:3év

Ezt már viszonylag egyszerűen tudod parseolni, egyéb esetekben a ragozást és a toldalékokat el kell távolítani, rosszabb esetben szótőt kell keresgélni->külön tudomány...
44

Szabadszavas

world-s · 2008. Május. 8. (Cs), 23.28
Ha jól tudom a Montana Infóvadász szolgáltatása valami ilyesmin alapul.

Csak gondolom van benne pár év fejlesztés.

Zoli
45

Apache Solr

hector · 2008. Május. 9. (P), 15.33
ezt ismered?: http://lucene.apache.org/solr/
standalone keresőszerver webservice felülettel.
kis gugli :)
46

Tud nativ nyelvi keresést?

zila · 2008. Május. 9. (P), 16.33
Nézegettem már ezt, de nem világos, hogy mit kezd ezzel a kereső kifejezéssel: "3 éves kisfiamnak kék ágytakarót keresek"

Helyesen felparsolja? Ha igen, akkor megyek és töltöm is lefele.
42

még mindig tagelés

amonrpg · 2008. Május. 8. (Cs), 17.10
Ruházat->Gyerekholmi->Zolni

Ez mennyiben különbözik ezektől a menüpontoktól?

Ruházat: http://domain.hu/?tag=ruha
Gyerekholmi: http://domain.hu/?tag=ruha+gyerek
Zokni: http://domain.hu/?tag=ruha+gyerek+zokni

A piros vagy kék zoknik meg:
http://domain.hu/?tag=ruha+gyerek+zokni+kék|piros

Pont a tag-elt megközelítéssel (rugalmassága) lehet elérni azt, hogy a termék akár az összes kategóriában jelen lehessen. Persze ha nagyon kell, akkor csinálhatsz relációt a tag-ek között, bár én ezt feleslegesnek érzem. (Miért ne keressen a júzer adott esetben egyszerre bútort és zoknit? ha az a heppje, hogy egy keresési eredményben szeretné őket látni?)

Ezen kívül fenntarthatod a szabad tag-re való keresést is, vagy akár a meglévő tag-tábla alapján bármilyen valósidejű szókiegészítéses keresést is tudsz adni. Pl. elkezdi beírni, hogy zo... és dobod neki a zoo-t meg a zokni-t, stb...

3 éves kisfiamnak kék ágytakarót keresek

Hát, itt max szinonímaszótárral jutsz - nem túl pontos - eredményre, pluszban lehet szótövet vágni, ami megint csak szótárazással valósítható meg, vagy implementálnod kell a magyar nyelv nem éppen könnyű logikáját, minden kivételével együtt (->szótár).
43

Válasz

world-s · 2008. Május. 8. (Cs), 23.14
A tag is jó, de szerintem nem mindenhová

1. Ez azt jelentené, hogy minden tag-et nekem kellene definiálni.
2. Ami nem igaz vagy hamis, arra nem jó.

Pl. vegyem fel súlynál:
1.0000 KG
1.0001 KG
1.0002 KG
1.0003 KG

De ha fel is venném, igen nehéz lenne a keresés az ilyen értékekre:
1-10 KG közötti valami.

Vagy rosszul látom?

Üdv:
Zoli
47

Megoldás!

gabesz666 · 2008. Május. 10. (Szo), 11.27
Nemtom volt-e már ez a megoldás, de szerintem ez elég egyszerű, bár lehet lassú: egyetlen mezőbe benyomod egy termék összes tulajdonságát és utána keresésnél lazán megtalálja pl %piros%! Nem kellenek külön mezők, szerintem!
50

Jaj, ne.

zila · 2008. Május. 14. (Sze), 09.39
Nesze neked relációs adatkezelés, meg normalizálás. A performanciáról ne is beszéljünk...
52

Ne légy annyira biztos

vbence · 2008. Május. 14. (Sze), 09.57
Adott esetben egy fulltext index és egyetlen "lerenderelt" mező gyorsabb megoldás lehet, mint minden alkalommal összekaparni azadatokat x darab táblából. (A kérdés csak a keresés / lekérdezés arány).
53

Végül is, jogos

zila · 2008. Május. 14. (Sze), 10.05
A fulltext index és a like megint két külön dolog. De egyébként jogos az ellenérv :)
Szép megoldás lehet, hogy egy megfelelő indextábla/indexadatbázis létrehozása ami csudálatosan denormalizált, és kizárólag a keresést szolgálja. Ettől függetlenül a forrásadatokat megérni annyira normalizáltan tartani amennyire lehet/ésszerű.
54

Mi "piros"?

foxmulder · 2008. Május. 14. (Sze), 10.18
gabesz666 példáját alapul véve, szerintem nem elég rákeresni a "piros" értékre, mert az is fontos lehet, hogy mi piros. Vagy mi 66 mm. Vagy az egyetlen mezőben így tároljuk az adatokat?

"szín:piros;előlap hossza:66mm; ..."
55

Arány

foxmulder · 2008. Május. 14. (Sze), 10.53
Nem inkább adatbevitel / lekérdezés arány?
56

Nem

vbence · 2008. Május. 14. (Sze), 11.18
A két ütköztetett módszer

A) kompozitált dataok: gyors lekérdezés, lassabb keresés
B) normalizált db: lassabb lekérdezés, gyors keresés

Egy webáruháznál a felvitelek aránya elenyésző lesz a lekérdezésekhez képest. (Hacsak nem apróhirdetés vagy hasonló, ahol a mezei user is vihet fel terméket). Úgyhogy ez az aspektus nem fog túl messze vinni.
57

Akkor nem értem...

foxmulder · 2008. Május. 14. (Sze), 11.32
Mi a "lekérdezés" és a "keresés" között a különbség. Illetve a látogató szempontjából a különbség tök mindegy, mert a kettő összege számít (az összegen belüli arányok nem), vagyis a kattintástól az eredmény megjelenéséig terjedő idő. Vagy nem?
60

Izé

vbence · 2008. Május. 14. (Sze), 12.17
A keresés az, amikor keres, azaz beír valamit egy szabadszavas keresőbe, vagy kiválaszt valamit egy listából. A lekérdezés pedig, amikor listázza a tulajdonságokat, azaz bemegy a termék részletes nézetébe.
65

Értem :)

foxmulder · 2008. Május. 14. (Sze), 13.04
Úgy tűnik, a kérdező szeretné behatárolni, hogy bizonyos kategóriába tartozó termékekhez csak bizonyos tulajdonságok legyenek rendelhetők, ill. az azonos tulajdonságok is (olykor) különböző lehetséges értékkészlettel. Ezen igényt a kompozitált módszer ki tudja elégíteni?
48

Hasonlóval én is görcsöltem...

foxmulder · 2008. Május. 11. (V), 14.52
Bevallom, nem olvastam végig az összes hozzászólást, bocs, ha már elhangzott ötletet ismétlek. A lényeg, hogyan kezeljük az eltérő adattípusú tulajdonságértékeket (a kiindulási alap megegyezik Protezis javaslatával):

- termekek (id, nev, leiras, ...)
- tulajdonsagok (id, nev)
- termekek_tulajdonsagok (id, termek_id, tulajdonsag_id, ertek_id)

Eddig ugyanaz (kis különbség a kapcsolótáblában: ertek helyett ertek_id), de mivel a különböző tulajdonságok különböző típusú értékekkel rendelkezhetnek (szín-szöveg, hossz-szám...), csinálunk egy ertekek táblát, amelyik csak az azonosítót tartalmazza, (erre mutat a termekek_tulajdonsagok tábla ertek_id-je), majd adattípusonként létrehozunk annyi további táblát, amennyi kell (ezek az Ertek egyedtípus specializáltjai).

- ertekek (id)
- numerikus_erkekek (id, ertek_id, ertek) (UI.: esetleg hozzácsaphatunk egy mertekegyseg mezőt is)
- szoveges_ertekek (id, ertek_id, ertek)
- intervallum_ertekek (id, ertek_id, min_value, max_value)

Így az absztrakt Ertek egyeden keresztül nem csak különböző adattípusú (szám, szöveg) tulajdonságérték, hanem többértékű érték (min-max típusú) is rendelhető egy tulajdonsághoz.
(UI.: Kérdés: hogyan juttathatjuk érvényre azt a megszorítást, miszerint ugyanaz az ertek_id csak egyszer szerepelhet a különböző értéktípusokat reprezentáló táblák egyikében? Egy táblán belül oké, kiteszünk egy "unique"-ot, de hogyan lehet valami egyszerre több táblára nézve unique?)

Ezen kívül, ha csinálunk egy tulajdonsagok_ertekek érvényesítőtáblát akkor korlátozhatjuk egy tulajdonság lehetséges értékeit:
- tulajdonsagok_ertekek (id, tulajdonsag_id, ertek_id)
(UI.: ez esetben nem az ertek_id szerepel a termekek_tulajdonsagok táblában, hanem a tulajdonsagok_ertekek_id)

A dolog szépséghibái:
- Mindig új táblát kell létrehoznunk, ha új adattípus jelenik meg (erre az időben előre haladva egyre kevesebbszer van szükség, sőt az is előfordulhat, hogy már a tervezéskor ismerjük az összes lehetséges értéktípust).
- Sosem próbáltam ki a gyakorlatban.
49

Új hét

world-s · 2008. Május. 14. (Sze), 00.04
Sziasztok!
Hétvégén nem volt időm a problémával foglakozni, de ismét teljes erővel belevetettem magam.

foxmulder!
Tetszik a te elképzelésed is, de ennyire nem akartam már szétszedni, mert egy egyszerű dolog kikeresése is már vagy 10 tábla összekapcsolás alapján lehetne kikeresni ami nagy adatbázisok esetén már gond lehet.

De a te modelled egy része szerepel nálam is, csak nem itt, hanem van egy tulajdonság-leíró táblában, mely azt írja le hogy milyen értékeket lehet felvenni/megjeleníteni és a konkrét értékek tárolásánál már nincsenek az intervallumok és társai tárolva.

Röviden a szerkezet a teljesség igénye nélkül az ami mellett maradtam:

Termékek (Ez tartalmazza a termékeket)
-id (egyéni azonosító)
-cat0 (kategória)
-cat1 (alkategória)
-cat2 (al-alkategória)
-Name (termék neve)
-Ar (termék ára)
-.... (további olyan tulajdonságok amik minden terméknél léteznek)


Tulajdonsag (Ez tartalmazza a lehetséges tulajdonságokat amik nem a fő táblában vannak)
-id (egyéni azonosító)
-Tul_Nev (Tulajdonság neve)
-Tul_type (Tulajdonság tárolási típusa)


Tulajdonsag_value (Ez egy kapcsolótábla, melytartalmazza a lehetséges tulajdonságokat amik nem a fő táblában vannak)
-id (egyéni azonosító)
-termek_id (ermék azonosítója)
-tulajdonsag_id (tulajdonság azonosítója)
-value_number (termék tulajdonság értéke, ha az szám [Tulajdonsag->Tul_type határozza meg])
-value_text (termék tulajdonság értéke, ha az szöveg [Tulajdonsag->Tul_type határozza meg])
-value_datetime (termék tulajdonság értéke, ha az idő [Tulajdonsag->Tul_type határozza meg])

Ez volt a tárolás.

Ezen kívül vannak az említett működést leíró táblák:
categoriak
-Cat_ID (egyéni azonosító, ha van rá szükség egyáltalán. Még nem biztos, hogy kell)
-Cat0_ID
-Cat1_ID
-Cat2_ID
-Name (kategória neve)

Ez tartalmazza az összes alá fölé rendelt kategóriát
pl.:
1, 0, 0, 'műszaki cikkek'
1, 1, 0, 'szórakoztató elektronika'
1, 1, 1, 'vedeómagnók'
1, 1, 2, 'televíziók'
1, 1, 3, 'mp3 lejátszók'
2, 0, 0, 'gépjárművek'

Továbbá van egy összekapcsoló tábla, mely tartalmazza, hogy mely kategóriában milyen tulajdonságok léteznek [megjelenítés/termék felvétel]. Ezen kívül itt kerül rögzítésre az is, hogy az egyes tulajdonságok az egyes kategóriákban milyen értéktartományokban vannak értelmezve. (egy telefon súlya más tartományban van értelmezve mint egy teherkocsié)

categoriak_tulajdonsag
-Cat0_ID
-Cat1_ID
-Cat2_ID
-Tul_ID (tulajdonság azonosító)
-Tul_Cat_Name (Milyen néven szereplejen az adott tulajdonság az adott kategóriában. Pl.: autó gyártója, tv gyártója, stb.)
-View_Type (hogyan legyen megjelenítve az oldalon az oldalon az adott tulajdonság. Pl.: telefonoknál a gyártó select listából, DVD lejátszóknál beírós, viszont mivel a gyártó mint tulajdonság tárolási típusa text, ezért mindkét esetben egységesen szöveg ként lenne tárolva az érték)
-MinValue (szám ábrázolás esetén megadja, hogy az adott kategóriában egy bizonyos érték minimum mekkora értéket kell, hogy felvegyen.)
-MaxValue (szám ábrázolás esetén a maximális érték)
-MinLength (szöveg esetén a minimális szöveghossz)
-MaxLength (szöveg esetén a maximális szöveghossz)

Itt kérdés, hogy itt az összeköttetés a kategória, alkategória, illetve al-alkategória mezővel legyen, vagy a kategóriákat leíró egyéni Cat_ID alapján legyen valahogy így:

categoriak_tulajdonsag
-Cat_ID
-Tul_ID
-Tul_Cat_Name
-MinValue
-MaxValue
-MinLength
-MaxLength

Mi a véleményetek erről?
Ti melyiket választanátok?
Tudom, hogy a normalizálás mit mondana, viszont akkor minden egyszerű csoportosítás esetén táblákat kellene összekapcsolni.

Ha simán csak a Cat_ID-s verziót választom, akkor egy műszaki cikkek kategóriába állva, először azt kell eldöntenem, hogy mely kategóriaazonosítók tartoznak az adott szinten egybe. Ezért is a Cat0_ID, Cat1_ID, Cat2_ID hármas a szimpatikusabb számomra az adott esetben.

Természetesen van még 2 tábla ahol hasonló gondom van de félig meddig visszavezethető ide, de ezt most nem akartam bekavarni ide:
-tulajdonsag_set_list (ez tartalmazza select listánál megjelenítés esetén a lehetséges értékeket)
-categoriak_tulajdonsag_set (ez pedig az összekapcsoló táblája)

Előre is köszönöm a segítséget, és az építő jellegű hozzászólásokat.

Ui. (2008.05.14 09:43):
Közben kaptam egy ötletet. Használjak VIEW táblát a kapcsolótáblára. Szépen egyéni azonosítóval kössem össze az adatokat, de a VIEW táblán keresztül könnyen bármit ki tudok olvasni.
A kérdésem, hogy a VIEW csak azt könnyíti meg, hogy szebb selecteket tudjak írni és attól a háttérben mindig végrehajtja a parancsokat, vagy van valamilyen szinten gyorsító funkciója is.
51

Kategorizálás

foxmulder · 2008. Május. 14. (Sze), 09.54
Nekem valahogy nem tetszik, hogy a kategorizálás mélysége kötött, vagyis az, hogy van kategória, alkategória, al-alkategória és punktum.
Vagyis szerintem a termekek-ben elég csak egy kategoria_id, a kategoriak (vagy categories) pedig nézzen ki így: (id, szülő_kategória_id, név), vagy lásd: hierarchikus adatkezelés SQL-lel PHP-ben I. és II.

A másik az, hogy egy szöveges értékkel kapcsolatban szerintem nem igazán a szöveg minimális vagy maximális hossza (a karakterek száma) a lényeges korlátozó tényező, hanem mondjuk az, hogy egy "szín" tulajdonság értéke 'piros', 'kék' és 'zöld' lehet (és nem mondjuk: 'paprikajancsi').

UI.: Ja, vagy erre vonatkozik a tulajdonsag_set_list? Akkor minek a categoriak_tulajdonsag táblában a MinLength és MaxLength?
58

Kategorizálás megint

foxmulder · 2008. Május. 14. (Sze), 11.37
Az általad javasolt termekek táblával megvalósítható, hogy egy termék több kategóriába (vagy al- és al-alkategóriába) is besorolható legyen?
59

Válasz

world-s · 2008. Május. 14. (Sze), 12.13
Szia!
Egyben válaszolnék.
"tulajdonsag_set_list" valóban az a tábla ami leírja a lehetséges étékeket mondjuk egy select esetén.
A "categoriak_tulajdonsag" tábla feladata, hogy ha a php oldal megmondja, hogy xyz kategóriában tartózkodik a felhasználó, akkor ott milyen tulajdonságok vannak értelmezve, azok milyen értékeket vehetnek fel.
MinLength és MaxLength akkor kerül érvénybe, ha az adott kategórián belül szöveges adatbekérés van.
pl.: telefonoknál a gyártó neve max 10 karakter lehet, autók esetén max mondjuk 30 karakter.
Mivel nagyon sok féle tulajdonság van, ezért akartam ezeket a dolgokat is SQL-ban tárolni és nem beégetni a PHP kódba.

A kategóriákat azért így gondoltam, mert a 3 szint minden esetben elég az én esetembe arra, hogy meg tudjam határozni, hogy milyen egyéni sajátosságokkal (tulajdonságokkal) bír egy adott termék.

Az a kettőt amit írtál igen érdekesek, sőt a második.... ;)
A kérdésem az, hogy ha a kategória szint nálam kötött, akkor érdemes -e ennyire elbonyolítani, vagy sem.
Minek mi az előnye, és hátulütője.

A Cat0_ID, Cat1_ID, Cat2_ID, -nak az, hogy pofon egyszerűen, nem csak a lehetséges alkategóriákat tudom lekérdezni a "categoriak" táblából (pl.: az mondjuk a műszaki cikkeket alkategóriái....)

.... where Cat0_ID='1' AND Cat1_ID!='0' AND Cat0_ID='0'



, hanem
az összekapcsoló táblából ("categoriak_tulajdonsag") is könnyen le tudom kérdezni egy selecttel a lehetséges tulajdonságokat: (pl.: az mondjuk a műszaki lehetséges tulajdonságai....)

.... where Cat0_ID='1' GROUP BY Tul_ID

Sőt a ” categoriak_tulajdonsag_set”-ből ugyanígy tudnám a lehetséges választható értékeket is listázni.
Természetesen ennek is van hátránya…
Ha nem teljes általánosságban vesszük a kategóriákat, akkor sem tetszik?
62

Válasz és kérdés

foxmulder · 2008. Május. 14. (Sze), 12.39
A kategorizálás mélysége tényleg egyedi megítélés dolga (bár én inkább választanám a később tetszőlegesen bővíthető változatot, ki tudja, hová fejlődik a cég).

A szöveges értékeknél viszont tényleg nem értem, miért lényeges a karakterek száma (a példádnál maradva az autógyártók nevei jellemzően hosszabbak, mint a telefonokat gyártók nevei? Tudom, hogy ez csak példa volt, de ilyen szempontból pont jó példa)?
61

Kategória vs. tulajdonság

foxmulder · 2008. Május. 14. (Sze), 12.24
A 38-as hozzászólásodban írsz egy példát:
Pl.
"Ruházat->Gyerekholmi->Zolni" menüpont a tárolt belső adatbázisból a ruházat->zokni kategóriából a gyereknek való tulajdonsággal rendelkező termékeket fogja leszűrni

"Ruházat->Zolni->Gyerekzokni" menüpont szintlén hasonló szűrőket használ mint fent


Ebben úgy érzem, keveredik a kategória és a tulajdonság fogalma. A "Ruházat->Gyerekholmi->Zolni" menüpontban a Gyerekholmi tulajdonság, a többi kategória? Vagy épp az a célod, hogy a tulajdonságok és a kategóriák különbsége a user számára el legyen rejtve?

Hasonló fogalomzavart sejtek a tag-elést taglaló diskurzusban, ill. amonrpg 36-os hozzászólásában:
Ja, és ne csoportosítsd a tag-eket típus szerint, mert nincs értelme. Azaz, kit érdekel, hogy a piros tag szín?

Szerintem a "piros" a "szín" tulajdonság egy lehetséges értéke. Viszont vbence ezt írja a 25-ös hozzászólásban:
A cimkézés ... nem a tulajdonságok tárolására szolgál, csak a csoportosításra.


UI.: ha a tag-elés elvetve, az egész post sztornó ;)
63

Tagelés

vbence · 2008. Május. 14. (Sze), 12.58
Én úgy látom, a tagelés logikáját nem igazán érti a kérdező, úgyhogy további kérdés helyett a témát diszkréten átugrotta ;) A másik lehetőség, hogy a tulajdonságok szerint csoportosítani is szeretne, ennek viszont ellentmond az utolsó vázlat, ami szerint külön mezőket tart fent a csoportosításnak.. ki érti ezt :)
64

Válasz ;)

world-s · 2008. Május. 14. (Sze), 13.00
Kicsit rátapintottál a lényegre. ;)

Tehát bent van egy struktúrám, illetve kint van egy menüstruktúrám.

Az, hogy küldő és a belső között mi az átjárás az megvan.

Most a belső struktúráról írtam, amikor is van 3 menüszint (ez elég arra, hogy szét tudjam választani, hogy az egyes tulajdonságokat, mert ami ezen 3 szinten belül van azoknak egyforma tulajdonságokkal is rendelkeznek.)

Kifelé természetesen nem így fog látszódni, mivel ott több féle kategória is lehetséges.
Minden egyes kinti kategória le fog írni egy belső kategóriát/kategóriákat, illetve különböző tulajdonságszűrőket.

Tehát a fenti példánál maradva (kicsit idióta lesz a példa, de talán érthető):
"Ruházat->Gyerekholmi->Zolni" a ruházat főkategória, zokni alkategóriát jelenti ahol az ajánlott életkor tulajdonság 0-16 éves kor között van.

Tehát most az elrejtett belső (fix kategóriaszintű) struktúraábrázolásra keresek jó megoldást.

Üdv:
Zoli
66

Hurrá :)

foxmulder · 2008. Május. 14. (Sze), 13.10
Akkor megint elővehetem kedvenc módszeremet, a specializált egyedtípust! Van egy absztrakt Menupont egyedtípusunk két specializálttal: Kategória és Tulajdonság.

Tehát most az elrejtett belső (fix kategóriaszintű) struktúraábrázolásra keresek jó megoldást.

Nem ezt oldottad meg a három kategória szinttel (mármint a belső struktúrát)? Inkább a külsővel van a gond (már persze, ha ragaszkodsz ahhoz, hogy a user számára ne legyen megkülönböztethető a halmaz->alhalmaz->al-alhalmaz láncban a kategória és a tulajdonság).
67

???

world-s · 2008. Május. 14. (Sze), 13.31
"Akkor megint elővehetem kedvenc módszeremet, a specializált egyedtípust! Van egy absztrakt Menupont egyedtípusunk két specializálttal: Kategória és Tulajdonság."

Ezt kifejtenéd kicsit, hogy értsem...? ;)

"Nem ezt oldottad meg a három kategória szinttel?"
De igen. Viszont kaptam olyan megjegyzést (nem itt, hanem bent nálunk), hogy nem igazán követi a normalizálás elvét. Miért nem kap a kategóriahármas a ”categoriak” táblában egy egyéni ”CAT_ID”-t amit használhatok a "categoriak_tulajdonsag" összekapcsoló táblában a ”Cat0_ID”, ”Cat1_ID” és ”Cat2_ID” helyett.

Viszont ezzel az volt a problémám, hogy ekkor az összetartozó kategóriákat előbb ki kellene gyűjtenem ahhoz, hogy meg tudjam mondani, hogy pl. milyen tulajdonsággal rendelkezhetnek azok a termékek amik "műszaki cikk"-en belül találhatók attól függetlenül, hogy az ”mosógép”, vagy ”videómagnó”.

Ez a két megoldás között őrlődöm. Hogy inkább könnyű lekérdezésre érdemes ilyenkor fókuszálni (”Cat0_ID”, ”Cat1_ID” , ”Cat2_ID”), vagy inkább arra, hogy normalizált legyen (”CAT_ID”).

Erre volt még a kérdés, hogy ha VIEW táblával áthidalom a problémát, akkor ezzel elérek valamit, vagy csak annyit, hogy számomra egyszerűbb lesz a select megírása.
Tehát nincs gyorsító, egyéb hatása?
Vagy ez így is lassabb lesz mintha közvetlenül a "categoriak_tulajdonsag" táblában egy egyszerű selectel tudnák szűrni?

Üdv:
Zoli
68

Szerintem...

foxmulder · 2008. Május. 14. (Sze), 14.35
...a két megoldás között szerintem nincs hatékonyságbeli különbség. Ez a megoldás például széltében elterjedt, tehát olyan súlyos gond nem lehet vele (plusz az adatmodellezés szabályainak is megfelel):

termékek (id, ez, meg, az....)
kategóriák (id, szülő_kategória_id, név)
termékek_kategóriák (id, termék_id, kategória_id)

(a "kategóriák" helyett megfelel a "tagek" kifejezés is :), lásd: 23-as post)
Ráadásul így egy termék több kategóriában is szerepelhet.
70

Kifejtés

foxmulder · 2008. Május. 14. (Sze), 14.47
Ezt kifejtenéd kicsit, hogy értsem...? ;)


Nem biztos, hogy szükséges, attól függ, hogy mennyire mosódik össze (ill. válik szét) a kategória és a tulajdonság. Fogalmi szinten. Ahogy a 69-es hozzászólásban elmerengtem: a user számára jól különválasztható, hogy kategória, vagy tulajdonság alapján választ?
Merthogy úgy tűnik a két dolognak vannak közös jellemzői. Mindkettő egyfajta találatszűkítő funkciót tölt be. Azt is mondhatnánk, hogy a kategória is csak egy tulajdonság, ami rendelkezhet Ruhák, Autók, Zoknik stb értékkel (és mellesleg meg van spékelve egy hierarchikus dimenzióval, de ez most lényegtelen).
69

Csak, hogy értsem

foxmulder · 2008. Május. 14. (Sze), 14.35
[csak a hozzám hasonló kekeckedők olvassák végig :)]

Konkrét példa:

Userünk rátalál a Termékek menüpontra és ráklattyint. Megjelennek az elsődleges termékkategóriák: Autók, Ruházati termékek, Hasadóanyagok... Ezen a szinten még nem jelennek meg tulajdonságok, mert nincs minden terméktípusra egyaránt jellemző tulajdonság (bár elképzelhető, hogy van 30E forintom és el akarom költeni, tök mindegy mire, tehát klattyintok a max 30E Ft tulajdonságra, vagy mindegy mit veszek, csak bio legyen, vagy csak a hazai termékek érdekelnek. Az azért nehezen hihető, hogy mindegy mi a termék, csak piros legyen). Tehát továbbmegyünk valamelyik termékkategóriát követve, például Ruházat. Megjelennek a kategórián belüli alkategóriák (Zoknik, Bugyik...) de egy másik listában azok a tulajdonságok is amelyek a Ruházati termékek kategória szintjén értelmezhetőek (pl.: minta (select: egyszínű, kockás, csíkos...), szezon (szintén select: tavasz-nyár-ősz-tél), méret (gyermek, kamasz, felnőtt, ill. 32, 34, 36, bár ez cipőnél és szoknyánál mást jelent, sebaj, a méret tulajdonságot (ha ilyen egzakt, számszerű) nem a Ruházati termékek, hanem a Zoknik-Bugyik-Szoknyák szinten fogjuk értelmezni)).
Szóval a Ruházati termékeken belül már két listát követhetünk, a további alkategóriákét vagy az ezen a szinten értelmezett tulajdonságokét. Ha az utóbbit követjük (pl.: szezon: téli holmik), akkor az egyik listában ugyanazokat az alkategóriákat látjuk majd, mint az előbb (Zoknik, Bugyik), a tulajdonságlistából pedig kiesett a szezon (hiszen azon belül vagyunk). Kérdés: a szűkítés milyen szintjén jelennek meg a konkrét termékek. Mert, ha már itt megjelennek, akkor ugyebár a kiválasztott tulajdonság alapján szűkítve.
Ha az alkategóriák közül választva megyünk tovább (pl.:Zoknik), akkor az új alkategória lista mellett egy új tulajdonságlista is megjelenik (méret, minta (a minta tulajdonság zoknik esetén nem ugyanazokat az értékeket tartalmazhatja mint az eggyel feljebbi szinten, mert itt már lehet például "garfieldos" is)).

Kérdés: mivel world-s három kategóriaszintet határozott meg, lenne még egy kategóriaszintünk a Zoknik-on belül. A Garfieldos zoknik al-alkategória, vagy a motívum tulajdonság egyik értéke legyen? Persze az lesz, amivé tesszük (elképzelhető egy Ruházat->Alsóruházat->Zokni hierarchia is, ekkor egyértelmű, hogy a Garfieldos egy tulajdonságérték), de én itt valami logikai bibit gyanítok. Ha valami nem egyértelmű, akkor nem hibás valahol az adatmodell?
71

:)

world-s · 2008. Május. 14. (Sze), 15.01
Ezt szépen végigvezetted.
Köszönöm.

Ez én fejemben úgy született meg a 3 belső kategóriaszint, mert a lehetséges termékeket elnézve úgy néztem, hogy ez a szint elegendő ahhoz, hogy csoportosítani tudjam a tulajdonságokat.
Tehát a "Ruházat->Alsóruházat->Zokni" kategóriában a "Garfieldos" zokni is ugyanolyan tulajdonságokkal (méret, stb.) rendelkezik mint a nem "Garfieldos".

Tehát ez a 3 szintet a belső struktúrában azért gondoltam, hogy pl. egy zokninál né kérjem be termékfelvételkor, hogy dízeles, vagy benzines.

Üdv:
Zoli
72

Mindez világos :)

foxmulder · 2008. Május. 14. (Sze), 15.19
Nekem csak annyi most a gondom, hogy "mér' pont három?". Mert ha pl.: négy, akkor a Garfield-os zokni lehetne kategória is. Ez a hasraütésszerűség szerintem valami logikai bibit rejt, de nem jövök rá, mi az. Azért vagyok így rákattanva a kérdésre, mert egy ötletemet valahol ezen a szinten adtam fel.
73

Bocs, de még értetlenkedem picit.

foxmulder · 2008. Május. 14. (Sze), 17.01
Hogy is van ez a categoriak tábla? Azt írod, az első mező:
-Cat_ID (egyéni azonosító, ha van rá szükség egyáltalán. Még nem biztos, hogy kell)

Ha nincs rá szükség, akkor mire hivatkoznak a további idegen kulcsok (vagy nem azok?):
-Cat0_ID
-Cat1_ID
-Cat2_ID

A Termékek táblában csak annyit írsz:
-cat0 (kategória)
-cat1 (alkategória)
-cat2 (al-alkategória)
ezek nem tűnnek idegen kulcsnak, a categoriak_tulajdonsag táblában viszont idegen kulcsokból álló hármast használsz (legalábbis erre utal a nevek _ID végződése):
-Cat0_ID
-Cat1_ID
-Cat2_ID

Valamint a kategória nevét is a categoriak táblában tárolod. Ugyanakkor a Termékek, illetve a categoriak_tulajdonsag táblákban egyaránt számhármasokkal hivatkozol a kategóriára (mondván, hogy mivel kéznél van, így gyorsabb), de a kategória nevéért le kell kérdezned a categoriak táblát.
74

Válasz

world-s · 2008. Május. 15. (Cs), 12.42
Szia!

Akkor azt írom ami jelenleg van.

categoriak
-Cat_ID (egyéni azonosító. Ez a kulcsa az összekapcsolásoknak)
-Cat0_ID (meghatározza, hogy az adott kategória mely főkategóriában van. Igazából az alá fölé rendelési viszonyt írja le)
-Cat1_ID (meghatározza, hogy az adott kategória mely alkategóriában van.)
-Cat2_ID (meghatározza, hogy az adott kategória mely alkategóriában van.)
-Name (Ez a alkategória megjelenő neve)

Termékek
Termékek (Ez tartalmazza a termékeket)
-id (egyéni azonosító)
-Cat_ID (kategória azonosító)
-Name (termék neve)
-Ar (termék ára)
-.... (további olyan tulajdonságok amik minden terméknél léteznek)

categoriak_tulajdonsag
-Cat_ID (kategória azonosító)
-Tul_ID (tulajdonság azonosító)
-Tul_Cat_Name
-MinValue
-MaxValue
-MinLength
-MaxLength

Hogy egyszerűen le tudjam kérdezni, hogy egy adott kategórián belül (CAT_ID) milyen tulajdonságok vannak, azt könnyen le tudom kérdezni.
Viszont sokszor a kategória fában nem a legbelső szinten fogok elhelyezkedni.
Ilyenkor nem egy konkrét kategóriára vagyok kíváncsi, hanem az összes a kategórián belül eső alkategóriára is.
(Azért van, mert nem akarom a kintebbi kategóriaszinteken felvenni a lehetséges tulajdonságokat!)

Zoli
76

Miért így?

zila · 2008. Május. 15. (Cs), 13.40
categoriak
-Cat_ID (egyéni azonosító. Ez a kulcsa az összekapcsolásoknak)
-Cat0_ID (meghatározza, hogy az adott kategória mely főkategóriában van. Igazából az alá fölé rendelési viszonyt írja le)
-Cat1_ID (meghatározza, hogy az adott kategória mely alkategóriában van.)
-Cat2_ID (meghatározza, hogy az adott kategória mely alkategóriában van.)
-Name (Ez a alkategória megjelenő neve)


Miért van 3 kategória id? Nem elég egy sima parent_id ami a közvetlen szülő kategória id-je? Így tetszőleges mélységben ágyazhatsz egymásba kategóriákat... Ha meg több kategóriában akarod szerepeltetni akkor kell még egy kapcsolótábla.
77

Válasz

world-s · 2008. Május. 15. (Cs), 14.40
Azért nem ezt választottam, mert akkor ha én a legfelső szinten vagyok, akkor:
- először meg kell keresnem, hogy milyen alkategóriák vannak. Ezt a parent_id-vel könnyen meg is tudnám oldani
- viszont ezek után az előzőleg kapott találatokat is tovább kellene boncolnom. Megnézni, hogy melyek azok a kategóriák, melyek parent_id-je az előbb kapottak valamelyike.
És csak ekkor kapom meg, hogy mely kategóriákról is van szó.
Ezek után tudom meg azt, hogy milyen tulajdonságok lehetnek, úgy, hogy a select-be agy IN után felsorolom őket.

Számomra ez a 3-mad, csak azért kell, hogy a különböző tulajdonságsémákat össze tudjam állítani.
Ebbe a hármasba belefér úgy vélem minden.
pl. gépkocsiknál már 2 szint is elegendő:
-gépjárművek->hasznongépjárművek
Ezen belül az összes termék már ugyanolyan tulajdonságokkal rendelkezik (üzemanyag, zöldkártya, stb.)

Inkább lehetne tulajdonság_goup-oknak hívni, hisz az ügyfél felé kommunikált kategorizálás ettől teljesen eltérő lesz. Ezek már csak hivatkozások a különböző tulajdonság-együttállásokra (és ilyenkor szinte ez is kicsit az).
Pl.:
categoriak
Cat_ID, Cat0_ID, Cat1_ID, Cat2_ID, Name
1, 1, 0, 0, Autók
2, 1, 1, 0, Haszongépjárművek
3, 1, 2, 0, Személygépkocsik
.....

Akkor:
autó->diesel->személygépkocsi =====>>>> főkategóra=autók (CAT0_ID=1); alkategória=személygépkocsi(CAT1_ID=2); üzemenyag_tipus=deiesel

Zoli
81

feladom :)

zila · 2008. Május. 16. (P), 17.59
Bevallom őszintén elvesztettem a fonalat. Érzésem szerint túlbonyolítod a megoldást, de ezt most nem tudom érvekkel alátámasztani...
75

Na ezt hogyan?

world-s · 2008. Május. 15. (Cs), 13.06
Elkezdtem a mostani szerkezetben felvenni próbából tulajdonságokat.
Kezdtem az autókkal, és máris nyílt egy kérdés. Ugye mivel sokféle variáció lehetséges, azért mindent adatbázissal szeretnék leírni.

pl.:
riasztó (lehetséges értékek: nincs megadna, nincs, van)
centrálzár (lehetséges értékek: nincs megadna, nincs, van)
klíma (lehetséges értékek: nincs megadna, nincs, mauális, automata)
vezetooldali_legzsak (lehetséges értékek: nincs megadna, nincs, van)
utasoldali_legzsak (lehetséges értékek: nincs megadna, nincs, van)
oldal_legzsak (lehetséges értékek: nincs megadna, nincs, van)
hatso_oldal_legzsak (lehetséges értékek: nincs megadna, nincs, van)
fugguny_legzsak (lehetséges értékek: nincs megadna, nincs, van)

Ha valaki riasztós autót keres, akkor egyszerű a szűrés.
A valaki centralzáras riasztósat keres, akkor sincs probléma, mert a két tulajdonságot ÉS-elem a lekérdezésben.
Viszont mi van akkor ha valaki azt mondja, hogy mindegy milyen klíma, csak legyen.
Vagy mindegy milyen légzsák, csak legyen, és majd ő eldönti a találatok nézésekor, hogy szimpatikus -e az adott autó.

A légzsáknál ugye azt kellene tudni, hogy az egyes típusokat nem ÉS-el, hanem VAGY-al kellene összekötni, a légkondinál pedig mindegy milyen, csak legyen.

Van egy ötletem, de még nem kavarnák be vele...
Üdv:
Zoli
78

!nincs

foxmulder · 2008. Május. 15. (Cs), 19.46
A "nem nincs" azt jelenti van.

WHERE `klima`!='nincs'
79

Válasz

world-s · 2008. Május. 16. (P), 10.53
Ez még igaz is mondjuk a klímánál, viszont a légzsáknál nem.
Ott több tulajdonság összességét kellene venni.
De a klímánál is meg kellene mondani a van klíma, az azt jelenti, hogy klíma tulajdonság nem "nincs".
Ha mondjuk a színeket nézem, akkor meg, ha olyat szeretnék, hogy világos, sötét, akkor meg ugye azt kell látnom, hogy mely színekre mondtam azt, hogy világos, melyekre hogy sötét.

Ha menürendszerből jövök akkor nincs gondom, hisz akkor az egyes menüpontokhoz tudom rögzíteni a szűrőket.

Viszont ha egy kereső ablakot képzelek el, akkor ugye ott eleve látnom kell, hogy van ilyen megközelítés is.
Pl: összetett keresésnél a légzsákok típusaira kereshetek, egyszerű keresésnél pedig arra, hogy van -e légzsák vagy nincs.

Mivel vagy 400 tulajdonságom lehetséges, és ebből adódóan nem a programba szeretnél beégetni ezeket a tulajdonságokat.

Ezért én arra gondoltam, hogy ezek a tulajdonságok (van légzsák, van légkódi, stb.) felvenném mint tulajdonság.
A tulajdonságoknál lenne egy arra szolgáló mező ami le tudná írni az összefüggéseket. Tehát valahol látszódna, hogy számolt adat.

Viszont, az hogy ezt hol használom fel arra két megoldásom van:
1. mikor felveszek egy új terméket, akkor ezek alapján kiszámolom az összefüggéseket, és utána mint valós tulajdonságot rögzítem. Tehát nem az ügyfél adja meg, hanem az ügyfél egyéb válaszaiból a gép számolja ki.
Előnye, hogy bármikor könnyen elérhető kereséskor, hátránya viszont az, hogy ha felveszek később egy új tulajdonságot, vagy módosítok egy ilyen összefüggést, akkor az összes termékre újra kell számolnom.

2. nem a felvételnél, hanem a kereséskor generálom le ezeket az összefüggéseket. Ez azt jelentené, hogy nekem egy tulajdonság egyik mezőjében lévő értéket a select-ben kellene értelmeznem. Ezt nem tudom hogy lehet.
Ha lehet itt is kerülném azt, hogy először értelmezem az összefüggéseket, majd ez alapján megírom az SQL-t.
Mintha láttam volna valamikor ilyet, de nem tudom hol és nem tudom hogy volt. Mintha generált volna egy változót SQL-ben, amivel összerakta a lekérdezést, majd ezt meg is tudta futtatni. De lehet nem ez a jó út.

Ötletek?...
80

Vissza az adatmodellezéshez

foxmulder · 2008. Május. 16. (P), 15.11
Új igények? Ejnye-bejnye :)

Azt írják az okos könyvek, hogy már az adatmodell szintjén meg kell oldani az ilyesfajta problémákat és nem az adatokat kezelő program(ok)ra bízni. Az persze kiküszöbölhetetlen (szinte), hogy ne menet közben derüljön ki az ilyesmi.

Szerintem azért tudnál olyan SQL lekérdezést írni, ami mind a négy, légzsákokkal kapcsolatos tulajdonságot lekérdezi és abból ad egy igen-nem választ.

A színekkel kapcsolatos világos-sötét kiegészítés viszont tipikusan utólag megjelent ötlet, úgyhogy vagy szoftveres tákolás, vagy vissza az adatmodellhez. Egy köztes megoldás: A "szín" tulajdonság lehetséges értékei: sötétkék, világoskék, kék... A sötét színek lekérdezése valami ilyesmi: WHERE `szin` LIKE 'sötét'.
De inkább lásd: hozzászólás témája...
82

Kérdés

world-s · 2008. Május. 19. (H), 09.12
Ez meg lehet csinálni?
(Kicsit leegyszerűsítve írom csak.)

SELECT tul.*,
CASE
WHEN tul.feltetel THEN 'true'
ELSE 'false'
END as type_value
FROM tul, tertul
WHERE ...

És a tulajdon táblában, a feltétel mezőben ez szerepelne:
tulertek.value='maunális' OR tulertek.value='automata'

Megoldható, hogy ez így működjön és kigyűjtse az összes légkondís autót?
Gondolom úgy ahogy leírtam, úgy azt vizsgálná, hogy van -e valami az adott mezőben....


Üdv:
Zoli
83

Hogyan az OR?

world-s · 2008. Május. 23. (P), 13.37
Sziasztok!

Kicsit egyszerűsítettem az eddig tárgyaltakon.
Kénytelen voltam rájönni, hogy mindent nem tudok megcsinálni MYSQL-ben a szerveren belül.
Az egyszerűsítés annyit jelent, előre beolvasom milyen tulajdonságok is léteznek, vagy melyekre van szükségem. Ez két ponton jelent egyszerűsítést, s így nem kell a MYSQL-nek számolni:
- előre meg tudom határozni, hogy mely mezőben van tárolva egy adott tulajdonság értéke (TEXT, DECIMAL, stb.)
- a fentiekből adódik, hogy szépen meg tudom írni a tulajdonságokat mutató mezőket PHP-ból még.

Viszont most, hogy a kiszolgáló részt írom előjött még egy probléma:

Visszakanyarodva Protezis (12. hozzászólás) kódjára, mely arra adott megoldást, hogy miként tudom megnézni, hogy egy adott termék megfelel -e az elvárt kritériumoknak.
Ehhez a "HAVING"-et használtuk fel "GROUP BY"-al. (sajnos a második miatt elveszek a tulajdonságok, viszont ezt egy beágyazással küszöböltük ki később.)

SELECT COUNT(ter.id) AS megfeleles, ter.nev, ter.szoveg  
FROM termekek ter  
INNER JOIN termekektulajdonsagok tertul ON ter.id = tertul.termek_id  
INNER JOIN tulajdonsagok tul ON tertul.tulajdonsag_id = tul.id  
WHERE (tul.nev = "WAP képes" AND tertul.ertek = "igen") OR (tul.nev = "kártya független" AND tertul.ertek = "igen")  
GROUP BY ter.id  
HAVING megfeleles = 2


A probléma akkor került elő, amikor azt az általános részt írtam, ami az SQL parancs szűrő részét lenne hivatott legenerálni.

Addig nincs gondom a mostani módszerrel, amíg a szűrő feltételei ÉS kapcsolatban vannak.
Viszont amint VAGY-lagos feltétel is szerepel, akkor máris nem tudom számszerűsíteni, hogy ez alapján hányszor szerepelne az adott rekord.

Pl. ha végeredményként ilyet szeretnék szűrni, akkor nem tudom hogy írjam le ha HAVING-el:
... WHERE (eletkor > 18 AND nem='f') OR (eletkor > 20 AND eletkor < 30 AND nem='n' AND haj='osz')


Mivel lehet a HAVING módszert kiváltani, mert itt azt sem tudnám megmondani, hogy a HAVING után mit írjak, hiszen nem tudom azt sem meghatározni, hogy hány együttállás szükséges.

Üdv:
Zoli
84

Mi a vélemyén?

world-s · 2008. Május. 26. (H), 10.22
Mi a meglátásotok arról, ha úgy végezném el a szűrést, hogy először létrehozom azokat a virtuális mezőket amikbe a tulajdonságokat legenerálom, majd WHERE helyett (mert mező ALIAS-okra nem használható) HAVING-el normálisan szűrök mintha egy normál tábla esetén tenném ezt.

SELECT ter.nev,    
group_concat( CASE WHEN tul.nev = "WAP képes" THEN tertul.ertek ELSE NULL END ) wap_kepes, 
group_concat( CASE WHEN tul.nev = "kártya független" THEN tertul.ertek ELSE NULL END ) kartya_fuggetlen, 
group_concat( CASE WHEN tul.nev = "MMS képes" THEN tertul.ertek ELSE NULL END ) MMS_kepes   
FROM `!termekek` ter   
INNER JOIN `!termekektulajdonsagok` tertul ON ter.id = tertul.termek_id   
INNER JOIN `!tulajdonsagok` tul ON tertul.tulajdonsag_id = tul.id 
GROUP BY ter.id 
HAVING (MMS_kepes='igen' AND wap_kepes ='igen') OR kartya_fuggetlen='igen'
Mennyire lassabb egy HAVING-es lekérdezés?
Van e szebb hatékonyabb megoldás arra az alap problémára, ha az ember szűrni szeretne egy olyan szerkezetben, ahol a termékeket és tulajdonságokat egy kapcsolótáblán keresztül köti össze.

Előre is köszi.

Zoli
85

Kész csőd!!!!!

world-s · 2008. Május. 28. (Sze), 14.57
Elkészült az SQL generátorom.

Valami ilyesmit készít:

select belsotable.*,
(CASE WHEN ( `vezetooldali_legzsak`='true' OR `utasoldali_legzsak`='true' OR `oldal_legzsak`='true' OR `hatso_oldal_legzsak`='true' OR `fugguny_legzsak`='true' OR `legzsak_kikapcsolo`='true') THEN 'true' ELSE 'false' END ) `van_legzsak`
FROM (
SELECT ter.ID product_Id, ter.Cat0 product_Cat0, ter.Cat1 product_Cat1, ter.Cat2 product_Cat2, ter.Type product_Type, ter.Owner product_Owner, ter.Name product_Name, ter.Summary product_Summary, ter.Description product_Description, ter.Price product_Price, 
group_concat( IF(`tertul`.`Attr_ID` = '1', `tertul`.`Value_smalltext`, NULL) ) `gyarto`, 
group_concat( IF(`tertul`.`Attr_ID` = '2', `tertul`.`Value_smalltext`, NULL) ) `tipus`, 
group_concat( IF(`tertul`.`Attr_ID` = '3', `tertul`.`Value_integer`, NULL) ) `kivitel`, 
group_concat( IF(`tertul`.`Attr_ID` = '4', `tertul`.`Value_datetime`, NULL) ) `gyartas_eve`, 
group_concat( IF(`tertul`.`Attr_ID` = '6', `tertul`.`Value_datetime`, NULL) ) `muszakivizsga_ervvege`, 
group_concat( IF(`tertul`.`Attr_ID` = '10', `tertul`.`Value_integer`, NULL) ) `uzemenyag`, 
group_concat( IF(`tertul`.`Attr_ID` = '51', `tertul`.`Value_truefalse`, NULL) ) `vezetooldali_legzsak`, 
group_concat( IF(`tertul`.`Attr_ID` = '52', `tertul`.`Value_truefalse`, NULL) ) `utasoldali_legzsak`, 
group_concat( IF(`tertul`.`Attr_ID` = '53', `tertul`.`Value_truefalse`, NULL) ) `oldal_legzsak`, 
group_concat( IF(`tertul`.`Attr_ID` = '54', `tertul`.`Value_truefalse`, NULL) ) `hatso_oldal_legzsak`, 
group_concat( IF(`tertul`.`Attr_ID` = '55', `tertul`.`Value_truefalse`, NULL) ) `fugguny_legzsak`, 
group_concat( IF(`tertul`.`Attr_ID` = '56', `tertul`.`Value_truefalse`, NULL) ) `legzsak_kikapcsolo`
FROM `product` ter 
INNER JOIN `product_attribute` tertul ON ter.ID = tertul.Product_ID 
GROUP BY ter.ID 
) AS belsotable 
HAVING `gyarto`='Audi' AND `uzemenyag`=2 AND `tipus`='A3' AND `van_legzsak`='true' AND `muszakivizsga_ervvege` = '2008-08-21 15:07:04' 
A probléma, hogy csináltam egy 50.000 rekordos termék táblát és egy 1.300.000 rekordos terméktulajdonság táblát.
Ha csak a belső SELECT-et futattom le, akkor is 145-155 másodperc alatt fut le egy kérés.
Ez ugye így használhatatlan.

Mi a francot lehet ezzel kezdeni?
Nem hiszem, hogy nem lehet megoldani ha a termékeket és a tulajdonságokat egy kapcsolótáblában összekötöm, akkor az egyes tulajdonságokra rá lehessen keresni AND és OR kapcsolattal is.

Ez a struktúra csak akkor működne ha a termék irányból indulnák ki és ez alapján annak a tulajdonságait szeretném látni.

Valakinek valami ötlete?

Üdv:
Zoli
86

nem szabványos a query

Hodicska Gergely · 2008. Május. 28. (Sze), 19.43
Először is ez a query tisztsséges DB-n nem fut le. Group by esetén nem kérdezhetsz le nem aggregált mezőt anélkül, hogy egy aggregátor függvényt használnál rá.

Aztán nem is értem teljesen ezt a felépítést, mi szükség van a subselectre, miért nem lehet a havinget azon belülre tenni...

...amely havingre nincs is szükséged: mert így előbb megcsináltatod a DB-vel teljes kereszt táblát, majd csak ezután állsz neki szűrni. Minimum a belső queryben kéne szűrnöd, de a MySQL ilyesmiben nem a legokosabb, ezért a biztos, hogy egy online view-t (subselect) csinálsz, amiben már csak a leszűrt termékek vannak, és ehhez joinolod a másik táblát.

Végül meg nézd, hogy a tertul táblán van-e Product_ID mezőn index. Szerintem nincs, és ez is drsztikusan ronthatja a query teljesítményét, meg szépen föleszi a szervert is.


Üdv,
Felhő
87

Szia!

world-s · 2008. Május. 28. (Sze), 21.56
Köszönöm, hogy segítesz.

Amúgy kiderült, hogy egy elég gyenge gépen a tesztgép.
Most áttettem egy jóval nagyobbra (4 magos és 4GB memória a 128MB helyett).
Ekkor olyan 14 másodperc alatt fut le (jóval jobb, de még mindig brutális), viszont a második futatás már 0.005 alatt is lefut.

Viszont ebből is látszik, hogy még van mint javítani:
-"Group by esetén nem kérdezhetsz le nem aggregált mezőt anélkül, hogy egy aggregátor függvényt használnál rá."
Ezt nem teljesen értem.

-"mi szükség van a subselectre" nem mindig van subselect. Csak akkor ha olyan mező van a lekérdezésben ami nem létezik magában az adattáblában, hanem csak számolt együttállásokból adódik. A belső SELECT-be szerintem is be lehet emelni azokat a szűrőket ami valódi tulajdonságokat tartalmaznak.
Azért nem tettem, mert egyenlőre még nem tudom hogy bontsam szét az eredeti feltételt a PHP-ban ami az SQL-t generálja:
1. a valódi mezők lekérdezhetők a belső SELECT-ben
2. a számolt mezők csak kívül
3. ha a számolt mező valamilyen együttállásban van egy virtuálissal, akkor ezeket a valódi mezőket is csak kívül lehet összefüggéseiben vizsgálni

Szerinted segíthet a dolgon ha szűkítem akkor az összekapcsolandó táblák mennyiségét?
Holnapra ilyesmi dolgokat szeretnék lepróbálni:
1. A belső SELECT-ben nem az összes terméktulajdonságot venném, hanem csak azokat a tulajdonságokat amiket fel is használok.

.....
FROM `product` ter 
INNER JOIN (select * FROM `product_attribute` WHERE `Attr_ID` in (1,2,3,4,6,10,51,52,53,54,55,56)) tertul ON ter.ID = tertul.Product_ID  
GROUP BY ter.ID 
....
2. Mi lenne, ha a tulajdonság táblából nem csak azokat a tulajdonságokat venném amikre szükségem van, hanem azoknak egy OR-al meg is kelljen felelnie az előre meghatározható feltételeknek. Bár sajnos a logikai összefüggéseket nem tudom még teljes mértékben kiértékelni csak a GROUP BY után, de a kiértékelendő értéktartomány elviekben csökkenne. Kérdés amit nyerek azt más helyen nem veszítem -e el.

.....
FROM `product` ter 
INNER JOIN (
select * FROM `product_attribute` WHERE 
(`Attr_ID` = '1' AND `Value_smalltext` = 'Audi') OR
(`Attr_ID` = '4' AND `Value_datetime` > '2000-01-01 00:00:00') OR
(`Attr_ID` = '4' AND `Value_datetime` > '2005-01-01 00:00:00') OR
) tertul ON ter.ID = tertul.Product_ID  
GROUP BY ter.ID 
....
3. Az 1. és a 2. továbbgondolva, ha nem a teljes termékpalettáról van szó, akkor a termék táblát is mondjuk kategóriára le lehet szűkíteni.

.....
FROM (
(
select * FROM `product` WHERE Cat in (1,2,3)
) ter 
INNER JOIN (
select * FROM `product_attribute` WHERE 
(`Attr_ID` = '1' AND `Value_smalltext` = 'Audi') OR
(`Attr_ID` = '4' AND `Value_datetime` > '2000-01-01 00:00:00') OR
(`Attr_ID` = '4' AND `Value_datetime` > '2005-01-01 00:00:00') OR
) tertul ON ter.ID = tertul.Product_ID  
GROUP BY ter.ID 
....
4. Ha nincs a szűrő feltételben olyan tulajdonság ami maga a terméknél van tárolva (pl. product_Name, product_Summary, product_Description, product_Price, stb.), akkor elviekben a JOIN is lehagyható lenne. Ekkor viszont az így kapott eredményhez utólag kell ezeket az az értékeket hozzáfűzni.
Még gondolkodom ezt hogyan tudom megtenni.

Van esetleg valami jó ötlet még? Amiket kigondoltam azoknak lehet hatása a futásra?

Tényleg: hogyan lehet a táblákat becachelni? Mivel azt tapasztaltam, hogy ha egymás után többször kérdezek le, akkor a futás idő jóval kisebb.

Előre is köszönöm.
Üdv:
Zoli
88

query cache

Hodicska Gergely · 2008. Május. 28. (Sze), 22.32
Ekkor olyan 14 másodperc alatt fut le (jóval jobb, de még mindig brutális), viszont a második futatás már 0.005 alatt is lefut.
Ez még mindig nagyon lassú, főleg egy jó gépen. A második adat nem számít, az a query cache.

"Group by esetén nem kérdezhetsz le nem aggregált mezőt anélkül, hogy egy aggregátor függvényt használnál rá."
Vannak azok az oszlopok, amelyeket felsorolsz a group by-nál, ezek szerint csoportosítasz. Egy adott csooportban ezen mezőknek ugyanaz az értéke (ezek az aggregált mezők). Minden egyes ilyen csoportból egy sor lesz a végeredményben, és te ezek közül a sorok közül választasz ki mezőket. Az aggregált mezők esetén egyértelmű, hogy mi legyen a mező értéke, hisz mindegyik sorban ugyanaz van. Viszont egy nem aggregált mezőben a csoporton belül az adott mezőben különböző értékek vannak, és a DB-nek ebből kéne valamelyiket visszaadnia. Egy rendes DB nem választ ki véletlenszerűen egyet ezek közül, hanem azt mondja, majd te mond meg jól, hogy melyiket is szeretnéd. Ezt teheted meg valamilyen aggregáló függvény segítségével, például azt mondod, hogy legyen a legkisebb, legnagyobb, átlag stb., a group_concat is egy ilyen függvény.

1. a valódi mezők lekérdezhetők a belső SELECT-ben
2. a számolt mezők csak kívül

"HAVING `gyarto`='Audi' AND `uzemenyag`=2 AND `tipus`='A3' AND `van_legzsak`='true' AND `muszakivizsga_ervvege` = '2008-08-21 15:07:04'"
Csak valahogy nem értem ezt a lekérdezést (de azt igen, hogy mit nem láttam az előbb :)), mert akkor ezesetben a másik irányból kéne megközelíteni. Először kérdezd le a tulajdonságok közül azokat az id-kat, amiknek meg van mondjuk mind a 4 tulajdonsága egy subselectben, és ehhez joinld a termék táblát. Erre a queryre egy kis trükk: select id from tags where tag = 'value1' OR tag = 'value2' OR tag = 'value3' group by id having count(*) = 3, tehát az a szám van a feltételben, ahány tulajdonságra vizsgálsz.

Most látom, hogy ilyesmi irányba mentél el a második felében a hozzászólásofnak, csak ez a having rész hiányzik.

Az index meglétét nézd meg, az akár százszoros vagy még durvább növekedést jelenthet. Amúgy is nézd meg a queryd explainjét, és abban egyből fog látszani, hogy a joinhoz használ-e indexet.


Üdv,
Felhő
89

Válasz.

world-s · 2008. Május. 28. (Sze), 23.38
Köszi a gyors választ.
"group_concat is egy ilyen függvény"
Ahogy írtad az lenne a jó, ha ezt a függvényt ki tudnám váltani egy olyanra ami azt az értéket veszi ki amelyik nem NULL. Csak ilyet egyenlőre nem találtam. Így akkor ezek a mezők eleven BLOB-ként jönnének ki, hanem az INT IND, a DATETIME, DATETIME, stb.... Talán az index itt is jobban érvényesülne. Vagy ezt az aggregáló függvény nekem kell valahogy megírni?

"Csak valahogy nem értem ezt a lekérdezést"

A `van_legzsak` tulajdonság nem létezik. Ezt más tulajdonságok együttállásából számolja. Viszont ezek csak a GROUP BY után áll rendelkezésemre, mikor egy sorrá tudom nyomom össze a tulajdonságokat.
Sajnos a valódi ALIAS-okat (pl. gyarto, tipus, kivitel, stb.) nem tudom egy SELECT-en belül felhasználni.

"tehát az a szám van a feltételben, ahány tulajdonságra vizsgálsz"
Tehát ez hasonlít ahhoz ami egy kezdeti verzióban volt (18. hozzászólás), csak is az értéktartomány szűrésére.
Ha ezt esetleg kombinálnám a holnapi 2. kísérletemmel, akkor azok is kiesnek amik durván kiesnek egy bizonyos értéktartományomon.

"Az index meglétét nézd meg" Vannak index-ek, viszont meg fogom nézni, hogy megfelelőek -e.

Üdv:
Zoli
90

Teszt

world-s · 2008. Május. 29. (Cs), 11.21
Első nekifutásra azt értem le, hogy lassabbak lettek a hívások (14->17 másodperc), ezért kivettem csak azt a rész, ami a tartományszűrést intézné:

Az vettem észre, hogy minél jobban le szeretném szűrni a tartományt annál lassabb a kérés:
(RESET QUERY CACHE használva)

SELECT * 
FROM `product_attribute` 
WHERE (
`Attr_ID` = '1'
AND `Value_smalltext` = 'Audi'
)
OR (
`Attr_ID` = '2'
AND `Value_smalltext` LIKE '%A%'
)
OR (
`Attr_ID` = '10'
AND `Value_integer` =2
)
OR (
`Attr_ID` = '6'
AND `Value_datetime` >= '2000-08-21 15:07:04'
)
OR `Attr_ID` 
IN ( 3, 4, 51, 52, 53, 54, 55, 56 ) 
Futás ideje: 0,0406 másodperc

SELECT * 
FROM `product_attribute` 
WHERE `Attr_ID` 
IN ( 1, 2, 3, 4, 6, 10, 51, 52, 53, 54, 55, 56 ) 
Futás ideje: 0,0136 másodperc

A tábla így néz ki:

CREATE TABLE IF NOT EXISTS `product_attribute` (
  `Product_ID` bigint(20) NOT NULL,
  `Attr_ID` bigint(20) NOT NULL,
  `Value_integer` bigint(20) default NULL,
  `Value_double` decimal(12,2) default NULL,
  `Value_smalltext` varchar(250) collate latin2_hungarian_ci default NULL,
  `Value_fulltext` text collate latin2_hungarian_ci,
  `Value_datetime` datetime default NULL,
  `Value_truefalse` enum('true','false') collate latin2_hungarian_ci default NULL,
  KEY `Product_ID_Index` (`Product_ID`),
  KEY `Integer_Index` (`Attr_ID`,`Value_integer`),
  KEY `Double_Index` (`Attr_ID`,`Value_double`),
  KEY `smalltext_Index` (`Attr_ID`,`Value_smalltext`),
  KEY `datetime_Index` (`Attr_ID`,`Value_datetime`),
  KEY `truefalse_Index` (`Attr_ID`,`Value_truefalse`),
  FULLTEXT KEY `fulltext_Index` (`Value_fulltext`)
) ENGINE=MyISAM DEFAULT CHARSET=latin2 COLLATE=latin2_hungarian_ci;

Miért lassabb az első kérés?
91

EXPLAIN

world-s · 2008. Május. 29. (Cs), 12.51
Megnéztem egy alap kérést a fenti táblára.
SELECT * 
FROM `product_attribute` 
WHERE `Attr_ID` =1
AND `Value_smalltext` =2 
Nem tudom jól értelmezem -e az EXPLAIN eredményét, de azt vettem ki, mintha le**arná hogy nekem van INDEX-em mondjuk a Value_smalltext-re is. Csak a Integer_Index-et használja az Attr_ID miatt.

select * FROM `product_attribute` WHERE    
(`Attr_ID` = '1' AND `Value_smalltext` = 'Audi') OR  
(`Attr_ID` = '2' AND `Value_smalltext` like '%A%') OR  
(`Attr_ID` = '10' AND `Value_integer` = 2) OR  
(`Attr_ID` = '6' AND `Value_datetime` >= '2000-08-21 15:07:04') OR  
`Attr_ID` in (3,4,51,52,53,54,55,56) 
Ennél pedig egyáltalán nem használ semmit.
Az érdekes, hogy

SELECT * 
FROM `product_attribute` 
WHERE `Attr_ID` =1
OR `Attr_ID` =3
OR `Attr_ID` =4
OR `Attr_ID` =51
OR `Attr_ID` =52
OR `Attr_ID` =53 
esetén nincs index használva, de ha az utolsó feltételt leveszem, akkor még van.
Zoli
92

Előre legyártás?

world-s · 2008. Május. 31. (Szo), 22.10
Gondolkodtam.
Lehet -e megoldás az, hogy mondjuk egy script 10 percenként elkészít egy táblát amibe az összes termék összes tulajdonságát összerakom.
Ezt arra használnám, hogy a keressek benne.
Igaz, hogy bazi sok mezeje lesz, de kevés rekordot fog tartalmazni.
Ráadásul szépen lehet keresni benne.
Persze az alap adatokon kívül nem tudom a többit hogyan lehetne indexelni.
Mi a véleményetek róla?
Nem tudom hasonló okok miatt van -e pl. a Va*erán is 1/2 órás késés az új aukciók kiírásakor, vagy ott ezt ellenőrzésre használják

Üdv:
Zoli
93

Teszt

world-s · 2008. Jún. 2. (H), 10.36
Ma reggel ki tudtam próbálni a fenti megoldást.
Igaz PHP-t kellett írnom hozzá, hogy legenerálja nekem az SQL parancsokat amit utána a PHPMYADMIN-ba beilleszthetek.

Az elkészült tábla: 164 mező+ a termék táblában tárolt pár alap mező és 50.000 terméket tartalmazz.
Méretileg ez fele annyit eszik mint maga az alap kapcsolótáblám.
Az eddig példaként használt SELECT pedig 14-17 másodperc helyett 0.2758 másodperc alatt futott le, úgy hogy csak a termék ID alapján van indexelve, amit a lekérdezésben nem használok fel.

Elég csúnya a megoldás, de úgy néz van benne fantázia. Bár kérdés, hogy ha már 500-700 mezős a tábla, akkor mit szól hozzá?
Van egyáltalán határ?

Üdv:
Zoli
94

termékkereső

chaser · 2008. Szep. 15. (H), 21.55
Hello,
Hol tart a termékkereső fejlesztése, esetleg működik már ki lehet próbálni?

Üdv,
ch