Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Fehler 1005 in MySQL (von der Fremdschlüsselsyntax?)

Ihre Fehler werden durch eine falsche Fremdschlüsselsyntax verursacht.

Ich denke jedoch, dass Sie ID-Felder verwenden sollten, anstatt Primärschlüssel aus Zeichenfolgen zu erstellen . Es gibt ein paar Probleme mit Ihrer Methode...

  • Dadurch wird es für die DB schwieriger, Tabellen zusammenzufügen, als wenn ein Integer-Feld (ID) zum Verbinden verwendet wird (härter ==mehr Verarbeitungszeit).

  • Es ist gültig, mehrere Personen mit demselben Namen zu haben, auch wenn ein mittlerer Anfangsbuchstabe verwendet wird.

  • Was passiert, wenn Sie den Namen einer Person ändern müssen? Entweder weil es falsch gespeichert wurde oder sie geheiratet haben oder so ... Das bedeutet, dass Sie nicht nur Ihren employee aktualisieren müssen Tabelle, aber der works table und jeder anderen Tabelle, die Sie den Namen als Fremdschlüssel verwendet haben.

Schauen Sie sich das an:http://sqlfiddle.com/#! 2/2dc8c/3/0

Ich habe jeder Tabelle eine Tabellen-ID hinzugefügt . Es ist ein unsigned int , was bedeutet, dass es nicht negativ sein kann (weil das nicht viel Sinn machen würde). Es ist auch auto_increment , was bedeutet, dass jedes Mal, wenn Sie der Tabelle eine Zeile hinzufügen, diese ID automatisch generiert und um 1 erhöht wird.

    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)
      );

Sie würden dieser Tabelle Dinge wie folgt hinzufügen:

    insert into Employee (Employee_ID, LastName, FirstName, MidInitial) 
                   values (null,       'Smith',  'John',    'K');

Der null wird zur automatisch generierten ID. Es wird für jede Zeile eindeutig sein.

Außerdem eine eindeutige Einschränkung bedeutet, dass die Kombination dieser Felder in der Tabelle eindeutig sein muss. Bei einem Unternehmen, das groß genug ist, wette ich jedoch, dass zwei Personen denselben Namen haben werden. Im wirklichen Leben würde ich vorschlagen, diese einzigartige Einschränkung zu entfernen.

Ich habe ähnliche Änderungen an der Firmentabelle vorgenommen...

     create table company(
         company_ID      int unsigned auto_increment primary key,

         company_name    varchar(20),
         city            varchar(10),

         unique (company_name)
    );

Dinge könnten hinzugefügt werden wie:

     insert into company values (null, 'Taco Bell', 'Paris'); 

Also ... für works ....anstatt den vollständigen Namen jeder Person und den vollständigen Firmennamen immer wieder in dieser Tabelle zu speichern, müssen wir jetzt nur noch die IDs speichern.

    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) 
    );

Sie könnten Dinge zu works hinzufügen so:

    insert into Works values (null, 1, 1, '10.00');

Da John Smith unser erster Mitarbeiter war, wäre seine Employee_ID 1. Um dies zu überprüfen, versuchen Sie einfach select * from Employee where FirstName='John' and LastName='Smith' . Taco Bell würde auch company_id =1 erhalten. Durch Einfügen dieser Werte in works , das heißt, John arbeitet jetzt bei Taco Bell.

Ich würde auch vorschlagen, dass Sie Felder wie start_date hinzufügen und end_date und job_title zu Ihrem Arbeitstisch. Und Sie sollten auch besondere Einschränkungen für diese Tabelle berücksichtigen. Menschen können mehr als einmal für dasselbe Unternehmen arbeiten. Sie können auch verschiedene Jobs haben.

Wenn Sie Ihre Daten wieder herausholen möchten, verwenden Sie eine Abfrage wie diese:

  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 

das ist nur eine schicke Art, dies auszudrücken:

  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  

Einige Anmerkungen zu Datenbanksachen...

  • Wählen Sie eine Namenskonvention und halten Sie sich daran! Wenn Sie CamelCase verwenden möchten , verwenden Sie es überall. Wenn you_want_to_use Unterstriche in Ihren Namen, verwenden Sie sie überall. Es gibt unzählige Namenskonventionen zur Auswahl:Attribute (Spalten/Felder) mit dem Tabellennamen voranstellen, gebräuchliche Abkürzungen verwenden (oder nicht), wo Großschreibung verwendet wird (oder nicht) ... das hängt meistens von persönlichen Vorlieben ab, aber da Es gibt Artikel über die Vor- und Nachteile der Verwendung bestimmter. Letzte Anmerkung:_nur weil Sie Leerzeichen in einem Namen verwenden können,__ bedeutet das nicht, dass Sie dies tun sollten. `Almost all` Datenbanken lassen [you use spaces] in Namen, wenn Sie möchten, aber es kann später viele Probleme verursachen.

  • Tabellennamen sollten nicht im Plural stehen. Dies ist ein Lieblingsärgernis von mir und hier ist der Grund:Wir wissen, dass eine Tabelle viele Rekorde enthalten wird ... viele Personen / Personen, viele Mitarbeiter, mehrere Unternehmen, mehrere Einträge jeglicher Art oder Art. Jede Zeile beschreibt nur eine dieser Dinge. Manchmal macht es einfach keinen Sinn, den Namen im Plural zu haben. Andere Male ist es fraglich - wie der works Tisch. Wenn Sie es manchmal im Plural und manchmal im Singular machen, kann es später verwirrend werden. Indem Sie alles einfach in den Singular schreiben, ist es immer noch absolut sinnvoll, und Sie müssen nicht hin und her wechseln oder den genauen Namen nachschlagen, wenn Sie Abfragen schreiben.

  • Datentypen sind wichtig und versuchen Sie, über Tabellen für ähnliche Felder hinweg konsistent zu sein (wie alle id s derselbe Typ; alle booleschen Felder alle Bits oder ganze Zahlen oder was auch immer machen, machen Sie sie einfach gleich). Es gibt verschiedene Größen von Integer-Typen, aus denen Sie wählen können. Denken Sie an Größe, Leistung und was für Ihre Bedürfnisse geeignet ist. Entscheiden Sie, ob Sie wirklich ein nvarchar brauchen oder ob ein varchar in Ordnung ist.

    • Dates sollten nie sein als String gespeichert werden. Verwenden Sie den entsprechenden Datums-, Datetime-, Time- oder Timestamp-Datentyp . Dies wird Ihnen später sehr helfen, wenn Sie es abrufen, vergleichen oder in Berechnungen verwenden müssen. Eine weitere wichtige Entscheidung ist, wie Sie mit Zeitzonen umgehen . Ich speichere gerne alles in UTC und handhabe alle Zeitzonen-Offsets am Frontend, wenn die Informationen dem Benutzer angezeigt werden. Dadurch bleibt alles konsistent und ich muss mir keine Gedanken darüber machen, ob die Zeile basierend auf der Computerzeit meines Benutzers, der Browserzeit des Benutzers, der Zeit meiner Datenbank oder der Zeit des Servers um 18:00 Uhr eingefügt wurde.

  • Fügen Sie eine ID hinzu Feld das ist für die Zeile in jeder Tabelle eindeutig. Der einfachste Weg, dies zu tun, ist die Verwendung eines auto_increment (mysql) oder identity(1,1) (sql server) Feld, damit die Datenbank es für Sie nachverfolgt. Diese Werte können bei Bedarf zurückgesetzt oder neu gesetzt werden.

  • Erfahren Sie, wie Sie Normalisierung verwenden .

  • Erfahren Sie, was Transaktionen sind tun und warum sie wichtig sind ... auch wenn Sie sie nicht verwenden.

  • Erfahren Sie mehr über die verschiedenen Arten von Joins . Dies ist eine der besten Erklärungen ich je gesehen habe. Dabei ist vor allem zu beachten, ob der Join ein äußerer oder innerer Join sein soll.

  • Erfahren Sie mehr über SQL-Injection und noch wichtiger, wie um es zu verhindern (Dieser Link ist für PHP).

  • Wenn Sie PHP verwenden, verwenden Sie nicht das alte mysql_ Klasse. Verwenden Sie stattdessen PDO oder MySQLi_ . Info...

  • Das große Ding bei Datenbanken ist Datenintegrität, -validierung und -bereinigung . Benutzer werden alle Arten von schlampigen, schmutzigen Daten in Ihre Tabellen einfügen wollen. Ist es MO oder Missouri? Weiblich, F, Frau, Mädchen oder ja? Ist das Gehalt 15,00 pro Stunde, 50.000 jährlich oder 3.000 ein Gehaltsscheck? Ist es der 31.12.2013, der 31.12.2013, der 31.12.13, der 31. Dezember 2013 oder der einunddreißigste Dezember zweitausenddreizehn?

  • Entscheiden Sie, ob Sie NULL zulassen möchten oder nicht. Es macht die Dinge wegen der dreifachen Zustandslogik komplizierter und Sie müssen später danach suchen. Einige Leute entscheiden sich dafür, stattdessen einfach einen leeren String zu verwenden. NULL ist eher ein Zustand als ein tatsächlicher Wert und bedeutet undefiniert oder unbekannt - der Wert kann alles sein. Ich verwende null weil ein leerer String manchmal ein gültiger Wert für ein Feld ist. Zum Beispiel das Setzen von Middle_Initial gleich einer leeren Zeichenfolge zu sein, könnte bedeuten, dass die Person keinen mittleren Anfangsbuchstaben hat, oder es könnte bedeuten, dass Sie einfach nicht wissen, was es ist. Für mich sind diese Dinge anders. Für andere Menschen spielt der Unterschied keine Rolle. Denken Sie nur an Zahlen ... ist 0 dasselbe wie unbekannt?

  • Wenn nichts anderes, sei einfach konsequent.