[ Milos911 @ 20.08.2011. 16:27 ] @
Ovako. Jedan korisnik moze da kreira projekat, sa mnogo podataka u njemu. Ja radim pretragu na osnovu grada, pokrajine (?) i drzave - city, state, country. Bazu sam napravio na sledeci nacin:
Code:

CREATE TABLE IF NOT EXISTS `projects` (
  `pid` int(15) NOT NULL AUTO_INCREMENT,
  `uid` int(15) NOT NULL,
  `project_category` varchar(200) NOT NULL,
  `project_subcategory` varchar(200) NOT NULL,
  `project_name` varchar(200) NOT NULL,
  `pickup_country` varchar(200) NOT NULL,
  `pickup_state` varchar(200) NOT NULL,
  `pickup_city` varchar(200) NOT NULL,
  blablablablabl
   PRIMARY KEY (`pid`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

Code:

CREATE TABLE IF NOT EXISTS `projects_matching` (
  `pid` int(15) NOT NULL,
  `city` varchar(200) NOT NULL,
  `state` varchar(200) NOT NULL,
  `country` varchar(200) NOT NULL,
  `type` varchar(200) NOT NULL,
  `expires` varchar(200) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Tabela projects ima 28 kolona.
Upit su na fazon:
Code:

SELECT * FROM projects_matching LEFT JOIN projects ON projects_matching.pid = projects.pid WHERE projects_matching.state ='Arizona' ORDER BY projects_matching.expires DESC

pretragu uvek radim sa = , nikad sa like.

Racunao sam da je najbolje da sve podatke koji se ne menjaju (cesto ili nikad), stavim u ovu prvu tabelu, i da njoj nikad ne pristupam direktno, vec da sve pretrage radim na osnovu druge. Eventualno ako dodje do potrebe da pomenim nesto u prvoj, uradicu to tako sto cu jos pristupati preko pid-a. Da li je ovo dobro resenje?

Druga stvar, posto imam i pickup_state i delivery_state, da ne komplikujem upisujem i jedno i drugo u project matching, a u type upisem 1 ili 2 (ako nekad budem trebao da radim pretragu u kojoj ce biti bitno da li je state pickup ili delivery).
E sad, problem je taj sto ako korisnik izabere isto za pickup i delivery state, ja cu dobiti dva rezultata sa istim pid-om, sto mi naravno ne odgovara.
Znam da treba da koristim distinct da bih dobio samo jedan rezultat, ali ne znam kako?

Imam i drugu opciju, a to je da prilikom upisa podataka uradim proveru
if(pickup_state == delivery_state){delivery_state='whatever123'}
ali onda dolazim do istog problema jer upit nekad nece imati where pa cu opet morati da koristim distinct.
Tako da, sta da radim?

I da li mi je ok pocetna ideja za bazu? Pravio sam i posebne tabele u koje sam upisivao samo pid i uid(user_id), da na osnovu njih nalazim sve projekte od jednog korisnika i da ne koristim ovu tabelu i za to. Znam da je to dupliranje podataka, ali racunam da mi je vrednije da sve radi brzo neko da imam vise prostora na disku...

To je to za sad, nadam se da sam sve dobro objasnio.
[ bogdan.kecman @ 20.08.2011. 18:39 ] @
Citat:
Milos911
I da li mi je ok pocetna ideja za bazu?


yok. Moras to da normalizujes.

Citat:
Milos911:
ali racunam da mi je vrednije da sve radi brzo neko da imam vise prostora na disku...


nije to bas tako jednostavno. Ako zauzima vise mesta, trazi vise memorije da se kesira, vise mesta u indexu, vise ... tako da "radi brzo" u ovom tvom slucaju ne deluje kao tacan zakljucak

[ Milos911 @ 20.08.2011. 18:56 ] @
E jbg :)
Jesam li bar dobro smislio ovu pretragu, ili i to da menjam? I posto mi malo gori pod nogama, mozes li da mi kazes kako da napisem upit koji ce uraditi isto kao i ovaj:
SELECT * FROM projects_matching LEFT JOIN projects ON projects_matching.pid = projects.pid WHERE projects_matching.state ='Arizona' ORDER BY projects_matching.expires DESC
samo preskociti isti pid kad (ako)naleti na njega? To da sredim za sad, pa cu normalizaciju kasnije.

Mada mi nije bas jasno, posto se ceo red i tako i tako ucitava, svaki put(x20 redova), zar nije brze ucitati jedan red nego raditi join 5-6 tabela? Ok kad bi se nesto menjalo i tim redovima, ili kad bih pretragu zasnivao na njima, ali valjda bi trebalo da bude bas brzo ucitati to odma' preko pid-a?

edit: Uspeo da napisem upit:) :
"SELECT DISTINCT projects_matching.pid, projects . *
FROM projects_matching
LEFT JOIN projects ON projects_matching.pid = projects.pid"
verovatno zesce nepravilno ali za sada ga neka ovako, dok ne zavrsim normalizaciju.

[Ovu poruku je menjao Milos911 dana 20.08.2011. u 20:44 GMT+1]
[ bogdan.kecman @ 20.08.2011. 23:46 ] @
Citat:
Milos911: E jbg :)
Jesam li bar dobro smislio ovu pretragu, ili i to da menjam?


to zavisi od modela baze. Generalno - baza ti je nenormalizovana. Treba da je normalizujes -> dakle pocni sa tim da u projects tabeli samo project_name treba da bude varchar dok sve ostalo treba da bude int, dok u projects_matching nista ne treba da bude varchar.

Citat:
Milos911:
zar nije brze ucitati jedan red nego raditi join 5-6 tabela?


normalizacija db modela se ne radi radi brzine vec zbog nekih drugih stvari (vecina objasnjena u mom tekstu o normalizaciji
[ Milos911 @ 21.11.2011. 20:47 ] @
Zavrsavao sam nesto drugo, pa sam se vratio na ovo. Pa da pitam da li mi je ovaj deo ok? :)
Stara tabela:
Code:
CREATE TABLE `projects_matching` (
  `pid` int(15) NOT NULL,
  `city` varchar(200) NOT NULL,
  `state` varchar(200) NOT NULL,
  `country` varchar(200) NOT NULL,
  `type` varchar(200) NOT NULL,
  `expires` varchar(200) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Nove tabele:
Code:

CREATE TABLE `static_cities` (
  `city_id` int(15) NOT NULL AUTO_INCREMENT,
  `city_name` varchar(200) NOT NULL,
  PRIMARY KEY (`city_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;


CREATE TABLE `static_countries` (
  `country_id` int(15) NOT NULL AUTO_INCREMENT,
  `country_name` varchar(200) NOT NULL,
  PRIMARY KEY (`country_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;


CREATE TABLE `static_states` (
  `state_id` int(15) NOT NULL AUTO_INCREMENT,
  `state_name` varchar(200) NOT NULL,
  PRIMARY KEY (`state_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;


CREATE TABLE `tmp_project_matching` (
  `pid` int(15) NOT NULL,
  `city_id` int(15) NOT NULL,
  `state_id` int(15) NOT NULL,
  `country_id` int(15) NOT NULL,
  `expires` int(15) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Sad pre pretrage, ukoliko vec nemam, pokupim id iz static tabela, pa na osnovu njega radim pretragu u tmp_project_matching? Ima li neki bolji pristup od ovog?