Problem z kluczami w tabeli Mysql

0

Witam

Mam problem ze stworzeniam tabeli "wypozyczenia" zrobiłem ją tak jak poprzednie ale wyskakuje mi bląd 1005. Bardzo proszę o pomoc.
Te tabele są mi potrzebne do zaliczenia :-(


CREATE TABLE imie
(
imie_id INT NOT NULL AUTO_INCREMENT,
imie VARCHAR(15) NOT NULL,
PRIMARY KEY(imie_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE ulica
(
ulica_id INT NOT NULL AUTO_INCREMENT,
nazwa VARCHAR(40),
PRIMARY KEY(ulica_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE miejscowosc
(
miejscowosc_id INT NOT NULL AUTO_INCREMENT,
nazwa VARCHAR(40),
PRIMARY KEY(miejscowosc_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE autor
(
autor_id INT NOT NULL AUTO_INCREMENT,
nazwa VARCHAR(30),
PRIMARY KEY(autor_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE wydawnictwo
(
wydawnictwo_id INT NOT NULL AUTO_INCREMENT,
nazwa VARCHAR(40),
PRIMARY KEY (wydawnictwo_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE okladka
(
okladka_id INT NOT NULL AUTO_INCREMENT,
nazwa VARCHAR(10),
PRIMARY KEY (OKLADKA_ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE ksiazki
(
ksiazki_id INT NOT NULL,
tytul VARCHAR(50)NOT NULL,
autor_id INT(30)NOT NULL,
wydawnictwo_id INT(40)NOT NULL,
stron SMALLINT UNSIGNED NOT NULL,
wymiary VARCHAR(9)NOT NULL,
okladka_id INT(10)NOT NULL,
ISBN VARCHAR(13)NOT NULL,
wydanie TINYINT UNSIGNED NOT NULL,
INDEx(autor_id),
INDEX(wydawnictwo_id),
INDEX(okladka_id),
CONSTRAINT fkey_ksiazki_autor_id FOREIGN KEY (autor_id) REFERENCES autor(autor_id),
CONSTRAINT fkey_ksiazki_wydawnictwo_id FOREIGN KEY (wydawnictwo_id) REFERENCES wydawnictwo(wydawnictwo_id),
CONSTRAINT fkey_ksiazki_okladka_id FOREIGN KEY (okladka_id) REFERENCES okladka(okladka_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



CREATE TABLE osoba
(
osoba_id INT NOT NULL,
imie_id INT(15)NOT NULL,
nazwisko VARCHAR(20) NOT NULL,
ulica_id INT(40)NOT NULL,
kod VARCHAR(6)NOT NULL,
miejscowosc_id INT(40) NOT NULL,
dom VARCHAR(5) NOT NULL,
mieszkania INT,
INDEX(imie_id),
INDEX(ulica_id),
INDEX(miejscowosc_id),
CONSTRAINT fkey_osoba_imie_id FOREIGN KEY (imie_id) REFERENCES imie(imie_id),
CONSTRAINT fkey_osoba_ulica_id FOREIGN KEY (ulica_id) REFERENCES ulica(ulica_id),
CONSTRAINT fkey_osoba_miejscowosc_id FOREIGN KEY (miejscowosc_id) REFERENCES miejscowosc(miejscowosc_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



CREATE TABLE wypozyczenia
(
wypozyczenia_id INT NOT NULL,
tytul_id VARCHAR (50) NOT NULL,
imie_id VARCHAR(15) NOT NULL,
nazwisko_id VARCHAR(20) NOT NULL,
miejscowosc_id INT(40) NOT NULL,
kod_id VARCHAR(6) NOT NULL,
ulica_id INT(40) NOT NULL,
dom_id VARCHAR(5) NOT NULL,
mieszkania_id INT NOT NULL,
data_wypozyczenia DATE,
data_oddania DATE,
data_deklarowana DATE,
w_terminie BOOLEAN NOT NULL default false,
INDEX(tytul_id),
INDEX(imie_id),
INDEX(nazwisko_id),
INDEX(miejscowosc_id),
INDEX(kod_id),
INDEX(ulica_id),
INDEX(dom_id),
INDEX(mieszkania_id),
CONSTRAINT fkey_wypozyczenia_tytul_id FOREIGN KEY (tytul_id) REFERENCES ksiazki(tytul),
CONSTRAINT fkey_wypozyczenia_imie_id FOREIGN KEY (tytul_id) REFERENCES osoba(imie_id),
CONSTRAINT fkey_wypozyczenia_nazwisko_id FOREIGN KEY (nazwisko_id) REFERENCES osoba(nazwisko),
CONSTRAINT fkey_wypozyczenia_miejscowosc_id FOREIGN KEY (miejscowosc_id) REFERENCES osoba(miejscowosc_id),
CONSTRAINT fkey_wypozyczenia_kod_id FOREIGN KEY (kod_id) REFERENCES osoba(kod),
CONSTRAINT fkey_wypozyczenia_ulica_id FOREIGN KEY (ulica_id) REFERENCES osoba(ulica),
CONSTRAINT fkey_wypozyczenia_dom_id FOREIGN KEY (dom_id) REFERENCES osoba(dom),
CONSTRAINT fkey_wypozyczenia_dom_mieszkania_id FOREIGN KEY (mieszkania_id) REFERENCES osoba(mieszkania)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


</php>
0

treść błędu

0

Twój największy problem to źle zaprojektowana baza danych. Otóż zauważyłam że dane sie dublują (co wskazuje że nie masz pojęcia o normalizacji). Ja bym proponowała na początek:
ze zmianą tabeli autor, otóż jeśli zrobiłeś tabele imię to ją wykorzystaj tam (tabela autor będzie miała wtedy trzy kolumny: autor_id, imie_id, nazwisko),
jeśli chodzi o tabele osoby przeniosłabym z niej kolumnę kod (jeśli dobrze rozumie to chodzi tu o kod pocztowy) do tabeli miejscowość (bo przecież kod i miejscowość zawsze są dla siebie jednakowe),
natomiast jeśli chodzi o samą tabele wypożyczenia to zostawiłabym w niej kolumny: wypozyczenia_id, ksiazki_id, osoba_id, data_wypozyczenia, data_oddania, data_deklarowana, w_terminie. Te kolumny wystarczą według mnie w tej tabeli pamiętaj też o odpowiednich relacjach między tabelami.

0

Miałeś rację w prawie wszystkim ;-) bo jezeli chodzi o kod pocztowy to w jednej miejscowości może być wiele poczt i wiele kodów pocztowych (np. Warszawa).

A co do tabeli "wypozyczenia" to nie wiem czy się dobrze zrozumieliśmy bo w niej chodzi o to że jak dam zapytanie do tej tabeli o konkretny tytuł książki to pokaże mi się kto ją wypożyczał z jego adresem (np. książkę "Świat niezwykły" wypożyczały osoby, Jan Kowalski1, Jan Kowalski2, i Jan kowalski3) I też powinna być możliwość zapytania jakie książki wypożyczała konkretna osoba (np. Jan Kowalski4 wypożyczał książki "Słownik ortograficzny" autora takiego, "Działa II wojny światowej" takiego autora i "Rozwój Inteligencji" autora owego).

No i te przeklete relacje w tabeli "wypozyczenia" :-[

Poza tym to wielkie thx [soczek]

0

Jeśli chodzi o kod pocztowy to faktycznie masz racje, natomiast jeśli chodzi o tabele wypożyczenia to uważam że nie potrzebne są tam dane o osobie wystarczy że będzie odpowiednie id_osoby, a poprzez nie będziesz wiedział takie dane jak imię czy nazwisko.

Trochę też nie rozumie tego że tworzysz klucze obce np. nazwisko ze zwykłych kolumn. Najczęściej tworzy się klucze obce w tabeli poprzez użycie klucza głównego z drugiej tabeli (a w tabeli wypożyczenia za dużo tych kluczy obcych i może przez to ci się wszystko sypie).

Proponuje ci zmienić tabele wypożyczenia i usunąć zbędne kolumny, a poprzez wykorzystanie odpowienich zapytań i tak odnajdziesz dane cię interesujące.

0

Witam !

Proponuję ci zmianę tabeli wypożyczenia na taką jak proponuje Wagr oraz dla ułatwienia wyszukiwania danych z bazy możesz stworzyć widok do kilku tabel. tworzy się go podobnie jak tabele.

Oto przykładowy widok:

CREATE VIEW nazwa_widoku
AS SELECT tabela1.id1, tabela1.a, tabela1.b, tabela2. id2, tabela2.c, tabela2.d
FROM tabela1 INNER JOIN tabela2
ON tabela1.id2 = tabela2.id2

Oczywiście w tym zapisie kolumna id2 z tabeli1 jest kluczem obcym w tej tabeli i dzięki niemu możemy połączyć dwie tabele. Pomocna jest przy tym komenda INNER JOIN
. Oczywiście nie musisz w tym wypadku tworzyć widoku możesz jedynie użyć selecta, który będzie miał za zadanie pokazywać interesujące cię rekordy.

Co do tabeli wypożczenia (z tego co się orientuje) to nie tworzy się kluczy obcych w tabeli, jeżeli nie są one kluczami głównymi lub unikalnymi kolumnami innej tabeli, aty właśnie coś takiego zastosowałeś, dlatego może coś ci nie wychodzić.

:-)

0

Witam

Żeczywiście mam problem z kluczami w tabeli wypozyczenia [glowa] , bo jak je wszystkie wywalilem to udało się ją utwożyć :-) na razie bez tych pozycji ale zawsze coś :>

A uwaga że w tej tableli można przez id osoby ją sprawdzić (zamiast dublowania tych samych danych) jest jak najbardziej własciwa.

No i sprawa z widokami też jest interesujaca. :-)

thx

1 użytkowników online, w tym zalogowanych: 0, gości: 1