Vaše chyby jsou způsobeny nesprávnou syntaxí cizího klíče.
Myslím si však, že byste místo primárních klíčů složených z řetězců měli používat pole ID . S vaší metodou je několik problémů...
-
Ztíží to DB spojovat tabulky dohromady ve srovnání s použitím celočíselného (ID) pole ke spojování (těžší ==delší doba zpracování).
-
Platí, že má více lidí se stejným jménem, a to i s použitím střední iniciály.
-
Co se stane, když budete muset někomu změnit jméno? Buď proto, že to bylo uloženo špatně, nebo se vzali nebo tak něco... To znamená, že budete muset nejen aktualizovat svého
employee
tabulka, aleworks
tabulka a jakákoli další tabulka, jejíž název jste použili jako cizí klíč.
Podívejte se na toto:http://sqlfiddle.com/#! 2/2dc8c/3/0
Do každé tabulky jsem přidal ID tabulky . Je to unsigned int
, což znamená, že nemůže být negativní (protože by to nedávalo moc smysl). Je to také auto_increment
, což znamená, že pokaždé, když do tabulky přidáte řádek, bude toto ID automaticky vygenerováno a zvýší se 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)
);
Do této tabulky byste přidali věci takto:
insert into Employee (Employee_ID, LastName, FirstName, MidInitial)
values (null, 'Smith', 'John', 'K');
null
se stane automaticky generovaným ID. Pro každý řádek bude jedinečný.
Také jedinečné omezení znamená, že kombinace těchto polí musí být v tabulce jedinečná. Nicméně s dostatečně velkou společností se vsadím, že dva lidé budou mít stejné jméno. V reálném životě bych doporučil toto jedinečné omezení odstranit.
Podobné změny jsem provedl v tabulce společnosti...
create table company(
company_ID int unsigned auto_increment primary key,
company_name varchar(20),
city varchar(10),
unique (company_name)
);
Mohou být přidány věci jako:
insert into company values (null, 'Taco Bell', 'Paris');
Takže... pro works
.... místo toho, abychom do této tabulky znovu a znovu ukládali celé jméno každé osoby a celý název společnosti, musíme nyní ukládat pouze ID.
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)
);
Můžete přidat věci do works
takto:
insert into Works values (null, 1, 1, '10.00');
Vzhledem k tomu, že John Smith byl naším prvním zaměstnancem, jeho Employee_ID by bylo 1. Chcete-li to ověřit, zkuste select * from Employee where FirstName='John' and LastName='Smith'
. Taco Bell by také získal company_id =1. Vložením těchto hodnot do works
, to znamená, že John nyní pracuje v Taco Bell.
Také bych vám doporučil přidat pole jako start_date
a end_date
a job_title
k vašemu pracovnímu stolu. A také byste chtěli věnovat zvláštní pozornost všem jedinečným omezením této tabulky. Lidé mohou pracovat pro stejnou společnost více než jednou. Mohou mít i různá zaměstnání.
Když chcete dostat svá data zpět, použijte dotaz jako tento:
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ž je jen skvělý způsob, jak to říct:
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
Několik poznámek k databázím...
-
Vyberte si konvenci pojmenování a držte se jí! Pokud chcete použít
CamelCase
, použijte to všude. Pokudyou_want_to_use
podtržítka ve svých jménech, používejte je všude. Existuje spousta konvencí pojmenování, ze kterých si můžete vybrat:předřazení atributů (sloupců/polí) názvu tabulky, používání běžných zkratek (nebo ne), kde se používá velká písmena (nebo ne)... to většinou závisí na osobních preferencích, ale existuje jsou tam články o výhodách a nevýhodách používání některých z nich. Poslední poznámka, _jen proto, že můžete ve jméně používat mezery,__ neznamená, že byste měli.`Almost all`
databáze umožňují[you use spaces]
v názvech, chcete-li, ale později to může způsobit spoustu problémů. -
Názvy tabulek by neměly být množné. Toto je moje hnusná nálada a tady je důvod:Víme, že stůl pojme mnoho záznamů... mnoho lidí/osob, mnoho zaměstnanců, více společností, více položek jakéhokoli typu nebo druhu. Každý řádek popisuje pouze jeden z těchto věcí. Někdy prostě ani nedává smysl, aby jméno bylo v množném čísle. Jindy je to sporné - stejně jako
works
stůl. Pokud někdy uděláte množné číslo a někdy jednotné číslo, může to být později matoucí. Tím, že je to celé singulární, to stále dává dokonalý smysl a při psaní dotazů nemusíte přepínat tam a zpět ani nemusíte hledat přesný název. -
Datové typy jsou důležité a pokuste se být konzistentní napříč tabulkami pro podobná pole (stejně jako všechny
id
s stejný typ; udělejte ze všech booleovských polí všechny bity nebo celá čísla nebo cokoli jiného, prostě je udělejte stejně). Existují různé velikosti celočíselných typů, ze kterých si můžete vybrat. Zamyslete se nad velikostí, výkonem a tím, co je vhodné pro vaše potřeby. Rozhodněte se, zda opravdu potřebujete nvarchar nebo zda je varchar v pořádku.- Data by neměla nikdy být uložen jako řetězec. Použijte vhodný datový typ data, data a času, času nebo časového razítka . To vám později velmi pomůže, když jej budete potřebovat získat, porovnat nebo použít ve výpočtech. Dalším důležitým rozhodnutím je, jak jste se rozhodli nakládat s časovými pásmy . Rád ukládám vše v UTC a zpracovávám jakékoli offsety časového pásma na frontendu, když jsou informace prezentovány uživateli. Díky tomu je vše konzistentní a nemusím se starat o to, zda byl řádek vložen v 18:00 na základě času počítače mého uživatele, času prohlížeče uživatele, času mé databáze nebo času serveru.
- Data by neměla nikdy být uložen jako řetězec. Použijte vhodný datový typ data, data a času, času nebo časového razítka . To vám později velmi pomůže, když jej budete potřebovat získat, porovnat nebo použít ve výpočtech. Dalším důležitým rozhodnutím je, jak jste se rozhodli nakládat s časovými pásmy . Rád ukládám vše v UTC a zpracovávám jakékoli offsety časového pásma na frontendu, když jsou informace prezentovány uživateli. Díky tomu je vše konzistentní a nemusím se starat o to, zda byl řádek vložen v 18:00 na základě času počítače mého uživatele, času prohlížeče uživatele, času mé databáze nebo času serveru.
-
Zahrňte
ID
pole který je jedinečný pro řádek v každé tabulce. Nejjednodušší způsob, jak toho dosáhnout, je použítauto_increment
(mysql) neboidentity(1,1)
(sql server), aby jej databáze sledovala za vás. Tyto hodnoty lze v případě potřeby resetovat nebo znovu nastavit. -
Naučte se používat normalizaci .
-
Přečtěte si, jaké transakce dělat a proč jsou důležité... i když je nepoužíváte.
-
Přečtěte si o různých typech připojení . Toto je jedno z nejlepších vysvětlení Už jsem někdy viděl. Hlavní věc, kterou je třeba věnovat pozornost, je, zda by spojení mělo být vnější nebo vnitřní.
-
Další informace o SQL Injection a co je důležitější, jak abyste tomu zabránili (ten odkaz je pro PHP).
-
Pokud používáte PHP, nepoužívejte starý
mysql_
třída. Místo toho použijtePDO
neboMySQLi_
. Informace... -
Velká věc na databázích je integrita dat, ověřování a sanitace . Uživatelé budou chtít do vašich tabulek vkládat všechny druhy nedbalých a špinavých dat. Je to MO nebo Missouri? Žena, F, žena, dívka, nebo ano? Je mzda 15,00 za hodinu, 50 000 ročně nebo 3 000 výplata? Je to 31. 12. 2013, 31. 12. 2013, 31. 12. 13, 31. prosince 2013 nebo prosinec třicátých pěstí dva tisíce třináct?
-
Rozhodněte se, zda chcete povolit
NULL
nebo ne. Dělá to věci složitější kvůli logice trojitého stavu a budete to muset později zkontrolovat. Někteří lidé se rozhodnou místo toho použít prázdný řetězec. NULL je spíše stav než skutečná hodnota a znamená nedefinovaný nebo neznámý - hodnota může být jakákoli. Používám null protože prázdný řetězec je někdy platnou hodnotou pro pole. Například nastaveníMiddle_Initial
rovnat se prázdnému řetězci může znamenat, že osoba nemá střední iniciálu, nebo to může znamenat, že prostě nevíte, co to je. Pro mě jsou tyto věci jiné. Pro ostatní lidi na rozdílu nezáleží. Stačí vzít v úvahu čísla... je 0 stejná jako neznámá? -
Pokud nic jiného, buďte důslední.