I tuoi errori sono causati da una sintassi errata della chiave esterna.
Tuttavia, Penso che dovresti utilizzare i campi ID invece di creare chiavi primarie composte da stringhe . Ci sono alcuni problemi con il tuo metodo...
-
Renderà più difficile per il DB unire le tabelle rispetto all'utilizzo di un campo intero (ID) per unire (più difficile ==più tempo di elaborazione).
-
È valido avere più persone con lo stesso nome, anche utilizzando un'iniziale centrale.
-
Cosa succede se devi cambiare il nome di qualcuno? O perché è stato memorizzato in modo errato o si sono sposati o altro... Ciò significa che non dovrai solo aggiornare il tuo
employee
tabella, ma ilworks
table e qualsiasi altra tabella di cui hai usato il nome come chiave esterna.
Dai un'occhiata a questo:http://sqlfiddle.com/#! 2/2dc8c/3/0
Ho aggiunto un ID tabella a ciascuna tabella . È un unsigned int
, il che significa che non può essere negativo (perché non avrebbe molto senso). È anche auto_increment
, il che significa che ogni volta che aggiungi una riga alla tabella, questo ID verrà generato automaticamente e aumenterà di 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)
);
Aggiungeresti elementi a questa tabella in questo modo:
insert into Employee (Employee_ID, LastName, FirstName, MidInitial)
values (null, 'Smith', 'John', 'K');
Il null
diventerà l'ID generato automaticamente. Sarà unico per ogni riga.
Inoltre, un vincolo unico significa che la combinazione di questi campi deve essere univoca nella tabella. Tuttavia, con un'azienda abbastanza grande, scommetto che due persone avranno lo stesso nome. Nella vita reale, suggerirei di rimuovere questo vincolo unico.
Ho apportato modifiche simili alla tabella dell'azienda...
create table company(
company_ID int unsigned auto_increment primary key,
company_name varchar(20),
city varchar(10),
unique (company_name)
);
Si potrebbero aggiungere cose come:
insert into company values (null, 'Taco Bell', 'Paris');
Quindi... per works
.... invece di memorizzare il nome completo di ogni persona e il nome completo dell'azienda più e più volte in questa tabella, ora dobbiamo solo memorizzare gli 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)
);
Potresti aggiungere elementi a works
così:
insert into Works values (null, 1, 1, '10.00');
Poiché John Smith è stato il nostro primo dipendente, il suo Employee_ID sarebbe 1. Per verificarlo, prova a select * from Employee where FirstName='John' and LastName='Smith'
. Taco Bell otterrebbe anche company_id =1. Inserendo quei valori in works
, ciò significa che John ora lavora presso Taco Bell.
Ti suggerirei anche di aggiungere campi come start_date
e end_date
e job_title
al tuo tavolo di lavoro. E vorresti prestare particolare attenzione anche a eventuali vincoli univoci per questa tabella. Le persone possono lavorare per la stessa azienda più di una volta. Possono anche svolgere lavori diversi.
Quando vuoi recuperare i tuoi dati, dovresti utilizzare una query come questa:
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
che è solo un modo elegante per dire questo:
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
Alcune note sulle cose del database...
-
Scegli una convenzione di denominazione e rispettala! Se vuoi usare
CamelCase
, usalo ovunque. Seyou_want_to_use
caratteri di sottolineatura nei tuoi nomi, usali ovunque. Ci sono un sacco di convenzioni di denominazione tra cui scegliere:prefissare attributi (colonne/campi) con il nome della tabella, usare abbreviazioni comuni (o meno), dove si usa (o meno) la maiuscola... questo dipende principalmente dalle preferenze personali ma c'è ci sono articoli là fuori sui pro e contro dell'utilizzo di alcuni. Ultima nota, _solo perché puoi usare gli spazi in un nome,__ non significa che dovresti.`Almost all`
database lascia[you use spaces]
nei nomi se vuoi, ma può causare molti problemi in seguito. -
I nomi delle tabelle non devono essere plurali. Questa è una mia seccatura ed ecco perché:sappiamo che un tavolo conterrà molti record... molte persone/persone, molti dipendenti, più aziende, più voci di qualsiasi tipo o tipo. Ogni riga ne descrive solo uno di queste cose. A volte non ha nemmeno senso che il nome sia plurale. Altre volte, è discutibile, come il
works
tavolo. Se a volte lo rendi plurale, ea volte lo rendi singolare, può creare confusione in seguito. Semplicemente rendendo tutto singolare, ha ancora perfettamente senso e non devi passare avanti e indietro o dover cercare il nome esatto quando scrivi le query. -
I tipi di dati sono importanti e cerca di essere coerente tra le tabelle per campi simili (come tutti gli
id
s dello stesso tipo; rendi tutti i campi booleani tutti bit o interi o altro, rendili uguali). Ci sono diverse dimensioni di tipi interi tra cui puoi scegliere. Pensa alle dimensioni, alle prestazioni e a ciò che è appropriato per le tue esigenze. Decidi se hai davvero bisogno di un nvarchar o se un varchar va bene.- Le date dovrebbero mai essere memorizzato come una stringa. Utilizza il tipo di dati data, data e ora, ora o timestamp appropriato . Questo ti aiuterà molto in seguito quando dovrai recuperarlo, confrontarlo o usarlo nei calcoli. Un'altra decisione importante è come hai scelto di gestire i fusi orari . Mi piace archiviare tutto in UTC e gestire qualsiasi cosa di offset del fuso orario sul front-end, quando le informazioni vengono presentate all'utente. Ciò mantiene tutto coerente e non devo preoccuparmi se la riga è stata inserita alle 18:00 in base all'ora del computer dell'utente, dell'ora del browser dell'utente, dell'ora del mio database o dell'ora del server.
- Le date dovrebbero mai essere memorizzato come una stringa. Utilizza il tipo di dati data, data e ora, ora o timestamp appropriato . Questo ti aiuterà molto in seguito quando dovrai recuperarlo, confrontarlo o usarlo nei calcoli. Un'altra decisione importante è come hai scelto di gestire i fusi orari . Mi piace archiviare tutto in UTC e gestire qualsiasi cosa di offset del fuso orario sul front-end, quando le informazioni vengono presentate all'utente. Ciò mantiene tutto coerente e non devo preoccuparmi se la riga è stata inserita alle 18:00 in base all'ora del computer dell'utente, dell'ora del browser dell'utente, dell'ora del mio database o dell'ora del server.
-
Includi un
ID
campo che è unico per la riga in ogni tabella. Il modo più semplice per farlo è usare unauto_increment
(mysql) oidentity(1,1)
(sql server) in modo che il database ne tenga traccia per te. Questi valori possono essere ripristinati o riseminati se necessario. -
Impara a usare la normalizzazione .
-
Scopri quali transazioni fare e perché sono importanti... anche se non li usi.
-
Scopri i diversi tipi di join . Questa è una delle migliori spiegazioni non ho mai visto. La cosa principale a cui prestare attenzione è se il join deve essere un join esterno o interno.
-
Ulteriori informazioni su SQL Injection e, soprattutto, come per prevenirlo (quel link è per PHP).
-
Se stai usando PHP, non usare il vecchio
mysql_
classe. Invece, usaPDO
oMySQLi_
. Informazioni... -
La cosa più importante dei database è integrità, convalida e sanificazione dei dati . Gli utenti vorranno inserire tutti i tipi di dati sciatti e sporchi nelle tue tabelle. È MO o Missouri? Femmina, F, donna, ragazza o sì? Lo stipendio è 15,00 l'ora, 50k all'anno o 3.000 una busta paga? È il 31/12/2013, 31/12/2013, 31-12-13, 31 dicembre 2013 o il trentaduemilatredici dicembre?
-
Decidi se vuoi consentire
NULL
o no. Rende le cose più complicate a causa della logica del triplo stato e dovrai verificarlo in seguito. Alcune persone decidono invece di usare solo una stringa vuota. NULLO è più uno stato che un valore reale e significa indefinito o sconosciuto:il valore potrebbe essere qualsiasi cosa. Uso null perché una stringa vuota a volte è un valore valido per un campo. Ad esempio, impostandoMiddle_Initial
uguagliare una stringa vuota potrebbe significare che la persona non ha un'iniziale centrale o potrebbe significare che non sai cosa sia. Per me queste cose sono diverse. Per le altre persone, la differenza non ha importanza. Considera solo i numeri... 0 è uguale a sconosciuto? -
Se non altro, sii coerente.