Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> relacje w mysql - jeden do wielu
michael8383
post 30.03.2010, 23:50:58
Post #1





Grupa: Zarejestrowani
Postów: 7
Pomógł: 0
Dołączył: 18.12.2009

Ostrzeżenie: (0%)
-----


witam

mam problem z zaprojektowaniem bazy. robie bardzo prosty katalog filmow i zatrzymalem sie w pewnym miejscu. mam tabele film, w ktorej przechowuje wszystko o filmie. jednakze, gdy doszedlem do pola gatunek, zaczely sie schody - film moze miec wiecej niz jeden gatunek. majac tabele dodatkowa gatunek w ktorej przechowuje nazwy gatunkow, moge wstawic id_gatunku w tabele film. tylko co jesli film ma np 3 gatunki? zrobilem tabele pomocnicza ktora sklada sie z id_film, id_gatunek. operacja dodania filmu i zaznaczeniu 3 gatunkow (przez formularz na stronie), dodawany jest rekord w tabeli film i 3 rekordy w tabeli pomocniczej gdzie id_film jest taki sam a zmienia sie tylko id_gatunek.

w tym miejscu mam pierwsze pytanie : czy taka konstrukcja utworzenia dodatkowej (zbiorczej) tabeli pomocniczej jest jedynym wyjsciem?

druga sprawa to klucze obce w mysql. chcialbym zrobic tak, ze w przypadku usuniecia rekordu z tabeli film o id=1, to automatycznie usuwane sa rekordy w tabeli pomocniczej. utworzylem indeks w tabeli film wskazujacy na tabele posrednia_tabela_z_gatunkami i ustawilem on delete=cascade, on update=cascade i wszystko jest ok, ale w przypadku gdy usune rekordy w tabeli gatunki z danym id_film smile.gif wtedy w tabeli film znika dany rekord. a ja chce zrobic na odwrot. usuwam rekord w film i serwer usuwa mi rekordy w tabeli pomocniczej. proba utworzenia indeksu (klikam na ikonke indeks w phpmyadmin) i tam wskazujac na pole film.id wyskakuje mi blad :

Kod
#1452 - Cannot add or update a child row: a foreign key constraint fails (`filmy2`.`#sql-da0_ae`, CONSTRAINT `#sql-da0_ae_ibfk_1` FOREIGN KEY (`id_film`) REFERENCES `film` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)


wiem, ze da sie to zrobic w pph usuwajac po prostu rekordy odpowiednim zapytaniem, a wlasciwie dwoma zapytaniami smile.gif ale wydaje mi sie, ze szybciej zrobi to serwer bazy, niz php. wlasnie tutaj jest nastepne pytanie : co jest lepsze, kaskadowe usuwanie w php zapytaniami czy zaprojektowanie bazy z relacjami?

przedstawiona ponizej struktura mojej bazy:

film
id (PK)
tytul

gatunek:
id (PK)
gatunek

posrednia_tabela_z_gatunkami
id_film
id_gatunek

czesze ten internet i czesze i nic konkretnego nie znalazlem. same zapytania na forach bez odpowiedzi smile.gif moze tutaj ktos mi pomoze. z gory dziekuje bardzo

pozdrawiam


ps oczywiscie tabele sa INNODB smile.gif

Ten post edytował michael8383 30.03.2010, 23:55:48
Go to the top of the page
+Quote Post
nospor
post 31.03.2010, 07:02:32
Post #2





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
: czy taka konstrukcja utworzenia dodatkowej (zbiorczej) tabeli pomocniczej jest jedynym wyjsciem?
jedynym rozsądnym - tak

Cytat
to automatycznie usuwane sa rekordy w tabeli pomocniczej.
To nie jest tabela pomocnicza. To pelnoprawna tabela.

Cytat
ale w przypadku gdy usune rekordy w tabeli gatunki z danym id_film wtedy w tabeli film znika dany rekord
Cos pomieszales z zakladaniem relacji.

Przyklad poprawnej bazy i relacji:
  1. CREATE TABLE `gatunek` (
  2. `ID` mediumint UNSIGNED NOT NULL AUTO_INCREMENT,
  3. `NAME-I-INNE BZDETY` varchar(64) NOT NULL,
  4. PRIMARY KEY (`ID`)
  5. ) ENGINE=InnoDB;
  6.  
  7. CREATE TABLE `film` (
  8. `ID` int UNSIGNED NOT NULL AUTO_INCREMENT,
  9. `NAME-I-INNE-BZDETY` varchar(64) NOT NULL,
  10. PRIMARY KEY (`ID`)
  11. ) ENGINE=InnoDB;
  12.  
  13. CREATE TABLE `film_gatunek` (
  14. `FK_FILM` int UNSIGNED NOT NULL,
  15. `FK_GATUNEK` mediumint UNSIGNED NOT NULL,
  16. PRIMARY KEY (`FK_FILM`,`FK_GATUNEK`),
  17. CONSTRAINT `fg_fk_film` FOREIGN KEY (`FK_FILM`) REFERENCES `film` (`ID`) ON DELETE CASCADE,
  18. CONSTRAINT `fg_fk_gatunek` FOREIGN KEY (`FK_GATUNEK`) REFERENCES `gatunek` (`ID`) ON DELETE RESTRICT
  19. ) ENGINE=InnoDB;

Gdy usuwasz film - znikają powiązanie w tabeli film_gatunek
Gdy usuwasz gatunek, który jest juz powiązany z filmem - baza na to nie pozwala. Gdybyś chciał jednak w tym miejscu usuwac powiązania w film_gatunek to zamien RESTRICT na CASCADE



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

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
michael8383
post 31.03.2010, 12:07:10
Post #3





Grupa: Zarejestrowani
Postów: 7
Pomógł: 0
Dołączył: 18.12.2009

Ostrzeżenie: (0%)
-----


slicznie dziekuje, dziala. zmodyfikowalem wprawdzie kod tak, ze ustawilem tylko jeden klucz obcy wskazujacy na tabele film. operacje na gatunkach nie beda robione ani spod poziomu bazy ani w php. to po prostu na sztywno ustawione nazwy.

poklikalem troche i wyglada na to, ze nie ustawilem klucza glownego w tabeli film_gatunek na oba pola. nie wiem czemu, ale dziala smile.gif

jeszcze raz dzieki!
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 19.07.2025 - 07:50