Mysql
 sql >> Database >  >> RDS >> Mysql

Errore 1005 in MySQL (dalla sintassi della chiave esterna?)

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 il works 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. Se you_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.

  • Includi un ID campo che è unico per la riga in ogni tabella. Il modo più semplice per farlo è usare un auto_increment (mysql) o identity(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, usa PDO o MySQLi_ . 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, impostando Middle_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.