Mysql
 sql >> Base de données >  >> RDS >> Mysql

Erreur 1005 dans MySQL (de la syntaxe de clé étrangère ?)

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 le works 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. Si you_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.

  • 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 un auto_increment (mysql) ou identity(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ôt PDO ou MySQLi_ . 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éfinir Middle_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.