Vos erreurs sont dues à une syntaxe de clé étrangère incorrecte.
Cependant, je pense que vous devriez utiliser des champs d'ID au lieu de faire des clés primaires composées de chaînes . Il y a quelques problèmes avec votre méthode...
-
Il sera plus difficile pour la base de données de joindre des tables par rapport à l'utilisation d'un champ entier (ID) pour joindre (plus difficile ==plus de temps de traitement).
-
Il est valide d'avoir plusieurs personnes avec le même nom, même en utilisant une initiale du milieu.
-
Que se passe-t-il si vous devez changer le nom de quelqu'un ? Soit parce qu'il a été mal stocké, soit parce qu'ils se sont mariés ou quoi que ce soit... Cela signifie que vous devrez non seulement mettre à jour votre
employee
table, mais leworks
table et toute autre table dont vous avez utilisé le nom comme clé étrangère.
Jetez un œil à ceci :http://sqlfiddle.com/# ! 2/2dc8c/3/0
J'ai ajouté un ID de table à chaque table . C'est un unsigned int
, ce qui signifie qu'il ne peut pas être négatif (car cela n'aurait pas beaucoup de sens). C'est aussi auto_increment
, ce qui signifie qu'à chaque fois que vous ajouterez une ligne au tableau, cet ID sera généré automatiquement et augmentera de 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)
);
Vous ajouteriez des éléments à ce tableau comme ceci :
insert into Employee (Employee_ID, LastName, FirstName, MidInitial)
values (null, 'Smith', 'John', 'K');
Le null
deviendra l'identifiant généré automatiquement. Il sera unique pour chaque ligne.
Aussi, une contrainte unique signifie que la combinaison de ces champs doit être unique dans la table. Cependant, avec une entreprise assez grande, je parie que deux personnes porteront le même nom. Dans la vraie vie, je suggérerais de supprimer cette contrainte unique.
J'ai apporté des modifications similaires à la table de l'entreprise...
create table company(
company_ID int unsigned auto_increment primary key,
company_name varchar(20),
city varchar(10),
unique (company_name)
);
Des choses pourraient être ajoutées comme :
insert into company values (null, 'Taco Bell', 'Paris');
Alors... pour works
.... au lieu de stocker le nom complet de chaque personne et le nom complet de l'entreprise encore et encore dans ce tableau, nous n'avons plus qu'à stocker les identifiants.
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)
);
Vous pouvez ajouter des choses à works
comme ceci :
insert into Works values (null, 1, 1, '10.00');
Puisque John Smith était notre premier employé, son Employee_ID serait 1. Pour vérifier cela, essayez simplement select * from Employee where FirstName='John' and LastName='Smith'
. Taco Bell obtiendrait également company_id =1. En insérant ces valeurs dans works
, cela signifie que John travaille maintenant chez Taco Bell.
Je vous suggère également d'ajouter des champs comme start_date
et end_date
et job_title
à votre table de travail. Et vous voudriez également accorder une attention particulière à toute contrainte unique pour cette table. Les gens peuvent travailler pour la même entreprise plus d'une fois. Ils peuvent aussi avoir des emplois différents.
Lorsque vous souhaitez récupérer vos données, vous utiliserez une requête comme celle-ci :
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
ce qui est juste une façon élégante de dire ceci :
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
Quelques notes sur les bases de données...
-
Choisissez une convention de dénomination et respectez-la ! Si vous souhaitez utiliser
CamelCase
, utilisez-le partout. Siyou_want_to_use
soulignements dans vos noms, utilisez-les partout. Il y a des tonnes de conventions de nommage parmi lesquelles choisir :préfixer les attributs (colonnes/champs) avec le nom de la table, utiliser des abréviations courantes (ou non), où la majuscule est utilisée (ou non)... cela se résume principalement à des préférences personnelles, mais il sont des articles là-bas sur les avantages et les inconvénients de l'utilisation de certains. Dernière note, _juste parce que vous pouvez utiliser des espaces dans un nom,__ ne signifie pas que vous devriez.`Almost all`
les bases de données laissent[you use spaces]
dans les noms si vous le souhaitez, mais cela peut causer beaucoup de problèmes plus tard. -
Les noms de table ne doivent pas être au pluriel. C'est une de mes bêtes noires et voici pourquoi :nous savons qu'un tableau contiendra de nombreux enregistrements... de nombreuses personnes/personnes, de nombreux employés, plusieurs entreprises, plusieurs entrées de quelque type que ce soit. Chaque ligne n'en décrit qu'une de ces choses. Parfois, cela n'a même pas de sens d'avoir le nom au pluriel. D'autres fois, c'est discutable - comme le
works
table. Si vous le faites parfois au pluriel et parfois au singulier, cela peut devenir déroutant plus tard. En faisant simplement tout cela au singulier, cela reste parfaitement logique, et vous n'allez pas et ne devez pas rechercher le nom exact lorsque vous écrivez des requêtes. -
Les types de données sont importants et essayez d'être cohérent entre les tables pour des champs similaires (comme tous les
id
s du même type ; faites que tous les champs booléens soient tous des bits ou des entiers ou quoi que ce soit, rendez-les simplement identiques). Vous pouvez choisir parmi différentes tailles de types entiers. Pensez à la taille, aux performances et à ce qui convient à vos besoins. Décidez si vous avez vraiment besoin d'un nvarchar ou si un varchar est correct.- Les rendez-vous ne doivent jamais être stocké sous forme de chaîne. Utilisez le type de données date, datetime, time ou timestamp approprié . Cela vous aidera beaucoup plus tard lorsque vous aurez besoin de le récupérer, de le comparer ou de l'utiliser dans des calculs. Une autre décision importante concerne la façon dont vous avez choisi de gérer les fuseaux horaires . J'aime tout stocker en UTC et gérer tous les éléments de décalage de fuseau horaire sur le front-end, lorsque les informations sont présentées à l'utilisateur. Cela permet de garder tout cohérent et je n'ai pas à me soucier de savoir si la ligne a été insérée à 18 heures en fonction de l'heure de l'ordinateur de mon utilisateur, de l'heure du navigateur de l'utilisateur, de l'heure de ma base de données ou de l'heure du serveur.
- Les rendez-vous ne doivent jamais être stocké sous forme de chaîne. Utilisez le type de données date, datetime, time ou timestamp approprié . Cela vous aidera beaucoup plus tard lorsque vous aurez besoin de le récupérer, de le comparer ou de l'utiliser dans des calculs. Une autre décision importante concerne la façon dont vous avez choisi de gérer les fuseaux horaires . J'aime tout stocker en UTC et gérer tous les éléments de décalage de fuseau horaire sur le front-end, lorsque les informations sont présentées à l'utilisateur. Cela permet de garder tout cohérent et je n'ai pas à me soucier de savoir si la ligne a été insérée à 18 heures en fonction de l'heure de l'ordinateur de mon utilisateur, de l'heure du navigateur de l'utilisateur, de l'heure de ma base de données ou de l'heure du serveur.
-
Inclure un
ID
champ qui est unique pour la ligne de chaque table. La façon la plus simple de le faire est d'utiliser unauto_increment
(mysql) ouidentity(1,1)
(sql server) afin que la base de données en garde la trace pour vous. Ces valeurs peuvent être réinitialisées ou réinitialisées si vous en avez besoin. -
Apprenez à utiliser normalisation .
-
Découvrez les transactions faire et pourquoi ils sont importants... même si vous ne les utilisez pas.
-
En savoir plus sur les différents types de jointures . C'est l'une des meilleures explications J'ai jamais vu. La principale chose à laquelle il faut faire attention est de savoir si la jointure doit être une jointure externe ou interne.
-
En savoir plus sur Injection SQL et plus important encore, comment pour l'empêcher (ce lien est pour PHP).
-
Si vous utilisez PHP, n'utilisez pas l'ancien
mysql_
classer. Utilisez plutôtPDO
ouMySQLi_
. Infos... -
La grande chose à propos des bases de données est l'intégrité, la validation et le nettoyage des données . Les utilisateurs voudront mettre toutes sortes de données bâclées et sales dans vos tables. Est-ce MO ou Missouri ? Femme, F, femme, fille ou oui ? Le salaire est-il de 15,00 heures, 50 000 par an ou 3 000 par chèque de paie ? Est-ce le 31/12/2013, le 31/12/2013, le 31/12/13, le 31 décembre 2013 ou le trente et un décembre deux mille treize ?
-
Décidez si vous voulez autoriser
NULL
ou non. Cela rend les choses plus compliquées à cause de la logique à trois états et vous devrez vérifier cela plus tard. Certaines personnes décident d'utiliser simplement une chaîne vide à la place. NULL est plus un état qu'une valeur réelle et cela signifie indéfini ou inconnu - la valeur peut être n'importe quoi. J'utilise null car une chaîne vide est parfois une valeur valide pour un champ. Par exemple, définirMiddle_Initial
être égal à une chaîne vide peut signifier que la personne n'a pas d'initiale ou que vous ne savez tout simplement pas ce que c'est. Pour moi, ces choses sont différentes. Pour les autres, la différence n'a pas d'importance. Considérez simplement les nombres ... est-ce que 0 est identique à inconnu? -
Si rien d'autre, soyez cohérent.