Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Budowanie struktury bazy od podstaw...
Forum PHP.pl > Forum > Bazy danych > MySQL
primo
Witam,

chcę przebudować gruntownie całą stronkę. W związku z tym rozpocząłem naukę obiektówki, no ale aby przejść do tego to najpierw zalecono mi przebudowe starej struktury bazy na bardziej odpowiednią. Oto stara struktura do przerobienia:

Struktura tabeli dla `filmy`
--

CREATE TABLE `filmy` (
`id` int(10) unsigned NOT NULL auto_increment,
`tytul_pl` varchar(50) NOT NULL default '',
`tytul_ang` varchar(50) NOT NULL default '',
`dlugosc` varchar(4) NOT NULL default '',
`okladka` varchar(60) NOT NULL default '',
`aktorzy` varchar(99) NOT NULL default '',
`rezyseria` varchar(25) NOT NULL default '',
`recenzja` text NOT NULL,
`nosnik_dvd` char(3) NOT NULL default '',
`nosnik_vhs` char(3) NOT NULL default '',
`gatunek` varchar(15) NOT NULL default '',
`rok_prod` year(4) NOT NULL default '0000',
`lektor` char(3) NOT NULL default '',
UNIQUE KEY `id` (`id`),
UNIQUE KEY `tytul_pl_3` (`tytul_pl`),
UNIQUE KEY `tytul_ang` (`tytul_ang`),
KEY `tytul_pl` (`tytul_pl`,`tytul_ang`,`rezyseria`),
KEY `gatunek` (`gatunek`),
FULLTEXT KEY `tytul_pl_2` (`tytul_pl`,`tytul_ang`,`recenzja`)
) TYPE=MyISAM AUTO_INCREMENT=499 ;


jak zapewnie widzicie wszystko jak leci jest w jednej tabeli. Przerobiłem to tak:

-- Struktura tabeli dla `aktorzy`

CREATE TABLE `aktorzy` (
`aktorID` int(10) unsigned NOT NULL auto_increment,
`filmID` int(10) unsigned NOT NULL default '0',
`imie_nazwisko` varchar(50) NOT NULL default '',
`dane_aktor` text NOT NULL,
PRIMARY KEY (`aktorID`),
KEY `imie_nazwisko` (`imie_nazwisko`)
) TYPE=MyISAM AUTO_INCREMENT=1 ;


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

-- Struktura tabeli dla `filmy`

CREATE TABLE `filmy` (
`filmID` int(10) unsigned NOT NULL auto_increment,
`tytul_pl` varchar(200) default NULL,
`tytul_ang` varchar(200) default NULL,
`czas_trwania` varchar(5) NOT NULL default '',
`rok_prod` year(4) NOT NULL default '0000',
`data_dodania` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`filmID`),
UNIQUE KEY `filmID` (`filmID`),
KEY `tytul_pl` (`tytul_pl`,`tytul_ang`)
) TYPE=MyISAM AUTO_INCREMENT=1 ;

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

-- Struktura tabeli dla `nosnik`

CREATE TABLE `nosnik` (
`filmID` int(10) unsigned NOT NULL default '0',
`dvd` char(3) NOT NULL default '',
`vhs` char(3) NOT NULL default ''
) TYPE=MyISAM;

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

-- Struktura tabeli dla `recenzje`

CREATE TABLE `recenzje` (
`filmID` int(10) unsigned NOT NULL default '0',
`rezenzja` text NOT NULL
) TYPE=MyISAM;

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

-- Struktura tabeli dla `rezyserzy`

CREATE TABLE `rezyserzy` (
`rezyserID` int(10) unsigned NOT NULL auto_increment,
`filmID` int(10) unsigned NOT NULL default '0',
`imie_nazwisko` varchar(100) NOT NULL default '',
`dane_rezyser` text NOT NULL,
UNIQUE KEY `rezyserID` (`rezyserID`),
KEY `imie_nazwisko` (`imie_nazwisko`)
) TYPE=MyISAM AUTO_INCREMENT=1 ;




Z jednej tabeli zrobiłem ich kilka. Pytanie moje czy coś byście dodali, zmienili questionmark.gif Oraz czy poprzez index filmID mogę powiązywać zależności między tabelami questionmark.gif
W sumie w każdej tabeli zastosowałem klucz obcy w postaci filmID


Pytanie do tabeli nosnik. Jeżeli mam film tylko na dvd to wpis w tabeli daję "tak", a jak nie mam tego na vhs to wpisuję "nie" i tak dokonuję podziału i wyciągnięcia danych. Podpowiedźcie jakieś lepsze rozwiązanie.

pozdrawiam i czekam na sugestie
mhs
polecam jeden z progamow do przygotowania strutkury bazy danych (np. DBDesigner 4)

masz moze rozrysowany projekt tej bazy danych? byloby lepiej sie rozeznac w tym wszystkim co masz zrobione...

moje uwagi to:

1) tabela aktorzy:
Kod
`imie_nazwisko` varchar(50) NOT NULL default '',

zle! nie tworz pol wielowartosciowych - jezeli chcesz przechowywac dane o imieniu i nazwisku aktora to zawsze rozbijaj to na dwa pole: imie, nazwisko

2) aktora z filmem polaczyl bym osobiscie przez tabele laczaca (osobna tabela gdzie przechowujesz id aktora i id filmu) bo moze byc wielu aktorow w jedym filmie...

3)
Kod
`czas_trwania` varchar(5) NOT NULL default '',
chyba lepiej bedzie jezeli tutaj bedzie to pole typu int gdzie dasz ilosc minut jakie trwa film

4) z tego Twojego projektu widze, ze na odwrot przypisujesz klucze obce. tzn. w tabeli filmy powinno byc id nosnika a nie w nosniku id filmu....

to samo dotyczy sie recenzji i rezyserow!

poza tym nazwij tabele nosnik -> nosniki

5) podobnie jak przy aktora - imie i nazwisko to dwa pola

6) poza tym nie pokoja mnie troche pola
Kod
`dane_rezyser` text NOT NULL, `dane_aktor` text NOT NULL,
co tutaj chcesz przechowywac? bo wydaje mi sie, ze to co tam chcesz wrzucac bedzie trzeba rozbic na osobne pola (nie tworz pol wielowartosciowych)!


pozdrawiam
primo
wielki dzięki za tak obszerne studium mojego problemu.

ok. popoprawiamłem, jednakże mam w związku z tym kolejne problemy, ale powoli:

Kod
-- Struktura tabeli dla  `aktorzy`

CREATE TABLE `aktorzy` (
 `aktorID` int(10) unsigned NOT NULL auto_increment,
 `imie` varchar(30) NOT NULL default '',
 `nazwisko` varchar(30) NOT NULL default '',
 `dane_aktor` text NOT NULL,
 PRIMARY KEY  (`aktorID`),
 KEY `imie_nazwisko` (`imie`),
 KEY `nazwisko` (`nazwisko`)
) TYPE=MyISAM AUTO_INCREMENT=1;

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

-- Struktura tabeli dla  `aktorzyfilmy`
--

CREATE TABLE `aktorzyfilmy` (
 `aktorID` int(10) unsigned NOT NULL default '0',
 `filmID` int(10) unsigned NOT NULL default '0'
) TYPE=MyISAM;

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

-- Struktura tabeli dla  `filmy`
--

CREATE TABLE `filmy` (
 `filmID` int(10) unsigned NOT NULL auto_increment,
 `tytul_pl` varchar(200) default NULL,
 `tytul_ang` varchar(200) default NULL,
 `czas_trwania` int(3) NOT NULL default '0',
 `rok_prod` year(4) NOT NULL default '0000',
 `data_dodania` datetime NOT NULL default '0000-00-00 00:00:00',
 `rezyserID` int(10) unsigned NOT NULL default '0',
 `recenzjaID` int(10) unsigned NOT NULL default '0',
 PRIMARY KEY  (`filmID`),
 UNIQUE KEY `filmID` (`filmID`),
 KEY `tytul_pl` (`tytul_pl`,`tytul_ang`)
) TYPE=MyISAM AUTO_INCREMENT=1;

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

-- Struktura tabeli dla  `nosniki`
--

CREATE TABLE `nosniki` (
 `nosnikID` int(10) unsigned NOT NULL auto_increment,
 `dvd` char(3) NOT NULL default 'tak',
 `vhs` char(3) NOT NULL default 'nie',
 PRIMARY KEY  (`nosnikID`),
 KEY `dvd` (`dvd`,`vhs`)
) TYPE=MyISAM AUTO_INCREMENT=1;

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

-- Struktura tabeli dla  `recenzje`
--

CREATE TABLE `recenzje` (
 `recenzjaID` int(10) unsigned NOT NULL auto_increment,
 `rezenzja` text NOT NULL,
 PRIMARY KEY  (`recenzjaID`)
) TYPE=MyISAM AUTO_INCREMENT=1;

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

--
-- Struktura tabeli dla  `rezyserzy`
--

CREATE TABLE `rezyserzy` (
 `rezyserID` int(10) unsigned NOT NULL auto_increment,
 `imie` varchar(30) NOT NULL default '',
 `nazwisko` varchar(30) NOT NULL default '',
 `dane_rezyser` text NOT NULL,
 UNIQUE KEY `rezyserID` (`rezyserID`),
 KEY `imie_nazwisko` (`imie`),
 KEY `nazwisko` (`nazwisko`)
) TYPE=MyISAM AUTO_INCREMENT=1;


pytanie dotyczy tabeli nosniki, jak to rozwiązać ? wydaje mi się, że nie są potrzebne aż trzy pola i czy potrzebny jest nosnikID.

co do odpowiedzi na nr 6 - dane_aktor to jakaś historia filmów, data urodzenia itp. zresztą nie to jest istotą zagadnienia jako aktor lecz film...

czy w tej wersji traktowanie obcych kluczy jest już poprawne questionmark.gif

urodziły mi się jeszcze 2 pytania:

1) jak istnieje na płycie coś takiego jak informacje dodatkowe: dźwięk, lektor, języki, napisy, format obrazu itp. --- dodać te poszczególne kategorie jako dodatkowe rekordy do tabeli filmy, czy też osobna tabela, tylko jak wtedy przypisywać określone dane do filmu. W sumie to lektor jest albo go nie ma, dźwięku jest około 6 rodzajów itd. są to więc dane dość nieobszerne i w jakimś sensie już zamknięte. W jaki sposób to zorganizować questionmark.gif

2)kolejna tabela gatunki, też w sumie ograniczona liczba danych, al emożliwa do zidentyfikowania poprzez gatunekID = np. komedia itp. a więc łatwiej. no a do tabeli filmy wstawiłem gatunekID

to narazie tyle
yavaho
Nie! no! jezeli chodzi o recenzje to pierwsza wersja byla prawidłowa. Chyba filmu nie kreci sie na podstawie recenzji winksmiley.jpg tylko recenzje sie wysatawia do konkretnego iflmu.

ja bym strukture tabel zbudował w ten sposob:

nosnik aktorzy rezyser
| | |
film
| |
recenzje aktorzyfilmy

Proponuje dodac jeszcze gatunek filmu. Albo jako nowa tabela tak jak nosniki albo dodatkowy rekord w tabeli filmy.
primo
czyli do tabeli recenzje dodaje filmID, ale z tabeli filmy nie usuwam recenzjaID questionmark.gif no to tą tabelę gatunek dodałem. Jak mam rozumień ten wykres questionmark.gif
yavaho
Moze inacze to przedstawie.
Same powiazania pomiedzy tabelami.

tabela 'nosnik' (
bez powiazania z innymi
)

tabela 'rezyser' (
bez powiazania z innymi
)

tabela 'gatunek' (
bez powiazania z innymi
)

tabela 'aktorzy' (
bez powiazania z innymi
)

tabela 'film' (
nosnik_ID
rezyser_ID
gatunek_ID
)

tabela 'aktorzy_filmy' (
aktorzy_ID
film_ID
)

tabela 'recenzje' (
film_ID
)

Jezeli chodzi o dzwiek i lektor to mozesz zrobic nowe tabele takie jak gatunek. Format obrazu moze i tez jezeli nie jest zbyt duza roznorodnosc tych formatow. Ale jezeli o jezyk chodzi to juz nie bo jezeli film jest w kilku roznych jezykach to trzeba zrobic posrednia tabele tak jak to jest z aktorami.
primo
ok. tabele gotowe. teraz dziwne pytanie...

  1. <?php
  2. if (!$bd->zapytaj(&#092;"select filmy.filmID, tytul_pl, tytul_ang, czas_trwania, rok_prod, data_doda
    n
  3. a, gatunek, recenzja, imie, nazwisko, imieaktora, nazwiskoaktora
  4.  from filmy, gatunki, recenzje, rezyserzy, aktorzy&#092;")) {
  5.  die ($db->error());
  6. ?>


powyższe zapytanie jest dla mnie nie do przeskoczenia. Powiązanie 5 tabel. Wszystko jest git dopóki nie dołoże imięaktora i nazwiskoaktora do zapytania - wprawdzie mi zwraca wynik (3 aktorów) ale pętla wyświetla 3 takie same wyniki różniące się tylko właśnie nieszczęsnymi aktorami. W pierwszym przebiegu pętli jest pierwsze imię i nazwisko w drugim drugie itd. Jak to dziadzostwo zmienić questionmark.gif

proszę o pomysł
yavaho
Musisz najpierw zaplanowac jakie dane potrzebujesz i czy one beda sie powtarzac czy nie. Lub czy beda wystepowac czy nie.

Jezeli np nosnik bedzie tylko jeden dla danego filmu to nie potrzeba dodatkowej tablicy z nosnikami - mozna ta pozycje zapisac w tabeli filmy - chyba ze film bedzie posiadal kilka nosnikow. To samo dotyczy sie recenzji - jezeli bedzie tylko jedna recenzja dla danego filmu to tez zbedna jest ta tablica.

Teraz widze ze tabela gatunek jest zupelnie nie potrzebna. Bo ta pozycja zawsze bedzie wystepowac i bedzie tylko jedna i mozna zapisac to w tabeli filmy.
primo
ok, no a z tymi nieszczęsnymi aktorami questionmark.gif jak zdefiniować to zapytanie questionmark.gif już z pół dnia z tym walczę questionmark.gif
yavaho
Ta tabela posrednia z aktorami troche komplikuje sprawe i w php musisz zastosowac petle.
Pisalem to od reki wiec moga byc bledy. Ten kod jest zrobiony na podstawie tych tabel we wczesniejszym moim poscie.

  1. <?php
  2.  $query=&#092;"SELECT * FROM film\";
  3.  $result_film=@mysql_query($query);
  4.  if($result_film && @mysql_num_rows($result_film) > 0)
  5.  { //jezeli sa jakies filmy
  6.  while($row_film=mysql_fetch_array($result_film))
  7.  { //petla - wszystkie filmy po kolei
  8. echo($row_film['tytul'].'<br />'); //wysietlasz tytul filmu
  9. $film_ID = $row_film['film_ID']; //pobierasz ID filmu
  10.  
  11. $query=&#092;"SELECT * FROM aktorzy_filmy WHERE film_ID = $film_ID\";
  12. $result_aktorzy_filmy=@mysql_query($query);
  13. if($result_aktorzy_filmy && @mysql_num_rows($result_aktorzy_filmy) > 0)
  14. { //jezeli do tego filmu przypisani sa aktorzy
  15.  while($row_aktorzy_filmy=mysql_fetch_array($result_aktorzy_filmy))
  16.  { //petla - wszyscy aktorzy z tego filmu
  17.  $aktorzy_ID = $row_aktorzy_filmy['aktorzy_ID']; //pobierasz ID aktora
  18.  
  19.  $query=&#092;"SELECT * FROM aktorzy WHERE aktorzy_ID=$aktorzy_ID\";
  20.  $row_aktorzy=mysql_fetch_array(@mysql_query($query));
  21.  echo($row_aktorzy['nazwisko'].'<br />'); //wysietlasz aktora
  22.  
  23.  }
  24. }
  25.  }
  26.  }
  27. ?>
Mozna to nieco krocej napisac ale chcialem aby bylo bardziej zrozumiale
Parti
Tabele aktorzy, reżyserzy, scenarzyści itd. połączyłbym w jedną tabele osoby. Są przypadki kiedy jedna osoba jest zarówno aktorem oraz reżyserem. W związku z tym informacje o jednej osobie musiałbyś trzymać w dwóch tabelach (aktorzy i reżyserzy). Zdarza się też, że jeden film ma np. dwóch reżyserów.

osoby (osoba_id, imie, nazwisko, ...)
film (film_id, tytul, gatunek, nosnik, ...)
osoby_film (film_id, osoba_id, rola[aktor, rezyser, scenarzysta])
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.