Eu tenho algumas tabelas onde eu armazeno dados e dependendo do tipo de pessoa (trabalhador, civil) que fez um trabalho que eu quero armazenar em uma event
tabela, agora esses caras resgatam um animal (existe uma animal
tabela).
Finalmente, quero ter uma mesa para armazenar o evento em que um homem (trabalhador, civil) salvou um animal, mas, se eu acrescentasse uma chave estrangeira, ou como saber o id
valor do civil ou trabalhador que fez o trabalho?
Agora, nesse design, eu não sei como relacionar qual pessoa fez o trabalho se, eu tivesse apenas um tipo de pessoa (aka civil), que apenas armazenaria o civil_id
vale em uma person
coluna nesta última tabela ... mas como saber se era civil ou trabalhador, preciso de outra tabela "intermediária"?
Como refletir o design do diagrama a seguir no MySQL?
Detalhes adicionais
Eu modelei da seguinte maneira:
DROP TABLE IF EXISTS `tbl_animal`;
CREATE TABLE `tbl_animal` (
id_animal INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(25) NOT NULL DEFAULT "no name",
specie VARCHAR(10) NOT NULL DEFAULT "Other",
sex CHAR(1) NOT NULL DEFAULT "M",
size VARCHAR(10) NOT NULL DEFAULT "Mini",
edad VARCHAR(10) NOT NULL DEFAULT "Lact",
pelo VARCHAR(5 ) NOT NULL DEFAULT "short",
color VARCHAR(25) NOT NULL DEFAULT "not defined",
ra VARCHAR(25) NOT NULL DEFAULT "not defined",
CONSTRAINT `uc_Info_Animal` UNIQUE (`id_animal`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `tbl_animal` VALUES (1,'no name', 'dog', 'M','Mini','Lact','Long','black','Bobtail');
INSERT INTO `tbl_animal` VALUES (2,'peluchin', 'cat', 'M','Mini','Lact','Long','white','not defined');
INSERT INTO `tbl_animal` VALUES (3,'asechin', 'cat', 'M','Mini','Lact','Corto','orange','not defined');
DROP TABLE IF EXISTS `tbl_person`;
CREATE TABLE `tbl_person` (
type_person VARCHAR(50) NOT NULL primary key
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `tbl_person` (type_person) VALUES ('Worker');
INSERT INTO `tbl_person` (type_person) VALUES ('Civil');
DROP TABLE IF EXISTS `tbl_worker`;
CREATE TABLE `tbl_worker`(
id_worker INTEGER NOT NULL PRIMARY KEY,
type_person VARCHAR(50) NOT NULL ,
name_worker VARCHAR(50) NOT NULL ,
address_worker VARCHAR(40) NOT NULL DEFAULT "not defined",
delegation VARCHAR(40) NOT NULL DEFAULT "not defined",
FOREIGN KEY (type_person) REFERENCES `tbl_person` (type_person),
CONSTRAINT `uc_Info_worker` UNIQUE (`id_worker`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `tbl_worker` VALUES (1,'Worker','N_CEDENTE1', 'DIR Worker 1', 'DEL');
INSERT INTO `tbl_worker` VALUES (2,'Worker','N_worker1', 'DIR Worker 2', 'DEL');
INSERT INTO `tbl_worker` VALUES (3,'Worker','N_worker2', 'address worker','delegation worker');
DROP TABLE IF EXISTS `tbl_civil`;
CREATE TABLE `tbl_civil`(
id_civil INTEGER NOT NULL PRIMARY KEY,
type_person VARCHAR(50) NOT NULL ,
name_civil VARCHAR(50) ,
procedence_civil VARCHAR(40) NOT NULL DEFAULT "Socorrism",
FOREIGN KEY (type_person) REFERENCES `tbl_person` (type_person),
CONSTRAINT `uc_Info_civil` UNIQUE (`id_civil`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `tbl_civil` VALUES (1,'Civil','N_civil1' , 'Socorrism');
CREATE TABLE `tbl_event` (
id_event INTEGER NOT NULL,
id_animal INTEGER NOT NULL,
type_person VARCHAR(50) NOT NULL ,
date_reception DATE DEFAULT '2000-01-01 01:01:01',
FOREIGN KEY (id_animal) REFERENCES `tbl_animal` (id_animal),
FOREIGN KEY (type_person ) REFERENCES `tbl_person` (type_person ),
CONSTRAINT `uc_Info_ficha_primer_ingreso` UNIQUE (`id_animal`,`id_event`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `tbl_event` VALUES (1,1, 'Worker','2013-01-01 01:01:01' );
INSERT INTO `tbl_event` VALUES (2,2, 'Civil','2013-01-01 01:01:01' );
No entanto, existe uma maneira de se livrar dos nulos?
As consultas que tenho são:
SELECT a.*,b.*,z.*
FROM tbl_event a
left JOIN tbl_worker b
ON a.type_person = b.type_person
left JOIN tbl_animal z
ON z.id_animal = a.id_animal ;
SELECT a.*,b.*,z.*
FROM tbl_event a
left JOIN tbl_civil b
ON a.type_person = b.type_person
left JOIN tbl_animal z
ON z.id_animal = a.id_animal ;
Aqui está um sqlfiddle atualizado .
fonte
TYPE_PERSON
quando ela contém apenas uma coluna?Respostas:
Desde que fiz o diagrama, é melhor eu responder;)
Infelizmente, os bancos de dados relacionais atuais não suportam a herança diretamente, portanto, você precisa transformá-la em tabelas "simples". Geralmente, existem três estratégias para fazer isso:
Para saber mais sobre o que isso realmente significa e alguns prós e contras, consulte os links fornecidos no meu post original , mas em poucas palavras o (3) provavelmente deve ser o seu padrão, a menos que você tenha um motivo específico para um dos outros dois. Você pode representar o (3) no banco de dados da seguinte maneira:
Infelizmente, essa estrutura permitirá que você tenha um
person
que não sejacivil
nemworker
(ou seja, você pode instanciar a classe abstrata) e também criará umperson
que seja amboscivil
eworker
. Existem maneiras de aplicar o primeiro no nível do banco de dados e, em um DBMS que suporta restrições diferidas 3, até o último pode ser aplicado no banco de dados, mas este é um dos poucos casos em que o uso da integridade no nível do aplicativo pode ser realmente preferível .1
person
,civil
eworker
neste caso.2
civil
eworker
neste caso (person
é "abstrato").3 O MySQL não.
fonte
civil
eworker
)civil
eworker
. Talvez você tenha perdido a sintaxe da mão curta (apenasREFERENCES
semFOREIGN KEY
)?Não há necessidade de Civil_ID e Worker_ID distintos; apenas continue usando o Person-ID como a chave para todas as três tabelas: Person, Civil e Worker. Adicione uma coluna PersonType a Person com os dois valores "Civil" e "Worker".
Agora, isso representa as duas subclasses CivilClass e WorkerClass da classe base abstrata PersonClass como sub-entidades Civil e Worker da entidade base Person. Você obtém uma boa correspondência entre o modelo de dados no banco de dados e o modelo de objeto no aplicativo.
fonte
civil_id
eworker_id
- eles são a mesma coisa queperson_id
, apenas nomeados de forma diferente - olham para oFK1
marcador (chave estrangeira) na frente deles.Seu caso é uma instância de modelagem de classe / subclasse. Ou, conforme o diagrama em ER, generalização / especialização.
Existem três técnicas que ajudarão você a criar tabelas mysql para cobrir este caso. Eles são chamados de herança de tabela única, herança de tabela de classe e chave primária compartilhada. Você pode lê-los na guia Informações da tag correspondente em SO.
/programming//tags/single-table-inheritance/info
/programming//tags/class-table-inheritance/info
/programming//tags/shared-primary-key/info
A herança de tabela única é útil para casos simples em que a presença de NULLs não causa problemas. A herança da tabela de classes é melhor para casos mais complicados. A chave primária compartilhada é uma boa maneira de impor relacionamentos individuais e acelerar junções.
fonte
Você pode criar uma tabela de tipos de pessoas e adicionar um campo a todas as tabelas que precisam da imposição de tipos. Em seguida, crie chaves estrangeiras. Aqui está um exemplo derivado do seu ...
fonte