DevProTalk

DevProTalk (http://www.devprotalk.com/index.php)
-   PHP (http://www.devprotalk.com/forumdisplay.php?f=9)
-   -   Normalizovana baza podataka (http://www.devprotalk.com/showthread.php?t=10386)

slavkan 23. 09. 2011. 23:49

Normalizovana baza podataka
 
Postovanje. Vezban na jednoj normalizovanoj bazi podatka i dolazim do dela gde treba da upisem podatke u 2 tabele istovremeno. Da pojasnim, radi se kao o jednoj prodavnici racunara i imam administratora koji treba da unese proizvode i da ih razvrsta po kategorijama koji oni pripadaju pa tako imam tabelu kategorije (koja je vec puna), zatim imam tabelu proizovdi i imam tabelu kategorija_proizvodi koja se dobije zbog veze vise:vise. Administrator dakle ima formu gde unosi naziv proizvoda, birakategoriju kojoj pripada i unosi broj proizvoda. E imam problem sa ovim id-ovima koji su mi u tabelama auto_increment. E kad insertujem recimo u tabelu proizvod - insertujem naizv i stanje a id mi se ubaci samo od strane sistema za upravljanja bazama e kako sad taj isti id da insertujem i u tabelu kategorija_proizvod kad taj id nigde ne cuvam ne postoji u nekoj promenljivoj. Da li sad ovde nije pozeljno koristiti ovaj autoincrement ili praviti neku promenljivu gde cu cuvati id proizvoda ili pak nesto trece. Voleo bih kad bi neko iskusniji dao neki savet oko ovoga. Evo postavicu tabele da bude jasnije:


Tabela kategorija
Kôd:

CREATE TABLE IF NOT EXISTS `kategorija` (
  `idKategorija` int(11) NOT NULL AUTO_INCREMENT,
  `naziv_kategorije` varchar(45) NOT NULL,
  PRIMARY KEY (`idKategorija`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ;

--
-- Dumping data for table `kategorija`
--

INSERT INTO `kategorija` (`idKategorija`, `naziv_kategorije`) VALUES
(1, 'Procesor'),
(2, 'Mticna ploca'),
(3, 'Monitor'),
(4, 'Hard disk'),
(5, 'RAM'),
(6, 'Graficka karta'),
(7, 'Napajanje'),
(8, 'Tastatura'),
(9, 'Mis'),
(10, 'Opticki uredjaj');

Tabela proizvodi
Kôd:

--
-- Table structure for table `proizvod`
--

CREATE TABLE IF NOT EXISTS `proizvod` (
  `idProizvod` int(11) NOT NULL AUTO_INCREMENT,
  `naziv_proizvoda` varchar(45) DEFAULT NULL,
  `stanje` int(3) NOT NULL,
  PRIMARY KEY (`idProizvod`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `proizvod`
--

Tabela kategorija_proizvod gde imam spoljne kljuceve iz tabele proizvod i tabele kategorije
Kôd:

CREATE TABLE IF NOT EXISTS `kategorija_proizvod` (
  `Kategorija_idKategorija` int(11) NOT NULL,
  `Proizvod_idProizvod` int(11) NOT NULL,
  PRIMARY KEY (`Kategorija_idKategorija`,`Proizvod_idProizvod`),
  KEY `fk_Kategorija_has_Proizvod_Kategorija1` (`Kategorija_idKategorija`),
  KEY `fk_Kategorija_has_Proizvod_Proizvod1` (`Proizvod_idProizvod`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `kategorija_proizvod`
--


--
-- Constraints for dumped tables
--

--
-- Constraints for table `kategorija_proizvod`
--
ALTER TABLE `kategorija_proizvod`
  ADD CONSTRAINT `fk_Kategorija_has_Proizvod_Kategorija1` FOREIGN KEY (`Kategorija_idKategorija`) REFERENCES `kategorija` (`idKategorija`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  ADD CONSTRAINT `fk_Kategorija_has_Proizvod_Proizvod1` FOREIGN KEY (`Proizvod_idProizvod`) REFERENCES `proizvod` (`idProizvod`) ON DELETE NO ACTION ON UPDATE NO ACTION;


webarto 24. 09. 2011. 00:49

MySQL:
PHP kôd:

last_insert_id() 

PHP kôd:

SELECT LAST_INSERT_ID() AS id 

PHP:

PHP kôd:

mysql_insert_id() 

PHP kôd:

$id mysql_insert_id(); 

....

PHP kôd:

$query "INSERT INTO proizvodi(naziv_proizvoda,stanje) VALUES('kompujtor', 5)";
$result mysql_query($query);

$id mysql_insert_id();

$query "INSERT INTO proizvodi_kategorije(Kategorija_idKategorija,Proizvod_idProizvod) VALUES(1, $id)";
$result mysql_query($query); 


slavkan 24. 09. 2011. 00:56

WOW :D

Tenk ju maestro ;)

Jasno ko dan ! Dobro samo sto cu ja morati da u kategorija_proizvod upisem jos i idKategorija iz tabele kategorija al sad je to prava poslastica :)

webarto 24. 09. 2011. 01:26

Napisao si istovremeno, a to nije moguće, moguće je samo multiple query u MySQLi extenziji ali to nije pametno koristiti.
PHP kôd:

$query "INSERT INTO proizvodi(naziv_proizvoda,stanje) VALUES('kompujtor', 5);
INSERT INTO proizvodi_kategorije(Kategorija_idKategorija,Proizvod_idProizvod) VALUES(1, (SELECT LAST_INSERT_ID()));"
;

mysqli_multi_query($link $query); 

A kako dođeš do ovog Kategorija_idKategorija, pretpostavljam iz $_POST, ako ga vučeš iz baze možeš u istom query-u...

slavkan 24. 09. 2011. 01:43

Mozda sam se pogresno izrazio ali treba da upisem podatke i u jednu i u drugu tabelu, ali logicno je da prvo upisem proizvode (id naziv i stanje) u tabelu proizvodi pa onda da upisem (Kategorija_idKategorija,Proizvod_idProizvod) u tabelu kategorija_proizvod. Kategorije su prethodno upisane.

A kako doci do Kategorija_idKategorija, pa da sa $_POST kako bih mogao drugacije? Da li mozda postoji neko bolje i prakticnije resenje od ovoga? Dakle ja uglavnom moram da omogucim administratoru da on moze da dodaje proizvode u tabelu proizvodi i da ih rasporedjuje po kategorijama, a to ce da uzrokuje da moram da popunjavam i tabelu kategorija_proizvodi sa id-ovima od proizvoda i kategorija jer je to valjda sustina normalizacije, da izbegnem dupliranje podataka itd.

Jos jedno pitanje, zasto nije pametno koristi mysqli ? Da li ta funkcija bukvalno omogucava istovremeni upis u obe tabele? Meni to i ne treba, zar ne?

webarto 24. 09. 2011. 02:06

Ne treba ti, ako ti treba, ne radiš dobro :)
MySQLi (improved) je ekstenzija a to je samo jedna od njenih funkcija (http://php.net/manual/en/book.mysqli.php)...
Pa ne, preko POST naravno, a kako si napisao učinilo mi se kao da je neki problem :)

Jeste to normalizacija, upravo sam radio za djevojku neku Access bazu (pohađa napredni kurs za Office)...



Uglavnom, predavač je rekao da ne mora da ima ovoliko tabela i da to može sve u jednu tabelu jer je lakše, takođe može staviti PRIMARY na VIN (koji je sastoji od slova i brojeva), talking about normalization :)

slavkan 24. 09. 2011. 02:15

Ma da , necu ulaziti sad u taj mysqli :D Pokusacu sutra ovo da insertujem pa se javljam, nebi trebalo biti problema.

E gledam ovaj Access :D Jel se moze ovo danas negde iskoristiti ?

ivanhoe 24. 09. 2011. 03:49

Nema razloga da ne koristis mysqli, to je samo drugaciji (noviji) drajver za mysql bazu, koji omogucava neke bitne stvari, recimo prepare statements i da se logujes u bazu sa novim sistemom cuvanja sifri koji je sigurniji. Ali jos bolje je da umesto mysqli odmah preskocis i naucis PDO, to je isto drajver, ali ne samo za mysql, vec podrzava razne baze.

Sto se tice multi-query postoje neke sigurnosne implikacije sa tom f-jom, pa se zato ne preporucuje, a sem toga to nije ono sto tebi treba.

Bitno je da razumes kako se SQL izvrsava: php posalje svom drajveru SQL string koji si zadao, on to prosledi bazi, baza kompajlira SQL string u komandu i onda je izvrsi. Kad imas vise komandi njih moras da izvrsis sekvencijalno, jednu po jednu, i svaka ce proci kroz sve ove korake. Ono sto multiquery pomaze je sto mozes u jednom pozivu bazi da posaljes vise komandi, pa stedis na konekcijama ka bazi, koje su inace najsporiji deo operacije. Ali posle toga se sve odvija isto, tj. i dalje se izvrsava jedna po jedna komanda

Druga stvar koju treba da razumes je pojam atomske operacije u bazi. To je operacija koju mozes da zamislis da se obavlja u jednom koraku, tj. ona ili ne uspe, ili se izvrsi onako kako je zadano, druge operacije koje se izvrsavaju u bazi ne mogu da uticu na njen rezultat. U mysql-u je svaka pojedina komanda atomska, znaci ako kazes UPDATE tabela SET a=5, b=6; ti znas da ce na svakom redu u tabeli a i b biti toliko, ne moze da se promeni samo a ili samo na par redova.

Medjutim kad imas vise komandi onda to ije atomska operacija, znaci bilo kakve izmene u bazi koje neko drugi radi mogu da ti uniste relacije (veze id-jeva koje imas, sto se jednim imenom zove referencijalni integritet baze). Da se to ne bi desilo koriste se transakcije, a posto koristis InnoDB engine ja bih ti preporucio da sve te svoje operacije zatvoris izmedju START TRANSACTION i COMMIT komandi. Vise o tome mozes da procitas ovde:
http://dev.mysql.com/doc/refman/5.0/en/commit.html

slavkan 24. 09. 2011. 14:43

Hvala na korisnim informacijama. Iskren da budem iako sam transakcije malo proucavao na faxu i kao rauzmeo tad nesto sad nebih znao primeniti niti jednu na ovaj moj problem iako sam pogledao ovaj link. Znam da je to kao jedan od nasigurnijih nacina upravljanja bazama podataka i da se koristi recimo u bankama.

Sto se tice ovog mog problema meni ne treba sad nesto toliko efikasno resenje, mada sto ti rece treba ovo sve preskociti i baviti se ovim efikasnijim nacinima upravljanja bazama al eto treba nauciti i ove skolske primere pa onda preci na ono sto se u praksi primenjuje. Ako imas jos negde konkretnih primera primena transakcija na neke upise postavi, mozda kad ovo zavrsim bas krenem da se bavim time.

Sto se tice ovih mojih upita imao bih jos jedno pitanje. Posto meni treba da upisem podatke prvo u jednu pa u drugu tabelu, ne istovremeno :D , da li ovaj primer sto je webarto naveo moze da se primeni u mom slucaju:


Kôd:

$query = "INSERT INTO proizvodi(naziv_proizvoda,stanje) VALUES('kompujtor', 5);
INSERT INTO proizvodi_kategorije(Kategorija_idKategorija,Proizvod_idProizvod) VALUES(1, (SELECT LAST_INSERT_ID()));";

mysqli_multi_query($link , $query);

Dakle da smestim 2 inserta u jedan $query i ako je to moguce da li je sintaksa ista kao i ovde. Ali pitanje je, sve da je to moguce, da li tako mogu da dodjem do ovog mog idProizvoda sto mi treba jer njega treba iscupati posle prvog inserta pa onda odraditi drugi insert. Ipak nema logike, jel tako? To kad bi moglo dobro bi bilo za neke druge upite gde su svi podaci koji se upisuju u tabele odmah, da kazem "poznati" .

webarto 24. 09. 2011. 14:50

Uradi kako sam ti prvo napisao, znači uzmi ID u $id varijablu, možeš i ovo drugo ali je nepotrebno komplikovanje, ništa ne dobijaš osim veće šanse za greške. Htio sam ti samo reći da ne možeš 2 INSERTa u 2 tabele uraditi u jednom queryu, u svakom slučaju su 2 querya. Ovaj drugi primjer bi trebao isto da radi.

U drugom INSERTu ima SELECT koji kupi zadnji ID odosno taj idProizvod...

PHP kôd:

(SELECT LAST_INSERT_ID()) 


slavkan 24. 09. 2011. 15:18

U redu

slavkan 24. 09. 2011. 17:15

E ja sam kralj najveci na svetu :D Ne mogu da uhvatim idKategorija iako sam mislio da cu to znati da uradim. Malo me zbunila ova moja select lista ali moram na ovja nacin administratoru da omogucim da izabere kategoriju gde ce smestiti proizvod. Evo kako sam to uradio:

Kôd:

$kategorija= "SELECT * FROM kategorija ORDER BY idKategorija DESC";
                                $rezultat=mysql_query($kategorija);

                                echo '<form id="myform" name="myform" method="post">
                                       
                                        <div class="form_row">
                                        <label></label>
                                        <ul id="options">
                                                        <li><label>Naziv Proizvoda:</label><input type="text" size="20" name="naziv"/></li>                                               
                                                                <li><label>Kategorija:</label>
                                                                <select name="kategorija">';
                                                               
                                                                while($red=mysql_fetch_assoc($rezultat))
                                                        {
                                                                        echo '<option value="'.$red['naziv_kategorije'].'" selected>';?> <?php echo $red['naziv_kategorije'];?> <?php echo '</option>';
                                                        }
                                                        echo'</select></li>
                                                <li><label>Stanje:</label><input type="text" size="3" name="brojkomada"/></li>
                                        </ul> </p>
                                       
                                        <input type="submit" value="Unesi!" name="submit"/>
                                        <input type="reset" name="reset" value="Resetovanje">
                                        </div>
                                        </form>';

E sad ja sam povukao sve iz tabele kategorije i idKategorija mi se nalazi u
Kôd:

$red['idKategorija']
ali kako da ja uzmem bas onaj
Kôd:

$red['idKategorija']
koji odgovara mom
Kôd:

$red['naziv_kategorija']
Valjda me razumete. Inace testirao sam mysql_insert_id() i to mi uspesno radi.

Br@nkoR 24. 09. 2011. 18:07

Nisam siguran da li sam dobro razumeo problem. Možeš da id uneseš u value atribut option html taga, dakle:
Kôd:

echo '<option value="' . $red['idKategorija'] . '">' . $red['naziv_kategorije'] . '</option>';
I onda na stranici gde obrađuješ formu:
Kôd:

$idKategorija = $_POST['kategorija'];

slavkan 24. 09. 2011. 19:43

Da da da moze to sigurno al nije mi palo na pamet. Videces da se webarto da potvrdi to :D

slavkan 24. 09. 2011. 20:28

Konacno sam uspeo. Evo kako sam postavio upite pa vi recite jel moze proci:

Kôd:

if (isset($_POST['submit']))
{
        $error='';
                                               
        //Provera da li je korisnik popunio polja
        if (!$_POST['naziv'] | !$_POST['kategorija'] | !$_POST['brojkomada'])
        {
                $error .= '<li>Niste popunili sva polja</li>';
        }
                                       
        if($error=='')
        {
                //Hvatanje promjenljivih
                                                                  $nazivproizvoda=mysql_real_escape_string($_POST['naziv']);
$kategorija=$_POST['kategorija'];                                                        $brojkomada=mysql_real_escape_string($_POST['brojkomada']);
                                                               
                $proizvodi = "INSERT INTO proizvod (naziv_proizvoda, stanje)
                VALUES ('".$nazivproizvoda."','".$brojkomada."')";
                                               
                if($dodajproizvod)
                {
                        echo'<h2>Nesto je krenulo po zlu sa tabelom proizvod</h2></p>';
                                               
                        //Uhvacen zadnji unesen id u auto_increment kolonu kao i idKategorije
                        $idProizvod = mysql_insert_id();
                        $idKategorija = $_POST['kategorija'];
                                                                               
                }
                                                               
                                                       
                //upisujemo spoljne kljuceve u tabelu kateogrija_proizvod
                                                               
$kategorijaproizvod = "INSERT INTO kategorija_proizvod (Kategorija_idKategorija,Proizvod_idProizvod) VALUES ('".$idKategorija."','".$idProizvod."')";
                                                                                                       
                $dodajkategorijaproizvod = mysql_query($kategorijaproizvod);
                if($dodajkategorijaproizvod)
                {
                        echo'<h2>Uspesno ste dodali proizvod</h2></p>';
                                               
                }
        }
                else
                {
echo '<li><font color=red>Javile su se sledeće greške:</font></li><br> <ul></ul> <p>'; echo  $error;
                }
                                       
}


webarto 24. 09. 2011. 22:52

Haha, kralj si. Potvrđujem Brankovo ;)

slavkan 24. 09. 2011. 23:47

Citat:

Originalno napisao webarto (Napišite 101734)
Haha, kralj si. Potvrđujem Brankovo ;)

Jesi ti skrt na recima, a sto ne prokomentarises ove upite :P Salim se, bitno je da sljaka :D

slavkan 25. 09. 2011. 15:30

Valjalo bi malo jos sa ovim experimentisati. Kad sam uneo fino proizvode, kategorije, odredio koji proizvodi pripadaju kojoj kategoriji sad bi trebao da ponudim korisnicima da izaberu konfiguraciju koju cu da smestam u jednu tabeli koja ce mi se zvati narudzbe. Ajde da ostavim smestanje za kasnije. Mene interesuje kako sad iz ove sume ponuditi korisniku listu svih proizvoda koje imam da on odabere za iz svake kategorije po jedan. Recimo imacu formu na kojoj cu da prikazem sledece:

Procesor:
Maticna ploca:
RAM:

Da li je mozda najzgodnije da koristim select liste kao sto sam radio za smestanje proizvoda u odredjenu kategoriju, nekako skoro svi takvi sistemi rade na tom principu. Ali kako iscupati podatke iz ove 3 tabele kategorije, proizvodi i kategorija_proizvod?!?Neki predlog?

cvele 26. 09. 2011. 08:28

Malko naprednije: http://code.google.com/p/tungsten-re...icatorCookbook

Ukoliko ti je ovo gore "preobimno" od verzije 5.1 trigger-i rade odlicno, nema razloga da ih ne koristis.

slavkan 26. 09. 2011. 11:33

Ih kad bih ja znao primeniti na ovo moje. Znam da se ovo moze uraditi sa JOIN ali nisam nikad ovako nista za mene "komplikovano" radio pa bi trebao neko da me uputi. Mozda bi ja nekako i znao iscupati podatke ali nebih znao kako da ih organizujem u ove select liste.To je problem

nn.nn 26. 09. 2011. 18:50

^ Možda ti ovo može pomoći: besplatan db kurs Introduction to Databases (Stanford University)

slavkan 27. 09. 2011. 17:04

hhehe nn.nn :D pa nije na odmet. Resio sam problem ali se odmah javio i drugi :D


Vreme je GMT +2. Trenutno vreme je 01:25.

Powered by vBulletin® Verzija 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Copyright © DevProTalk. All Rights Reserved.

Mišljenja, saveti, izjave, ponude ili druge informacije ili sadržaji nastali na Sajtu su vlasništvo onoga ko ih je kreirao, a ne DevProTalk.com, tako da ne morate da se oslanjate na njih.
Autori poruka su jedini odgovorni za ovakve sadržaje. DevProTalk.com ne garantuje tačnost, kompletnost ili upotrebnu vrednost informacija, stavova, saveta ili datih izjava. Ne postoje uslovi pod kojima bi mi bili odgovorni za štetu ili gubitak koji je posledica bilo čijeg oslanjanja na nepouzdane informacije, ili bilo kakve informacije nastale kroz komunikaciju između registrovanih članova.
Web sajt može sadržavati linkove na druge web sajtove na Internetu ili neke druge sadržaje. Ne kontrolišemo niti podržavamo te druge web sajtove, niti smo pregledali bilo kakve sadržaje na takvim sajtovima. Mi nećemo biti odgovorni za legalnost, tačnost ili prikladnost bilo kog sadržaja, oglasa, proizvoda, usluga ili informacije lociranim na ili distribuiranih kroz druge web sajtove, niti za bilo kakvu štetu nastalu kao posledica takvih informacija. DevProTalk.com drži i čuva druga prava vlasništva na web sajtu. Web sajt sadrže materijale zaštićene copyright-om, zaštitne znakove i druge informacije o pravu vlasništva ili softver. Članovi mogu poslatu informacije zaštićene pravima vlasništva njihovih nosilaca i ona ostaju zaštićena bez obzira da li su oni koji prenose te informacije to naveli ili ne. Osim informacija koje su u javnom vlasništvu ili za koje dobijete dozvolu, nemate pravo da kopirate, modifikujete ili na bilo koji način menjate, objavljujete, prenosite, distribuirate, izvršavate, prikazujete ili prodajte bilo koju informaciju zaštićenu pravima vlasništva. Slanjem informacija ili sadržaja na bilo koji deo DevProTalk.com, Vi automatski dozvoljavate i predstavljate garanciju da imate pravo da dozvolite DevProTalk.com ili članovima DevProTalk.com bespovratnu, kontinualnu, neograničenu, globalnu dozvolu da koriste, kopiraju, izvršavaju, prikazuju i distribuiraju takve informacije i sadržaje i da iz takvih sadžaja koriste bilo koji deo u bilo koje svrhe, kao i pravo i dozvolu da koriste gore navedene sadržaje. Svi zaštitni znakovi (trademarks), logotipi, oznake usluga, firme ili imena proizvoda koji se pominju na ovom web sajtu su vlasništvo kojim raspolažu njihovi vlasnici.