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 seuemployee
tabela, mas oworks
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 usarCamelCase
, use-o em todos os lugares. Seyou_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 oworks
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 osid
é 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.
- 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 umID
campo que é exclusivo para a linha em cada tabela. A maneira mais fácil de fazer isso é usar umauto_increment
(mysql) ouidentity(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 antigomysql_
classe. Em vez disso, usePDO
ouMySQLi_
. 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 permitirNULL
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, definindoMiddle_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.