Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Relacje - problem
Forum PHP.pl > Forum > Bazy danych > MySQL
requinus
Witam, na wstępie muszę zaznaczyć że jestem tu nowy biggrin.gif
Mój problem polega na tym, że gdy tworzę dwie tabele wraz z relacją jeden do wielu to jakoś nie widzę efektu działania tejże relacji. Przejdźmy do konkretów. Oto przykładowe tabele, które tworzę w bazie:
  1. CREATE TABLE adres (
  2. id_adres INT NOT NULL AUTO_INCREMENT,
  3. ulica VARCHAR (25) NOT NULL,
  4. kod_pocztowy VARCHAR (6) NOT NULL,
  5. miejscowosc VARCHAR (25) NOT NULL,
  6. PRIMARY KEY (id_adres)
  7. );
  8.  
  9. CREATE TABLE pracownik (
  10. id_pracownik INT NOT NULL AUTO_INCREMENT,
  11. imie VARCHAR (15) NOT NULL,
  12. nazwisko VARCHAR (20) NOT NULL,
  13. id_adres INT NOT NULL,
  14. PRIMARY KEY (id_pracownik),
  15. CONSTRAINT FK_adres2 FOREIGN KEY (id_adres) REFERENCES adres (id_adres)
  16. );


Nie wiem czy dobrze rozumiem ideę relacji tych dwóch tabel (wyprowadźcie mnie ewentualnie z błędu), ale wydaje mi się, że nie powinno się dać dodać rekordu do tabeli 'pracownik' jeśli zawierał będzie identyfikator 'id_adres', którego nie ma w tabeli 'adres'.
A tutaj niestety daje się dodać taki rekord.
Podpowiedzcie ja zrobić, żeby nie dało się dodać takiego rekordu no i aby dane kaskadowo usuwały się i aktualizowały.
Moja wersja serwera to: 4.0.24_Debian-10sarge2-log

Pozdrawiam i z góry dziękuję za pomoc.
nospor
po pierwsze:
Nie okresliles ENGINE=InnoDB, wiec domyslnie poszlo MyISAM, ktore nie posiada relacji smile.gif

po drugie:
przekombinowales. Zakladam ze jeden adres moze byc przypisany tylko do jednego pracownika, wiec robienie na te okazje dwoch tabel jest ciut bezsensu. No chyba ze masz inne zalozenia to przepraszam smile.gif
dr_bonzo
1.
Bo tworzy ci tabele typu MyISAM, dopiero InnoDB posiadaja wiezy integralnosci

  1. CREATE TABLE ...
  2.  
  3. ) engine = Innodb ;

i po problemie.


2.
http://dev.mysql.com/doc/refman/5.0/en/inn...onstraints.html
ON UPDATE ... , ON CREATE...
requinus
Zrobiłem to jeszcze raz od początku wraz z linijką
  1. engine = Innodb ;


...nie chce mi dodać tabeli pracownik sad.gif

Macie rację, że przykład pracowników i adresów nie najlepiej kojarzy się z relacjami jeden do wielu. Ale zdecydowanie chodzi mi o relację jeden do wielu. Czyli załóżmy że jeden pracownik może mieć wiele adresów winksmiley.jpg.
Pomóżcie...
nospor
Cytat
..nie chce mi dodać tabeli pracownik
no a jakie bledy dostajesz? No ijak to dodales?


Cytat
Czyli załóżmy że jeden pracownik może mieć wiele adresów
No ale twoja struktura i tak tego nie odzwierciedla smile.gif
dr_bonzo
1. zrob obie tabele w InnoDB
2. najpierw utworz ta bez FOREIGN KEYa

3.
Cytat
Czyli załóżmy że jeden pracownik może mieć wiele adresów .

Jak pisal nospor, masz to zle zrobione, na razie jest to: jeden adres ma wielu pracownikow
requinus
Może zróbmy inaczej...
Napiszcie mi proszę kod, który doda mi do bazy dwie tabele spięte relacją jeden do wielu.
Ja spróbuję to "wkeić" i zobaczymy czy zadziała (ew. podam kod błędu).
Próbowałem już różnych kombinacji, które nie działały i już się w tym trochę zagubiłem.
Powiedzmy niech to będzie tabela 'tematy' i tabela 'posty' (takie mini forum winksmiley.jpg ).
Czyli tak, żeby nie dało się dodać 'posta' jeśli wpiszemy w polu Idtematu wartość, która nie istnieje w tabeli tematy.
Mam nadzieję, że wiecie o co mi chodzi.



No i oczywiście jeśli usunę temat, to żeby usunęły się posty z tego tematu.

Zrobiłem tak jak mówiliście, stworzyłem tabele Innodb bez FOREIGN KEYa. Dało radę.
Ale kiedy piszę:

  1. ALTER TABLE pracownik ADD CONSTRAINT FK_adres2 FOREIGN KEY (id_adres) REFERENCES adres (id_adres);


to wyskakuje

  1. ERROR 1005: Can't create table './test/#sql-4b7_a0.frm' (errno: 150)


Co robię nie tak?

Pomóżcie proszę.


P.S.
Niech zostanie jeden adres dla wielu pracowników.
dr_bonzo
ehh, pisalem ze wystarczy dodac typ tabeli
  1. CREATE TABLE adres (
  2. id_adres INT NOT NULL AUTO_INCREMENT,
  3. ulica VARCHAR (25) NOT NULL,
  4. kod_pocztowy VARCHAR (6) NOT NULL,
  5. miejscowosc VARCHAR (25) NOT NULL,
  6. PRIMARY KEY (id_adres)
  7. ) engine = Innodb ;
  8.  
  9. CREATE TABLE pracownik (
  10. id_pracownik INT NOT NULL AUTO_INCREMENT,
  11. imie VARCHAR (15) NOT NULL,
  12. nazwisko VARCHAR (20) NOT NULL,
  13. id_adres INT NOT NULL,
  14. PRIMARY KEY (id_pracownik),
  15. CONSTRAINT FK_adres2 FOREIGN KEY (id_adres) REFERENCES adres (id_adres)
  16. ) engine = Innodb ;
requinus
Po wklejeniu drugiej tabeli mam

  1. ERROR 1005: Can't create table './test/pracownik.frm' (errno: 150)


I właśnie z tym mam problem sad.gif

Jeśli zrobię

  1. CREATE TABLE pracownik (
  2. id_pracownik INT NOT NULL AUTO_INCREMENT,
  3. imie VARCHAR (15) NOT NULL,
  4. nazwisko VARCHAR (20) NOT NULL,
  5. id_adres INT NOT NULL,
  6. PRIMARY KEY (id_pracownik)
  7. ) engine = Innodb ;


Jest OK.

Dlaczego kiedy próbuję dodać później relację instrukcją:

  1. ALTER TABLE pracownik ADD CONSTRAINT FK_adres2 FOREIGN KEY (id_adres) REFERENCES adres (id_adres);


otrzymuję

  1. ERROR 1005: Can't create table './test/#sql-4b7_a0.frm' (errno: 150)






OK, poradziłem sobie. Znalazłem na stronie, którą podał mi dr_bonzo.
Takie coś zadziałało:

  1. CREATE TABLE parent (id INT NOT NULL,
  2. PRIMARY KEY (id)
  3. ) ENGINE=INNODB;
  4. CREATE TABLE child (id INT, parent_id INT,
  5. INDEX par_ind (parent_id),
  6. FOREIGN KEY (parent_id) REFERENCES parent(id)
  7. ON DELETE CASCADE
  8. ) ENGINE=INNODB;


Dzięki Ci dr_bonzo.
Mogę się edukować dalej winksmiley.jpg
Pozdrawiam wszystkich
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.