J'ai des tableaux où je stocke des données et selon le type de personne (travailleur, civil) qui a fait un travail, je veux le stocker dans une event
table, maintenant ces gars sauvent un animal (il y a une animal
table).
Enfin, je veux avoir une table pour stocker l'événement qu'un gars (travailleur, civil), a sauvé un animal, mais s'incliner dois-je ajouter une clé étrangère ou comment connaître la id
valeur du civil ou du travailleur qui a fait le travail?
Maintenant, dans cette conception, je ne sais pas comment identifier la personne qui a fait le travail si, je n'avais qu'une sorte de personne (alias civile), je ne stockerais le civil_id
val dans une person
colonne dans ce dernier tableau ... mais comment savoir si elle était civile ou ouvrière, ai-je besoin d'une autre table "intermédiaire"?
Comment refléter la conception du diagramme suivant dans MySQL?
Détails supplémentaires
Je l'ai modélisé de la manière suivante:
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' );
Cependant, existe-t-il un moyen de se débarrasser des null?
Les requêtes que j'ai sont:
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 ;
Voici un sqlfiddle mis à jour .
la source
TYPE_PERSON
lorsqu'elle ne contient qu'une seule colonne?Réponses:
Depuis que j'ai fait le schéma, je ferais mieux de répondre;)
Les bases de données relationnelles actuelles ne prennent malheureusement pas directement en charge l'héritage, vous devez donc le transformer en tables "simples". Il existe généralement 3 stratégies pour le faire:
Pour en savoir plus sur ce que cela signifie réellement et certains avantages et inconvénients, veuillez consulter les liens fournis dans mon article d' origine , mais en un mot, le (3) devrait probablement être votre valeur par défaut, sauf si vous avez une raison spécifique pour l'un des deux autres. Vous pouvez représenter le (3) dans la base de données simplement comme ceci:
Malheureusement, cette structure vous permettra d'avoir un
person
qui n'est nicivil
niworker
(c'est-à-dire que vous pouvez instancier la classe abstraite), et vous permettra également de créer unperson
qui est à la foiscivil
etworker
. Il existe des moyens d'appliquer les premiers au niveau de la base de données, et dans un SGBD qui prend en charge les contraintes différées 3, même les derniers peuvent être appliqués dans la base de données, mais c'est l'un des rares cas où l'utilisation de l'intégrité au niveau de l'application pourrait être préférable .1
person
,civil
etworker
dans ce cas.2
civil
etworker
dans ce cas (person
est "abstrait").3 Ce que MySQL ne fait pas.
la source
civil
etworker
)civil
etworker
. Peut-être avez-vous manqué la syntaxe abrégée (justeREFERENCES
sansFOREIGN KEY
)?Il n'y a pas besoin de Civil_ID et Worker_ID distincts; continuez simplement à utiliser Person-ID comme clé pour les trois tables: Person, Civil et Worker. Ajoutez une colonne PersonType à Person avec les deux valeurs "Civil" et "Worker".
Cela représente désormais les deux sous-classes CivilClass et WorkerClass de la classe de base abstraite PersonClass en tant que sous-entités Civil et Worker de l'entité de base Person. Vous obtenez une belle correspondance entre le modèle de données dans la base de données avec le modèle d'objet dans l'application.
la source
civil_id
etworker_id
- c'est la même chose queperson_id
, juste nommé différemment - regardez leFK1
marqueur (clé étrangère) devant eux.Votre cas est une instance de modélisation de classe / sous-classe. Ou, comme vous l'avez schématisé dans ER, généralisation / spécialisation.
Il existe trois techniques qui vous aideront à concevoir des tables mysql pour couvrir ce cas. Ils sont appelés héritage de table unique, héritage de table de classe et clé primaire partagée. Vous pouvez les lire dans l'onglet info de la balise correspondante dans SO.
/programming//tags/single-table-inheritance/info
/programming//tags/class-table-inheritance/info
/programming//tags/shared-primary-key/info
L'héritage de table unique est utile dans les cas simples où la présence de valeurs NULL ne pose pas de problème. L'héritage de table de classe est préférable pour les cas plus compliqués. La clé primaire partagée est un bon moyen d'imposer des relations un-à-un et d'accélérer les jointures.
la source
Vous pouvez créer une table de type de personne et ajouter un champ à toutes les tables nécessitant l'application du type. Créez ensuite des clés étrangères. Voici un exemple dérivant du vôtre ...
la source