Organizacija tablica u mysql bazi

bok svima. zanima me kako je najbolje logicki posloziti i organizirati tablicu / tablice u mysql bazi…

prije svega, novi sam u php-u i mysql-u. pa nisam baš siguran kako da dizajniram, da tako kazemo, svoju bazu i ispričavam se zbog podužeg posta.

radim na nekoj stranici na kojoj bi htio svakom korisniku prikazati nekakve podatke dostupne samo njemu. trenutno svaki korisnik ima svoju tablicu ali te podatke (recordse) iz tablice trebam kategorizirati u 9 kategorija u kojoj svaka ima svojih 9 pod kategorija. i svaka pod kategorija bi imala recimo 10-ak tih podataka koji bi trebali imati dvije (osnovne) vrijednosti - naziv i oznaku - a bilo bi dobro kada bi dodao i još par vrijednosti po podatku (brojac neki npr) po kojem onda mogu sortirat poslije to.

9 kat x 9 pkat x 10 itema = 810 recordsa po korisniku…

ubiti, ja trenutno imam dvije tablice po svakom korisniku. jednu koja zapisuje kategorije i podkategorije - sto cini ukupno 81 stupac u svakoj tablici i jednu tablicu u kojoj se zapisuju podaci koja broji onda 6 stupaca ali 810 redova svaka. i ovako ja to nekako zamisljam:

tablica naziva kategorija:
[table=“width: 500, class: grid, align: center”]
[tr]
[td]kat1[/td]
[td]pkat1_1[/td]
[td]pkat1_2[/td]
[td]pkat1_3[/td]
[td]pkat1_4[/td]
[td]…[/td]
[td]kat9[/td]
[td]…[/td]
[td]pkat9_9[/td]
[/tr]
[tr]
[td]dijelovi (npr)[/td]
[td]pc[/td]
[td]dvd[/td]
[td]auto[/td]
[td]blabla[/td]
[td]…[/td]
[td]razno[/td]
[td]…[/td]
[td]blabla[/td]
[/tr]
[/table]

tablica podataka:
[table=“width: 500, class: grid, align: center”]
[tr]
[td]keyID[/td]
[td]kat[/td]
[td]pkat[/td]
[td]naziv[/td]
[td]oznaka[/td]
[td]brojac[/td]
[/tr]
[tr]
[td]1[/td]
[td]kat1[/td]
[td]pkat1_1[/td]
[td]item1[/td]
[td]abcdefg[/td]
[td]1[/td]
[/tr]
[tr]
[td]2[/td]
[td]kat1[/td]
[td]pkat1_3[/td]
[td]item21[/td]
[td]a12fr4g[/td]
[td]1[/td]
[/tr]
[tr]
[td]3[/td]
[td]kat3[/td]
[td]pkat3_1[/td]
[td]item181[/td]
[td]htj234g[/td]
[td]1[/td]
[/tr]
[/table]

( i sad 810 ovakvih redova po korisniku…)

i na kraju, bitno mi je da svaki korisnik moze sam imenovati svoje kategorije i pod kategorije, kao i unositi svoje podatke i vrijednosti.

doduse nemam jos nijednog korisnika, al hipotetski, recimo da imam :smiley:

moja pitanja su sljedeca:

  1. dali ce biti problema ukoliko se pojavi milijun (hipotetski, remember?) korisnika? kako u tom slucaju reagirati? odnosno, do kolko korisnika ja mogu punit mysql bazu na ovakav nacin a da to sve na kraju na stranici lijepo i stabilno radi?

  2. kako najbolje organizirati tablicu sa tim podacima (kako sam skicirao). kako organizirati kategorije i podkategorije?

na kraju htio bi i da se to sve lijepo prikazuje u nekakvoj html tablici svi itemi po podkategorijama i svaka podkat. u svojoj kategoriji. to trenutno radi tako da mysql napravi query iz tablice podaci_$userid ($userid dobivam iz svoje neke login skripte)

ovako to trenutno radi:

$grupe = mysql_query("SELECT * FROM grupe_$userid") or die(mysql_error());
$row2 = mysql_fetch_array($grupe);

$podaci = mysql_query("SELECT * FROM podaci_$userid WHERE pkat='pkat1_1'") or die(mysql_error());

echo $row2['kat1'];
echo $row2['pkat1_1'];
echo "<table>";
while($row = mysql_fetch_array( $podaci )) { echo "<tr><td>"; echo $row['naziv']; echo "
"; echo $row['oznaka']; echo "</td></tr>";} echo "</table>";

$podaci = mysql_query("SELECT * FROM podaci_$userid WHERE pkat='pkat1_2'") or die(mysql_error());]

echo $row2['kat1'];
echo $row2['pkat1_2'];
while($row = mysql_fetch_array( $podaci )) { echo "<tr><td>"; echo $row['naziv']; echo "
"; echo $row['oznaka']; echo "</td></tr>";} echo "</table>";

zadnja 4 reda idu 9 puta (zbog 9 pod kategorija) i imam 9 php-file-ova za svaku kategoriju.

nadam se da sam bio dovoljno jasan. malo sam pretrazio forum, al mene muci nesto specificno i nisam nasao slicno pitanje pa ako eto netko ima volje malo promislit i sugerirat, bio bi zahvalan za svaku pomoc. ja sam samouk skroz sto se tice php-a i surfajuci guglom da realiziram tu svoju ideju, ovako sam osmislio tablice pa se sad pitam dali to drzi vodu i ak drzi, do kad moze drzat? na kraju krajeva, uvijek postoji bolji nacin.

hvala svima koji su procitali post u cijelosti :smiley:
pozdrav!

zasto toliko tablica!?

sve korisnicke kategorije stavljaj u jednu tablicu, samo dodaj jos parametar za id korisnika i samo trazis u toj tablici korisnika i sve ucitas iz toga…

trabas nauciti povezivati tablice, npr:

za korisnika imas tablicu: korisnik, gdje zapisujes id(primary, auto increment) i sta god jos zelis zapisati…
za kategorije imas tablicu: id_zapisa, id_korisnika, kat1, pkat1_1…
i jos trecu tablicu onda za opis kategorija ili stagod…

neces imat ni blizu toliko puno zapisa…

i da, za ovo si napravi klase s kojima ces lakse pristupati podatcima…

oj

imam posebnu tablicu za popis svih korisnika sto mi skripta trazi.
istina, za kategorije bi mogao imati samo jednu tablicu i onda ih pozivat po ID-u korisnika

al sad kad bi svaki korisnik imao svojih 810 zapisa i oznaka (u kojima bi svakih 10 oznaka dijelilo istu podkategoriju) i i svakih 9 podkategorija dijelilo istu kategoriju. da idem na tak po svakom korisniku tablica ili da i tu idem na jednu tablicu i da dodam jos jedan stupac (user ID) i onda da povlacim sve iz jedne tablice?

oce li moc za recimo tak hipotetski milijun korisnika, jedna tablica, da kazem, izdrzat 810 000 000 redova? i da ce to sve stabilno i relativno brzo raditi?

klase? heh… prvi glas :slight_smile:

Ja bih to uradio ovako:

tablica kategorija:
id --id kategorije
naziv --naziv kategorije
gl_kategorija --0 ukoliko je to glavna kategorija ili id kategorije ukoliko je to podkategorija
opis --opis kategorije
korisnik_is --id korisnika kome ta kategorija pripada
– ostala polja koja ti trebaju za tu tablicu

tablica korisnik
id --id korisnika
korisnicko_ime --korisničko ime korisnika
lozinka --lozinka korisnika
– ostala polja koja ti trebaju za tu tablicu

tablica podatak
id --id podatka
naziv --naziv podatka
oznaka --oznaka podatka
kategorija_id --kategorija kojoj pripada podatak
korisnik_id --korisnik kojemu pripada taj podatak
– ostala polja koja ti trebaju za tu tablicu

Jedino mi nije jasan on brojač, čemu to?

I da ne zamaraj se u startu previše brojem zapisa u bazi. Baze od 1, 10, 100 GB u real worldu nisu nikakva iznimka.

Kada dođe do toga onda ćeš lako postaviti indekse i ostale stvari koje treba za optimizaciju baze.

[quote=“bobcat”]oj

imam posebnu tablicu za popis svih korisnika sto mi skripta trazi.
istina, za kategorije bi mogao imati samo jednu tablicu i onda ih pozivat po ID-u korisnika

al sad kad bi svaki korisnik imao svojih 810 zapisa i oznaka (u kojima bi svakih 10 oznaka dijelilo istu podkategoriju) i i svakih 9 podkategorija dijelilo istu kategoriju. da idem na tak po svakom korisniku tablica ili da i tu idem na jednu tablicu i da dodam jos jedan stupac (user ID) i onda da povlacim sve iz jedne tablice?

oce li moc za recimo tak hipotetski milijun korisnika, jedna tablica, da kazem, izdrzat 810 000 000 redova? i da ce to sve stabilno i relativno brzo raditi?

klase? heh… prvi glas :)[/quote]

dobro ti je CreatifCode rekao, nemoj se zamarati s brojem zapisa u tablici…

klase(class) koristis u objektnom programiranju u php-u(naravno i u drugim objektno orijentiram programskim jezicima), a one ti omogucuju da s jednom klasom kreiraš koliko želiš objekata koji koriste atribute klase… uglavnom moras nauciti oop u php-u i to ce ti olaksati kompliciranije programiranje…

što se tiče klasa ovo bi bila jedna npr. za korisnika

Eto to je ukratko.

[color="#FF0000"][size=14]Ovaj kod nikako nije za upotrebu u produkciji i služi samo kao primjer jedne klase[/size][/color]

[quote=“CreatifCode”]što se tiče klasa ovo bi bila jedna npr. za korisnika

Eto to je ukratko.

[color="#FF0000"][size=14]Ovaj kod nikako nije za upotrebu u produkciji i služi samo kao primjer jedne klase[/size][/color][/quote]

a zajebao si me sad, jos gledam sta ne radi :wink:

no salu na stranu, rad s objektima i klasama je nesto sto stvarno ustedi vrijeme i olaksa programiranje, zato su mi i najdrazi objektno orijentirani programski jezici. Klase mogu omogucavati da bez diranja tonu koda gdje se sve klasa koristi, minjamo samo kod u klasi i tako automatski utjecemo na svaki dio gdje se ta klasa koristi… mogucnosti su brojne, a ako netko misli ozbiljno programirati u php-u onda mu ne gine ucenje oop u php-u…

hvala vam na komentarima.

znaci bolje je imat 1 tablicu od 810 000 redova nego 1000 tablica po 810 redova svaka?
nece biti nikakav problem poslije kada ta jedna tablica naraste na 810 M redova? svejedno ce brzo i stabilo raditi kao i milijun tablica?

i sto ako poslije zelim dodavati jos kategorija? nisam bas tolko upucen u sql - n00b alert! - pretpostavljam da je dobro da su podaci sortirani po onom primary ID-u. ak je tak jel se moze to sortirati kasnije? :slight_smile: kada se npr tamo nastani 1000 korisnika i onda ja moram dodat (recimo) za jos jednu kategoriju svakome po jos 9 podkategorija (90 redova ukupno, za svakog korisnika). hoce li to pravit probleme na tako velikoj tablici? nekako mi se logicki cini da je bolje da svako ima svoju tablicu.

mislim, nisam ja to nikad do sad koristio. moj prvi susret sa mysql-om pa me zanima. sta mogu ocekivati sutra-preksutra.

pozdrav

Ajmo iznova.
Prvo ćemo definirati tablice, imamo 3 osnovne tablice:
kategorija, korisnik, podatak

zatim imamo 2 pomoćne:
kategorija_korisnik
kategorija_podatak

Tablica kategorija:

kategorija
id  --id kategorije
naziv --naziv kategorije
gl_kategorija --0 default, ako je 0 onda je glavna, ako je neki drugi broj onda je to podkategorija
opis --opis kategorije

--postavljamo index na id polje

Tablica korisnik

id --id korisnka
ime --ime korisnika
email --email korisnika
lozinka --lozinka korisnika

--postavljamo index na id polje

Tablica podatak

id --id podatka
naziv --naziv podatka
oznaka --oznaka podatka

--postavljamo index na id polje

Pomoćna tablica kategorija_korisnik

korisnik_id --foreign key na tablicu korisnik
kategorija_id --foreign key na tablicu kategorija

--postavljamo index na oba polja

Pomoćna tablica kategorija_podatak

kategorija_id --foreign key na tablicu kategorija
podatak_id -- foreign key na tablicu podatak

--postavljamo index na oba polja

Sad kad smo definirali tablice, ajmo vidjet koliko će u kojoj tablici biti podataka, ako imamo 1000 korisnika, po korisniiku 9 kategorija i 9 podkategorija, te 10 podataka po kategoriji. Ovo radim samo zato jer vidim da te strašno plaši veličina baze i broj redova.

Tablica kategorija će imati 9.000 zapisa glavnih kategorija i 81.000 zapisa, ukupno 90.000 zapisa
Tablica podatak će imati 900.000 zapisa
Tablica korisnik će imati 1000 zapisa

Tablica kategorija_podatak će imati (ukupno kategorija * podatak po kategoriji) 900.000 podataka
Tablica kategorija_korisnik će imati (ukupno korisnika * kategorija po korisniku(81 ( 9 kategorija * 9 podkategorija) )) 81.000 podataka

Idemo sad vidjeti kako bi mogli izvući pojedine kategorije po korisniku

Evo nadam se da sam ti barem malo olakšao tvoje vježbanje.

Evo ti i dump baze da se možeš igrati

- phpMyAdmin SQL Dump
-- version 3.4.10.1
-- http://www.phpmyadmin.net
--
-- Računalo: localhost
-- Vrijeme generiranja: Tra 06, 2012 u 04:31 PM
-- Verzija poslužitelja: 5.5.20
-- PHP verzija: 5.3.10

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

--
-- Baza podataka: `test`
--

-- --------------------------------------------------------

--
-- Tablična struktura za tablicu `kategorija`
--

CREATE TABLE IF NOT EXISTS `kategorija` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `naziv` varchar(64) NOT NULL,
  `gl_kategorija` int(11) NOT NULL DEFAULT '0',
  `opis` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;

--
-- Izbacivanje podataka za tablicu `kategorija`
--

INSERT INTO `kategorija` (`id`, `naziv`, `gl_kategorija`, `opis`) VALUES
(1, 'Auti', 0, 'Glavna kategorija '),
(2, 'Nekretnine', 0, 'Glavna kategorija za nekretnine'),
(3, 'Marke', 1, 'Podkategorija automobila'),
(4, 'Kuće', 2, 'Podkategorija nekretnina');

-- --------------------------------------------------------

--
-- Tablična struktura za tablicu `kategorija_podatak`
--

CREATE TABLE IF NOT EXISTS `kategorija_podatak` (
  `kategorija_id` int(11) NOT NULL,
  `podatak_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Izbacivanje podataka za tablicu `kategorija_podatak`
--

INSERT INTO `kategorija_podatak` (`kategorija_id`, `podatak_id`) VALUES
(3, 1),
(3, 2),
(4, 3),
(4, 4);

-- --------------------------------------------------------

--
-- Tablična struktura za tablicu `korisnik`
--

CREATE TABLE IF NOT EXISTS `korisnik` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ime` varchar(64) CHARACTER SET utf8 NOT NULL,
  `email` varchar(64) CHARACTER SET utf8 NOT NULL,
  `lozinka` varchar(128) CHARACTER SET utf8 NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

--
-- Izbacivanje podataka za tablicu `korisnik`
--

INSERT INTO `korisnik` (`id`, `ime`, `email`, `lozinka`) VALUES
(1, 'Nenad', 'nenad@creatifcode.com', 'test_lozinka'),
(2, 'Katica', 'katica.petkovic@gmail.com', 'lozinka_test');

-- --------------------------------------------------------

--
-- Tablična struktura za tablicu `korisnik_kategorija`
--

CREATE TABLE IF NOT EXISTS `korisnik_kategorija` (
  `korisnik_id` int(11) NOT NULL,
  `kategorija_id` int(11) NOT NULL,
  KEY `korisnik_kategorija_index` (`korisnik_id`,`kategorija_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Izbacivanje podataka za tablicu `korisnik_kategorija`
--

INSERT INTO `korisnik_kategorija` (`korisnik_id`, `kategorija_id`) VALUES
(1, 1),
(1, 3),
(2, 2),
(2, 4);

-- --------------------------------------------------------

--
-- Tablična struktura za tablicu `podatak`
--

CREATE TABLE IF NOT EXISTS `podatak` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `naziv` varchar(64) CHARACTER SET utf8 NOT NULL,
  `opis` varchar(256) CHARACTER SET utf8 NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=5 ;

--
-- Izbacivanje podataka za tablicu `podatak`
--

INSERT INTO `podatak` (`id`, `naziv`, `opis`) VALUES
(1, 'Alfa Romeo', 'auti marke alfa'),
(2, 'Audi', 'auti marke audi'),
(3, 'Prizemnica', 'Kuće prizemnice'),
(4, 'Visokoprizemnica', 'Kuće visoko prizemnice');

Ako nešto nije jasno samo pitaj tu smo da pomognemo.

kao prvo, hvala obojici na trudu… kad se vidimo imate cevape! :smiley:

CreatifCode - nije mi bas jasno zasto da imam dvije tablice za kategorije i dvije tablice za podatke od 900 000 redova (premda za 1000 korisnika trebam imati 810 000 redova u tablici podaci)

preslozio sam sada malo svoje tablice i stvari sada stoje ovako:

imam samo 3 tablice. jednu za popis korisnika nazvanu korisnici (iz koje mi je bitan samo ID trenutnog korisnika), jednu za popis kategorija od svakog korisnika i jednu za podatke (u kojoj svaki korisnik ima 810 redova)

tablica korisnici

id --id korisnika
username --ime korisnika
email --email korisnika
password --lozinka korisnika
  • ima jos podataka (stupaca) ali su nevazni za sad. bitan je samo id - kroz stranicu uvijek $userid

tablica kategorije:

id --id podatka
userid --id korisnika
kat1 --kategorija1
pkat1_1 --podkategorija1_1
pkat1_2 --podkategorija1_2
 .
 .
pkat1_9 --podkategorija1_9
kat2 --kategorija2
 .
kat9 --kategorija9
 .
pkat9_9 --podkategorija9_9
  • ukupno 92 stupca / svaki korisnik po 1 red
  • svaki korisnik bi trebao dobiti po jedan red u kojem ce pisat njegov ID iz tablice korisnici

tablica podaci:

id --id podatka
userid --id korisnika
kat --kategorija u koju spada podatak (trenutno je varchar(5) i oznake unutra idu npr: kat1, kat2, kat9)
pkat --podkategorija u koju spada podatak  (isto varchar(8) i oznake unutra idu npr: pkat1_1, pkat2_5, pkat9_2)
naziv --naziv podatka
oznaka --oznaka podatka
  • ukupno 6 stupaca / svaki korisnik po 810 redova
  • kad se rega novi korisnik, skripta doda 810 novih redova koje ispuni podacima iz prvih 810 redova i u svaki taj novi red stavi pod stupac userid korisnikov ID iz tablice korisnici

Ovako izvlacim podatke i prikazujem ih:

imam 9 ovakvih divova (svaki za svoju pod-kategoriju) u 9 razlicitih php file-ova (svaki za po jednu kategoriju)

divovi su jedan do drugog, tak da vizualno to sve cini jednu tablicu gdje je prvi red odabir kategorije (odnosno odabir php file-a), drugi red ispisuje podkategorije u toj kategoriji, a onda “while” generira redove u tablici dok vidi da ima necega (uvijek ima točno 10 podataka sa istom pod-kategorijom i uvijek ce biti max 10 redova u toj html tablici (uz jos 2 reda za kat i pkat))

e sad… moze li to tako? jer trenutno radi ok…

pozdrav

Može ali ne može. :slight_smile:

Ovo što si ti uradio ne prolazi nit prvu normalizacijsku formu baze.

Što je to normalizacija baze podataka:

Ima i druga normalizacijska foma:

, a svaka baza bi trebala biti prilagođena barem trećoj normalizacijskoj formi:

Kad ovo pročitaš i shvatiš onda se vrati vamo pa ćemo na PHP prijeći. Nisam namjerno ništa pisao ovdje jer je na danim linkovima to puno bolje i detaljnije objašnjeno.

oh… budem to sve prostudirao pa se vratim.
hvala na informaciji :slight_smile:

pozdrav

Imaš onaj zahvali se za post, to je dovoljno, ne trebaju čevapi. :slight_smile:

Da tu sam se malo zeznuo u računu jer sam ja pribroio ovome i podatke u glavnim kategorijama

ovo je ok.

Ovo nije u redu, a zašto nije u redu shavtit ćeš kada pročitaš linkove koje sam ti dao u prethodnom postu.

[quote=“bobcat”]
tablica podaci:

id --id podatka
userid --id korisnika
kat --kategorija u koju spada podatak (trenutno je varchar(5) i oznake unutra idu npr: kat1, kat2, kat9)
pkat --podkategorija u koju spada podatak  (isto varchar(8) i oznake unutra idu npr: pkat1_1, pkat2_5, pkat9_2)
naziv --naziv podatka
oznaka --oznaka podatka
  • ukupno 6 stupaca / svaki korisnik po 810 redova
  • kad se rega novi korisnik, skripta doda 810 novih redova koje ispuni podacima iz prvih 810 redova i u svaki taj novi red stavi pod stupac userid korisnikov ID iz tablice korisnici

[quote=“bobcat”]

Ovo također nije ok, i zato sam ti ja stavio one dvije dodatne tablice. kategorija_korisnik i kategorija_podatak
Isto info na linku iz prethodnog posta

[quote=“bobcat”]
Ovako izvlacim podatke i prikazujem ih:

imam 9 ovakvih divova (svaki za svoju pod-kategoriju) u 9 razlicitih php file-ova (svaki za po jednu kategoriju)

divovi su jedan do drugog, tak da vizualno to sve cini jednu tablicu gdje je prvi red odabir kategorije (odnosno odabir php file-a), drugi red ispisuje podkategorije u toj kategoriji, a onda “while” generira redove u tablici dok vidi da ima necega (uvijek ima točno 10 podataka sa istom pod-kategorijom i uvijek ce biti max 10 redova u toj html tablici (uz jos 2 reda za kat i pkat))

e sad… moze li to tako? jer trenutno radi ok…

pozdrav[/quote][/quote][/quote]

O ovome ćemo drugi put, nakon što pročitaš gornje linkove. :slight_smile:


Copyright © 2020 WM Forum - AboutContact - Sponsored by: Mydataknox & Webmaster.Ninja