1 (edited by skuelas 2012-12-31 19:00:37)

Topic: Masyvas, mysql ir pan...

:) Taigi dirbau dirbau kol is savo ideju susidare kamstis :)
Turiu lentele pavadinkim 'pirmas' kuriame as istraukiu id pagal koki tai kriteriju, rezultata implodinu (',',kintamasis) aisku jis yra masyvas tas kintamasis, rezultate gaunu id kruvele tarkim 1,2,3,4,5
Toliau turi lentele 'du'  is kurio irgi turiu istraukti id atitinkamus pasitelkes su anksciau istrauktais kitos lenteles id
tarkim select id where laukas IN (1,2,3,4,5)
viskas butu kaip ir gerai gaunu viska ka reikia, bet ne taip kaip noriu, nes ieskant lauka pagal '1' as gaunu ne viena rezultata, ieskant pagal '2' gaunu velgi ne viena rezultata. ir gaunasi taip kad kruva man nieko nesakanciu id, kazkaip man reikia pasidaryti kad istraukti pagal lauka 1 gauti atskirai grupe reiksmiu ir taip su visais kitais
tarkim laukas in 1 -> gaunu id 5,8,9 ir t.t. masyve
vel atskiras masyvas laukas in 2 -> gaunu 1,2,3 masyvas
Nezinau ar supratot jei ka bandysiu vel kitaip paaiskint, nesugalvoju kaip padaryti uzveskit ant kelio :)

var_dump(0 == 'tekstas'); // TRUE. ar zinai kodel? :)

Re: Masyvas, mysql ir pan...

Ne viską atidžiai skaičiau, nes kaip ir "šventinis vakaras", bet galiu trumpai pasakyt kame problemos:
1) nelaikyk celėse tokių masyvų, pagal kuriuos turi paskui dar kažką ištraukinėti, laikyk duomenis kaip priklauso, papildomuose lentelėse ar dar kaip, kad galėsum JOIN'inti;
2) stenkis niekada nenaudoti IN() operatoriaus;

Laikydamasis šių dviejų patarimų stipriai palengvinsi savo gyvenimą.

Re: Masyvas, mysql ir pan...

tarkim yra lentele masinos dideles mazos ir pan (id, dydis)
kita yra lentele masinos marke -> joje yra id, markiu pavadinimai, dydis_id
kita lentele saugoma tarkim id, markes_id,dydis_id, spalvos tu markiu masinu
tarkim reikia rasti bmw ir opel markes ir ju spalvas, bet atskirai
tai is pirmos lenteles paimu abieju markiu id
is antros isgaunu ju spalvas bet problema ya kad viskas kruvoje o norint toliau dirbti reik gauti atskirai kazkaip kad bmw spalvos, ir atskirai opel spalvos. o paskui jau gali daryti su jom ka nori.

var_dump(0 == 'tekstas'); // TRUE. ar zinai kodel? :)

Re: Masyvas, mysql ir pan...

issisprendiau po ilgu papildomu pamastymu, jau buvau issigandes kad teks gristi atgal truputi ir perrasyt skirpta ir koki viena kita lentele pakeist ar pridet :)

var_dump(0 == 'tekstas'); // TRUE. ar zinai kodel? :)

Re: Masyvas, mysql ir pan...

Sakot IN() operatoriaus nenaudot?
Pas mane dabar vienoje lenteleje
playlist:
id - user_id - songs
1 - 1 - ,1494,95040,585,61
dainos:
id - name
14694 - test
61 - test1

tai as su IN(14694,61,...) isrenku.
Ar kiekvienai playlist dainai kurt nauja irasa playlist lenteleje? ir atrenkant JOIN'int?

Kuom tas IN() blogas?

Re: Masyvas, mysql ir pan...

Tai tavo duomenų struktūra neatitinka normalinių formų.

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: Masyvas, mysql ir pan...

galima placiau kas tos normalines formos?

var_dump(0 == 'tekstas'); // TRUE. ar zinai kodel? :)

Re: Masyvas, mysql ir pan...

http://pixel.lt/duomenu-baziu-normalines-formos.html
Ir pats dabar gaminsiu pagal tai.

Re: Masyvas, mysql ir pan...

Nelabai aš čia gaudausi, bet badanu.
Parodysiu pavyzdi kaip pasigaminau. čia:
http://s13.postimage.org/xvbt3zv93/Untitled_2.png
Pagal `favorites` , atrenku dainas, `favorite_owner` gali but tiek ip adresas tiek  tam tikras vartotojo id.
Po to pagal `playlistsongs` , na taip pat kaip `favorites`.

Ar bent kažką pataikau?

Ir kaip reikėtu padoriai ištraukt `favorites` dainas iš `songs`

SELECT * FROM `favorites` , `songs` WHERE favorites.favorite_owner = '78.63.35.138' AND favorites.song_id = songs.song_id

Ne?

Gal labiau išmanantis patarts man? :]

Re: Masyvas, mysql ir pan...

Nepasakysiu konkretaus problemos sprendimo bet keletas minciu:

1. Atsakant i pati pirma klausima - gal multidimensinis masyvas butu sprendimas?
2. Atsakant i Avice pirma klausima - nelaikyk keletos reiksmiu viename laukelyje (pvz per kableli). Kiekvienai reiksmei - atskiras laukelis. Tai yra duomenu bazes principas ir esme. O lipdysi viska kai jau istrauksi duomenis ir kokiame php gali juos vartyti kaip nori.

Re: Masyvas, mysql ir pan...

SELECT
     songs.*,
     favorites.*
FROM
      favorites
INNER JOIN songs ON favorites.song_id = songs.song_id
WHERE
      favorites.favorite_owner = '78.63.35.138'

šito reikėjo?

Re: Masyvas, mysql ir pan...

Aham nemažai jau bandau.

SELECT *
FROM songs s
  LEFT JOIN (SELECT * FROM favorites WHERE favorite_owner='78.63.35.138' or favorite_owner='1') f ON (s.song_id = f.song_id)
  LEFT JOIN (SELECT * FROM votes WHERE vote_ip='78.63.35.138') v ON (s.song_id = v.song_id)
WHERE 1
ORDER BY `song_plus` DESC, `song_minus` ASC
LIMIT 100 OFFSET 0

Pasirašiau tokia užklausa veikt , tai veikia , bet užklausos laikas sieka apie 2~3 sec.
Noriu , kad parinktu 100 eilučių kuriuose didžiausias `song_plus` ir maziausias `song_minus` , bei prie to pačio prijungt dvi lenteles kuriuose saugoma informacija , abi lentelės kaip aukščiau pateiktame paveikslėlije `favorites` lentelė.

Re: Masyvas, mysql ir pan...

Del leto uzkrovimo laiko, perziurek indeksus. Ar sudeti ant tu stulpeliu kurie naudojami WHERE uzklausose.

Re: Masyvas, mysql ir pan...

Na sudėti , bet užklausą visvien krauna ~3 sec.

Re: Masyvas, mysql ir pan...

Nebus kas po vieną indeksą sudėjai ant kiekvieno stulpelio?

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: Masyvas, mysql ir pan...

Parodyk pilną duomenų schemą, kur matosi visi stulpeliai, tipai ir indeksai.

Nesimato pas tave nei 'song_plus', nei 'song_minus', nei indeksų nei tipų.

Spėjų, kad tau reikia pirma iš song_plus atimti song_minus ir pagal gautą rezultatą kažką skaičiuoti.

Kitas dalykas, kad jeigu duomenų yra nemažai, tai tokių dalykų dinamiškai niekas neskaičiuoja, pasigamina papildomus stulpelius, ir keičiantis pirminių stulpelių reikšmėms atnaujiną ir rezultatus. Tada ir užklausos greitai veikia (-;

(aišku, čia jau būtų vykdoma de-normalizacija, bet šiuo atveju ji reikalinga, negu ta, apie kurią buvo kalbama pirmose žinutėse, kur celėje buvo saugomas masyvas)

17 (edited by Avice 2013-01-09 16:37:02)

Re: Masyvas, mysql ir pan...

songs lentelė

CREATE TABLE IF NOT EXISTS `songs` (
  `song_id` int(11) NOT NULL AUTO_INCREMENT,
  `song_name` tinytext NOT NULL,
  `song_file` int(8) NOT NULL,
  `song_server` tinyint(2) NOT NULL,
  `song_plus` int(11) NOT NULL,
  `song_minus` int(11) NOT NULL,
  PRIMARY KEY (`song_id`)
) ENGINE=MyISAM;

votes lentelė:

CREATE TABLE IF NOT EXISTS `votes` (
  `vote_id` int(11) NOT NULL AUTO_INCREMENT,
  `song_id` int(11) NOT NULL,
  `vote_ip` tinytext NOT NULL,
  PRIMARY KEY (`vote_id`),
  KEY `song_id` (`song_id`)
) ENGINE=MyISAM;

favorites lentelė:

CREATE TABLE IF NOT EXISTS `favorites` (
  `favorite_id` int(11) NOT NULL AUTO_INCREMENT,
  `song_id` int(11) NOT NULL,
  `favorite_owner` tinytext NOT NULL,
  PRIMARY KEY (`favorite_id`),
  KEY `song_id` (`song_id`)
) ENGINE=MyISAM;

Nieko atimt nereikia iš plus ar minus ;]
Tiesiog nesiseka apjungt šių lentelių.

Bandau atrink 100 eilučių iš `songs` lentelės prijungdamas `votes` ir `favorites` lenteles , iš `votes` ir `favorites` atrinkti tik kur (favorite_owner yra (tarkim 1 arba 127.0.0.1) ir song_id su songs.song_id) ir (vote_ip yra (tarkim 127.0.0.1) ir song_id su songs.song_id).
Su gautom eilutem puslapije tikrinu ar svecias yra jau balsaves už ta įraša iš songs lentelės ir ar ji idėta į jo `favorites` sarašą, jei balsuota prie songs įrašo puslapije pridedu koki nors ikoną ar panašiai taip pat ir su `favorites`.


Visa tai bandau žemiau t.y paraše pateiktame puslapije.

Re: Masyvas, mysql ir pan...

Na trumpai tokios pastabos:
a) pas tave dauguma parinktų tipų yra pertekliniai:
  a1) tie patys INT yra labai dideli, reikia naudoti maženius ir ... tavo atveju, daugumoje vietų, UNSIGNED (plačiau apie INT tipus: http://dev.mysql.com/doc/refman/5.0/en/ … types.html );
  a2) IP saugok irgi INT(UNSIGNED) (pasižiūrėk INET_ATON ir INET_NTOA funkcijas;
b) mysql'as naudodamas lentelę jai konkrečioje užklausoje panaudoja tik vieną indeksą (pagal optimizatoirų išrenka, kuris indeksas jam atrodo patraukliausias);
c) tavo atveju, daugumoje vietų, turi būti kombinuoti indeksai, kurie būtų naudojami užklausoje prijungiant lentelę (jeigu jų nepajama automatiškai reikia HINT'inti (arba FORCE'inti));
d) skaičius prie INT (tipo.. "INT(4)" dažnai naudojamas nesuprantant, ką jis reiškia, bandant atspėti (iš kitų programavimo kalbų), kad tas skaičius nurodo kiek skaitmenų gali turėti kintamasis (šiuo atveju stulpelis);

Re: Masyvas, mysql ir pan...

o kas blogai su tuo int 11? ka jis reiskia nesuprantu, ka tas unsigned duoda?

var_dump(0 == 'tekstas'); // TRUE. ar zinai kodel? :)

Re: Masyvas, mysql ir pan...

šiuo atveju nieko blogo, nes čia defaultinis atvaizdavimas. Bet kartu tai ir mažiausiai tau rūpėti turintis klausimas (-; UNSIGNED daug svarbiau, pabandyk atsidaryt mano pateiktą vienintelę nuorodą.