Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Erro 1005 no MySQL (da sintaxe de chave estrangeira?)


Seus erros são causados ​​devido à sintaxe incorreta da chave estrangeira.



No entanto, acho que você deve usar campos de ID em vez de fazer chaves primárias compostas de string . Existem alguns problemas com o seu método...

  • Isso tornará mais difícil para o banco de dados unir tabelas em comparação com o uso de um campo inteiro (ID) para unir (mais difícil ==mais tempo de processamento).

  • É válido ter várias pessoas com o mesmo nome, mesmo usando a inicial do meio.

  • O que acontece se você precisar alterar o nome de alguém? Ou porque foi armazenado errado ou eles se casaram ou algo assim... Isso significa que você terá que não apenas atualizar seu employee tabela, mas o works table e qualquer outra tabela que você usou o nome como chave estrangeira.

Dê uma olhada nisso:http://sqlfiddle.com/#! 2/2dc8c/3/0

Adicionei um ID de tabela a cada tabela . É um unsigned int , o que significa que não pode ser negativo (porque isso não faria muito sentido). Também é auto_increment , o que significa que sempre que você adicionar uma linha à tabela, esse ID será gerado automaticamente e aumentará em 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)
      );

Você adicionaria coisas a esta tabela assim:
    insert into Employee (Employee_ID, LastName, FirstName, MidInitial) 
                   values (null,       'Smith',  'John',    'K');

O null se tornará o ID gerado automaticamente. Será único para cada linha.

Além disso, uma restrição exclusiva significa que a combinação desses campos deve ser exclusiva na tabela. No entanto, com uma empresa grande o suficiente, aposto que duas pessoas terão o mesmo nome. Na vida real, sugiro remover essa restrição única.

Fiz alterações semelhantes na tabela da empresa...
     create table company(
         company_ID      int unsigned auto_increment primary key,

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

         unique (company_name)
    );

Coisas podem ser adicionadas como:
     insert into company values (null, 'Taco Bell', 'Paris'); 

Então... para works .... em vez de armazenar o nome completo de cada pessoa e o nome completo da empresa repetidamente nesta tabela, agora só temos que armazenar os IDs.
    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) 
    );

Você pode adicionar coisas ao works assim:
    insert into Works values (null, 1, 1, '10.00');

Como John Smith foi nosso primeiro funcionário, seu Employee_ID seria 1. Para verificar isso, tente select * from Employee where FirstName='John' and LastName='Smith' . Taco Bell também obteria company_id =1. Ao inserir esses valores em works , isso significa que John agora trabalha na Taco Bell.

Também sugiro que você adicione campos como start_date e end_date e job_title à sua mesa de trabalho. E você também deve prestar atenção especial a quaisquer restrições exclusivas para essa tabela. As pessoas podem trabalhar para a mesma empresa mais de uma vez. Eles também podem ter empregos diferentes.

Quando você quiser recuperar seus dados, use uma consulta como esta:
  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 

que é apenas uma maneira elegante de dizer isso:
  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  

Algumas notas sobre coisas de banco de dados...

  • Escolha uma convenção de nomenclatura e cumpra-a! Se você quiser usar CamelCase , use-o em todos os lugares. Se you_want_to_use sublinhados em seus nomes, use-os em todos os lugares. Existem várias convenções de nomenclatura para escolher:prefixar atributos (colunas/campos) com o nome da tabela, usar abreviações comuns (ou não), onde a capitalização é usada (ou não)... são artigos por aí sobre os prós e contras sobre o uso de determinados. Última nota, _só porque você pode usar espaços em um nome,__ não significa que você deva. `Almost all` bancos de dados permitem [you use spaces] em nomes, se você quiser, mas pode causar muitos problemas mais tarde.

  • Os nomes das tabelas não devem estar no plural. Este é um problema meu e aqui está o porquê:Sabemos que uma tabela conterá muitos registros... muitas pessoas/pessoas, muitos funcionários, várias empresas, várias entradas de qualquer tipo ou tipo. Cada linha descreve apenas um dessas coisas. Às vezes, nem faz sentido ter o nome no plural. Outras vezes, é questionável - como o works tabela. Se você às vezes o torna plural e às vezes o singular, pode ficar confuso mais tarde. Ao tornar tudo no singular, ainda faz todo o sentido e você não está alternando ou tendo que procurar o nome exato ao escrever consultas.

  • Os tipos de dados são importantes e tente ser consistente nas tabelas para campos semelhantes (como todos os id é o mesmo tipo; faça todos os campos booleanos todos os bits ou inteiros ou qualquer outra coisa, apenas faça-os iguais). Existem diferentes tamanhos de tipos inteiros que você pode escolher. Pense no tamanho, no desempenho e no que é apropriado para suas necessidades. Decida se você realmente precisa de um nvarchar ou se um varchar está bem.
    • As datas devem nunca ser armazenado como uma string. Use o tipo de dados apropriado de data, data e hora, hora ou carimbo de data/hora . Isso o ajudará muito mais tarde, quando você precisar recuperá-lo, compará-lo ou usá-lo em cálculos. Outra decisão importante é como você escolheu lidar com fusos horários . Eu gosto de armazenar tudo em UTC e lidar com qualquer deslocamento de fuso horário no front-end, quando a informação é apresentada ao usuário. Isso mantém tudo consistente e não preciso me preocupar se a linha foi inserida às 18h com base no horário do computador do meu usuário, no horário do navegador do usuário, no horário do meu banco de dados ou no horário do servidor.


  • Incluir um ID campo que é exclusivo para a linha em cada tabela. A maneira mais fácil de fazer isso é usar um auto_increment (mysql) ou identity(1,1) (sql server) para que o banco de dados o rastreie para você. Esses valores podem ser redefinidos ou propagados novamente, se necessário.

  • Aprenda a usar a normalização .

  • Saiba quais transações fazer e por que eles são importantes... mesmo que você não os use.

  • Saiba mais sobre os diferentes tipos de junções . Esta é uma das melhores explicações eu já vi. A principal coisa a se prestar atenção é se a junção deve ser uma junção externa ou interna.

  • Saiba mais sobre SQL Injection e, mais importante, como para prevenir (esse link é para PHP).

  • Se você estiver usando PHP, não use o antigo mysql_ classe. Em vez disso, use PDO ou MySQLi_ . Informações...

  • A grande vantagem dos bancos de dados é a integridade, validação e sanitização dos dados . Os usuários vão querer colocar todos os tipos de dados desleixados e sujos em suas tabelas. É MO ou Missouri? Feminino, F, mulher, menina, ou sim? O salário é 15,00 por hora, 50k anualmente ou 3.000 um contracheque? É 31/12/2013, 31/12/2013, 31-12-13, 31 de dezembro de 2013 ou trinta e cinco de dezembro de dois mil e treze?

  • Decida se você deseja permitir NULL ou não. Isso torna as coisas mais complicadas por causa da lógica de estado triplo e você precisará verificar isso mais tarde. Algumas pessoas decidem usar apenas uma string vazia. NULO é mais um estado do que um valor real e significa indefinido ou desconhecido - o valor pode ser qualquer coisa. Eu uso null porque uma string vazia às vezes é um valor válido para um campo. Por exemplo, definindo Middle_Initial igualar uma string vazia pode significar que a pessoa não tem uma inicial do meio ou pode significar que você simplesmente não sabe o que é. Para mim, essas coisas são diferentes. Para outras pessoas, a diferença não importa. Apenas considere os números... 0 é o mesmo que desconhecido?

  • Se nada mais, apenas seja consistente.