ugrás a tartalomhoz

mysql: ha egy mezőbe több értéket kell tároni, és gyorsan kell tudni keresni

world-s · 2013. Már. 7. (Cs), 21.40
Lesz egy nagy terhelésű, sok ügyfelet kezelő rendszer.
Van egy olyan gondom, hogy az ügyfelekről van olyan tulajdonság, ami nem csak egy értéket vehet fel mint mondjuk a szemszín esetén, hanem többet is.
Pl. egy ügyfélnek több féle hobbija is lehet.
Most így terveztem (természetesen ettől összetettem a dolog, de próbáltam lecsupaszítani a szerkezetet most)
create table user( 
   id integer , 
   nev varchar(100),
   eletkor integer
); 

create table user_hobbik( 
   user_id integer, 
   hobbi_id varchar(100) 
); 

create table user_hobbik( 
   user_id integer, 
   hobbi_nev varchar(100) 
); 

select u.*, h.* from user AS `u` 
LEFT JOIN user_hobbik AS `h` ON `u`.`id`=`h`.`user_id` 
where `user_hobbik`.`hobbi_id` in (1,2,3);
A fenti kereséssel azt szeretném megtudni, hogy mely ügyfeleknek van 1-es, 2-es, vagy 3-mas hobbijuk (futás, úszás, tenisz).

Ennek hatására ha az id=1-es usernek két hobbija van (úszás, futás), akkor két rekordot kapunk az ügyfélből, mivel az összekapcsolás alapján két rekord keletkezik.

Ezt egy group_by-al el tudom tüntetni ezt, de nem vagyok biztos, hogy ez a legjobb megoldás, mivel több millió ügyfél esetén nem biztos jó a group_by.
select u.*, h.*, group_concat (`h`.`hobbi_id`,’,’) from user AS `u` 
LEFT JOIN user_hobbik AS `h` ON `u`.`id`=`h`.`user_id` 
where `user_hobbik`.`hobbi_id` in (1,2,3) 
GROUP BY (`user`.`user_id`);
Nem lenne ettől jobb megoldás? A legszebb az lenne ha egy SET mezőt tudnék használni, de mivel a valóságban végtelen számú hobbi lehet, és az folyamatosan bővül, ezért ez nem megoldás.

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

Zoli
 
1

Fura, hogy két táblád van

Poetro · 2013. Már. 7. (Cs), 21.46
Fura, hogy két táblád van azonos névvel:
create table user_hobbik( 
user_id integer, 
hobbi_id varchar(100) 
); 

create table user_hobbik( 
user_id integer, 
hobbi_nev varchar(100) 
); 

akkor két rekordot kapunk az ügyfélből, mivel az összekapcsolás alapján két rekord keletkezik.

Mi a probléma ezzel? Miért baj, hogy több sor van azonos felhasználóval?
4

Elrontottam. Ez lett

world-s · 2013. Már. 7. (Cs), 23.55
Elrontottam.
Ez lett volna.

create table user_hobbik(
user_id integer,
hobbi_id integer
);


create table hobbik(
id integer,
hobbi_nev varchar(100)
);


És sajnos nem készülhetek folyamatos felfutásra, mert ezt nem magamnak csinálom, hanem cégnek. A tervezett, hogy 1 hónapon belül olyan 2000-4000 onlie useres lesz folyamatosan.

És ha már az elején lerohad a gép, akkor az egésznek annyi, mert hiába a reklámkampány, az lesz a vízhangja, hogy lehalt az oldal.
5

Szerverek

Poetro · 2013. Már. 8. (P), 00.09
Gondolom ekkora egyszerre online levő felhasználószámra azért beüzemeltek legalább fél tucat szervert. És akkor se gondlom, hogy folyton lekérdezni kellene, az adatbázis-szerverek is igen jól tudják cachelni az eredményeket, ha adsz nekik pár GB memóriát. Ezen kívül érdemes több slave adatbázis-szervert üzemeltetni a lekérdezések elosztása véget. Valamint mindenképpen érdemes az eredményeket az alkalmazás rétegben is cachelni, például memcached vagy Varnish használatával.
6

Ezekre készülünk, de nem

world-s · 2013. Már. 8. (P), 01.25
Ezekre készülünk, de nem mindent szerver oldalon és a rendszereken szeretnénk megoldani, hanem a megfelelő lekérdezésekkel is.

De addig is míg jobb ötlet nem jön, addig próbálkozok ezzel a group by-al. Próbálom a sorokat oszlopokra fordítani, ami sikerült is.

Most ez van:
SELECT *, GROUP_CONCAT(CASE WHEN `Attributum_id` = 'eyecolor' THEN `Attributum_value_id` ELSE NULL END ) AS `eyecolor` ,GROUP_CONCAT(CASE WHEN `Attributum_id` = 'sport' THEN `Attributum_value_id` ELSE NULL END ) AS `sport` FROM `kp2_view_profile` WHERE 1
GROUP BY
`Id`

Az `kp2_view_profile` az ügyfél tábla és a tulajdonság-összekapcsoló tábla összekapcsolásából kialakult view tábla....

próbáltam erre a részre kitalálni egy funkciót, mivel a 'eyecolor' rész csak a változó rész.de nem sikerült:

GROUP_CONCAT(CASE WHEN `Attributum_id` = 'eyecolor' THEN `Attributum_value_id` ELSE NULL END ) AS `eyecolor`

String-ként ezt a részt elő tudom állítani ha kell, de nem tudok vele mit kezdeni. Ha nem string-ként kezelem, akkor meg az SQL darabka nem tud megfutni a funkcióba.
2

Lesz egy nagy

Hidvégi Gábor · 2013. Már. 7. (Cs), 22.03
Lesz egy nagy terhelésű
Kívánom, hogy legyen, de most még nincs, előre pedig nem szabad sosem optimalizálni. Működjön, jöjjenek az ügyfelek, aztán, ha lassú lesz, lehet rajta gondolkodni, addig fölösleges.

Nem is biztos, hogy a MySQL ki tud szolgálni hatékonyan ennyi adatot.
3

Set mező?

Nagy Gusztáv · 2013. Már. 7. (Cs), 22.32
Bár tapasztalatom nincs vele, de én biztos kipróbálnám erre a Set megoldást. Feltéve, hogy a hobbik listája előre ismert, és nem dinamikusan változó.