Twoje błędy są spowodowane nieprawidłową składnią klucza obcego.
Jednak Myślę, że powinieneś używać pól identyfikatorów zamiast tworzyć złożone klucze główne ciągów . Jest kilka problemów z Twoją metodą...
-
Utrudni to DB łączenie tabel w porównaniu z użyciem pola liczb całkowitych (ID) do łączenia (trudniejsze ==dłuższy czas przetwarzania).
-
Prawidłowe jest posiadanie wielu osób o tym samym imieniu, nawet przy użyciu drugiego inicjału.
-
Co się stanie, jeśli będziesz musiał zmienić czyjeś imię? Albo dlatego, że był źle przechowywany, albo pobrali się, albo coś... Oznacza to, że będziesz musiał nie tylko zaktualizować swojego
employee
tabela, aleworks
table i dowolna inna tabela, której nazwa została użyta jako klucz obcy.
Spójrz na to:http://sqlfiddle.com/#! 2/2dc8c/3/0
Dodałem identyfikator stołu do każdego stołu . Jest to unsigned int
, co oznacza, że nie może być ujemna (ponieważ nie miałoby to większego sensu). Jest to również auto_increment
, co oznacza, że za każdym razem, gdy dodasz wiersz do tabeli, ten identyfikator zostanie wygenerowany automatycznie i wzrośnie o 1.
create table Employee (
Employee_ID int unsigned auto_increment primary key,
Lastname varchar(10),
FirstName varchar(10),
MidInitial char(1),
gender char(1),
street varchar(10),
city varchar(10),
unique (Lastname, FirstName, MidInitial)
);
Możesz dodać rzeczy do tej tabeli w ten sposób:
insert into Employee (Employee_ID, LastName, FirstName, MidInitial)
values (null, 'Smith', 'John', 'K');
null
stanie się automatycznie wygenerowanym identyfikatorem. Będzie unikalny dla każdego rzędu.
Ponadto unikalne ograniczenie oznacza, że kombinacja tych pól musi być unikalna w tabeli. Jednak przy wystarczająco dużej firmie założę się, że dwie osoby będą miały to samo nazwisko. W prawdziwym życiu sugerowałbym usunięcie tego unikalnego ograniczenia.
Wprowadziłem podobne zmiany w tabeli firmowej...
create table company(
company_ID int unsigned auto_increment primary key,
company_name varchar(20),
city varchar(10),
unique (company_name)
);
Można dodać takie rzeczy jak:
insert into company values (null, 'Taco Bell', 'Paris');
Więc... dla works
....zamiast w kółko zapisywać w tej tabeli pełne imię i nazwisko każdej osoby oraz pełną nazwę firmy, teraz musimy tylko przechowywać identyfikatory.
create table Works (
works_id int unsigned auto_increment primary key,
employee_id int unsigned,
compay_id int unsigned,
salary numeric(8,2),
foreign key (employee_id) references Employee (employee_id),
foreign key (compay_id) references company (company_id)
);
Możesz dodawać rzeczy do works
tak:
insert into Works values (null, 1, 1, '10.00');
Ponieważ John Smith był naszym pierwszym pracownikiem, jego Employee_ID będzie wynosić 1. Aby to sprawdzić, po prostu spróbuj select * from Employee where FirstName='John' and LastName='Smith'
. Taco Bell również otrzyma company_id =1. Wstawiając te wartości do works
, oznacza to, że John pracuje teraz w Taco Bell.
Proponuję również dodać pola, takie jak start_date
i end_date
i job_title
do twojego stołu roboczego. I chciałbyś zwrócić szczególną uwagę na wszelkie unikalne ograniczenia dla tej tabeli. Ludzie mogą pracować w tej samej firmie więcej niż raz. Mogą też wykonywać różne prace.
Jeśli chcesz odzyskać swoje dane, użyj takiego zapytania:
select FirstName, MidInitial, LastName,
Company_Name,
Salary
from employee
join works
on works.employee_id = employee.employee_id
join company
on works.company_id = company.company_id
co jest tylko wymyślnym sposobem powiedzenia tego:
select FirstName, MidInitial, LastName,
Company_Name,
Salary
from employee, works, company
where employee.employee_id = works.employee_id and
company.company_id = works.company_id
Niektóre uwagi dotyczące bazy danych...
-
Wybierz konwencję nazewnictwa i trzymaj się jej! Jeśli chcesz użyć
CamelCase
, używaj go wszędzie. Jeśliyou_want_to_use
podkreśla w swoich imionach, używaj ich wszędzie. Istnieje mnóstwo konwencji nazewnictwa do wyboru:poprzedzenie atrybutów (kolumny/pola) nazwą tabeli, używanie popularnych skrótów (lub nie), gdzie używa się wielkich liter (lub nie)… to głównie sprowadza się do osobistych preferencji, ale tam są tam artykuły o zaletach i wadach korzystania z niektórych z nich. Ostatnia uwaga, _tylko dlatego, że możesz użyć spacji w nazwie__, nie oznacza, że powinieneś.`Almost all`
bazy danych pozwalają[you use spaces]
w nazwach, jeśli chcesz, ale później może to spowodować wiele problemów. -
Nazwy tabel nie powinny być w liczbie mnogiej. To jest moje zirytowanie i oto dlaczego:Wiemy, że stół będzie zawierał wiele rekordów... wiele osób/osób, wielu pracowników, wiele firm, wiele wpisów dowolnego typu lub rodzaju. Każdy wiersz opisuje tylko jeden tych rzeczy. Czasami po prostu nie ma sensu, aby imię było w liczbie mnogiej. Innym razem jest to wątpliwe - jak
works
stół. Jeśli czasami robisz to w liczbie mnogiej, a czasami w liczbie pojedynczej, później może to być mylące. Po prostu czyniąc wszystko w liczbie pojedynczej, nadal ma to sens i nie przełączasz się tam iz powrotem ani nie musisz wyszukiwać dokładnej nazwy podczas pisania zapytań. -
Typy danych są ważne i staraj się być spójnym w różnych tabelach dla podobnych pól (jak wszystkie
id
s ten sam typ; zrób wszystkie pola logiczne jako bity lub liczby całkowite lub cokolwiek innego, po prostu zrób je takimi samymi). Do wyboru są różne rozmiary typów liczb całkowitych. Pomyśl o rozmiarze, wydajności i tym, co jest odpowiednie dla Twoich potrzeb. Zdecyduj, czy naprawdę potrzebujesz nvarchar, czy też varchar jest w porządku.- Daty nie powinny nigdy być przechowywane jako ciąg. Użyj odpowiedniej daty, daty i godziny, godziny lub typu danych sygnatury czasowej . Pomoże ci to znacznie później, gdy będziesz musiał je odzyskać, porównać lub użyć w obliczeniach. Kolejną ważną decyzją jest sposób obsługi stref czasowych . Lubię przechowywać wszystko w UTC i obsługiwać wszelkie przesunięcia strefy czasowej w interfejsie użytkownika, gdy informacje są prezentowane użytkownikowi. Dzięki temu wszystko jest spójne i nie muszę się martwić, czy wiersz został wstawiony o godzinie 18:00 na podstawie czasu komputera mojego użytkownika, czasu przeglądarki użytkownika, czasu mojej bazy danych lub czasu serwera.
- Daty nie powinny nigdy być przechowywane jako ciąg. Użyj odpowiedniej daty, daty i godziny, godziny lub typu danych sygnatury czasowej . Pomoże ci to znacznie później, gdy będziesz musiał je odzyskać, porównać lub użyć w obliczeniach. Kolejną ważną decyzją jest sposób obsługi stref czasowych . Lubię przechowywać wszystko w UTC i obsługiwać wszelkie przesunięcia strefy czasowej w interfejsie użytkownika, gdy informacje są prezentowane użytkownikowi. Dzięki temu wszystko jest spójne i nie muszę się martwić, czy wiersz został wstawiony o godzinie 18:00 na podstawie czasu komputera mojego użytkownika, czasu przeglądarki użytkownika, czasu mojej bazy danych lub czasu serwera.
-
Dołącz
ID
pole to jest unikalne dla rzędu w każdej tabeli. Najprostszym sposobem na to jest użycieauto_increment
(mysql) lubidentity(1,1)
(serwer sql), aby baza danych śledziła je dla Ciebie. Te wartości można zresetować lub ponownie umieścić w razie potrzeby. -
Naucz się używać normalizacji .
-
Dowiedz się, jakie transakcje zrobić i dlaczego są ważne... nawet jeśli ich nie używasz.
-
Dowiedz się o różnych rodzajach złączeń . To jedno z najlepszych wyjaśnień jakie kiedykolwiek widziałem. Najważniejszą rzeczą, na którą należy zwrócić uwagę, jest to, czy sprzężenie powinno być sprzężeniem zewnętrznym, czy wewnętrznym.
-
Dowiedz się więcej o Wstrzykiwaniu SQL i co ważniejsze, jak aby temu zapobiec (ten link dotyczy PHP).
-
Jeśli używasz PHP, nie używaj starego
mysql_
klasa. Zamiast tego użyjPDO
lubMySQLi_
. Informacje... -
Wielką zaletą baz danych jest integralność danych, walidacja i sanityzacja . Użytkownicy będą chcieli umieszczać w tabelach wszelkiego rodzaju niechlujne, brudne dane. Czy to MO czy Missouri? Kobieta, F, kobieta, dziewczyna, czy tak? Czy pensja 15,00 za godzinę, 50 tys. rocznie czy 3 tys. to wypłata? Czy to 31.12.2013, 31.12.2013, 31.12.2013, 31.12.2013 czy trzydziesty piąty dwa tysiące trzynasty?
-
Zdecyduj, czy chcesz zezwolić na
NULL
albo nie. To komplikuje sprawę z powodu trójstanowej logiki i będziesz musiał to sprawdzić później. Niektórzy decydują się na użycie zamiast tego pustego ciągu. NULL jest bardziej stanem niż rzeczywistą wartością i oznacza nieokreśloną lub nieznaną - wartość może być dowolna. używam null ponieważ pusty ciąg jest czasami prawidłową wartością pola. Na przykład ustawienieMiddle_Initial
równanie pustego ciągu może oznaczać, że osoba nie ma środkowego inicjału lub po prostu nie wiesz, co to jest. Dla mnie te rzeczy są inne. Dla innych różnica nie ma znaczenia. Pomyśl tylko o liczbach... czy 0 to samo nieznane? -
Jeśli nic więcej, po prostu bądź konsekwentny.