Tengo algunas tablas donde almaceno datos y, dependiendo del tipo de persona (trabajador, civil) que hizo un trabajo, quiero almacenarlo en una event
tabla, ahora estos tipos rescatan a un animal (hay una animal
tabla).
Finalmente, quiero tener una mesa para almacenar el evento de que un hombre (trabajador, civil), salvó un animal, pero ¿debería agregar una clave foránea o cómo saber el id
valor del civil o trabajador que hizo el trabajo?
Ahora, en este diseño, no sé cómo relacionar qué persona hizo el trabajo si, solo tuviera un tipo de persona (también conocido como civil), solo almacenaría el civil_id
valle en una person
columna en esta última tabla ... pero cómo saber si era civil o trabajador, ¿necesito otra tabla "intermedia"?
¿Cómo reflejar el diseño del siguiente diagrama en MySQL?
Detalles adicionales
Lo he modelado de la siguiente manera:
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' );
Sin embargo, ¿hay alguna manera de deshacerse de los nulos?
Las consultas que tengo son:
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 ;
Aquí hay un sqlfiddle actualizado .
fuente
TYPE_PERSON
cuando solo contiene una columna?Respuestas:
Desde que hice el diagrama, mejor respondo;)
Desafortunadamente, las bases de datos relacionales actuales no admiten la herencia directamente, por lo tanto, debe transformarla en tablas "simples". Generalmente hay 3 estrategias para hacerlo:
Para obtener más información sobre lo que esto realmente significa y algunos pros y contras, consulte los enlaces provistos en mi publicación original , pero en pocas palabras, el (3) probablemente debería ser su valor predeterminado a menos que tenga una razón específica para uno de los otros dos. Puede representar el (3) en la base de datos simplemente así:
Desafortunadamente, esta estructura le permitirá tener un
person
que no es nicivil
tampocoworker
(es decir, puede crear una instancia de la clase abstracta), y también le permitirá crear unperson
que sea amboscivil
yworker
. Hay formas de hacer cumplir la primera en el nivel de la base de datos, y en un DBMS que admite restricciones diferidas 3, incluso la última puede aplicarse en la base de datos, pero este es uno de los pocos casos en los que podría ser preferible utilizar la integridad en el nivel de la aplicación. .1
person
,civil
yworker
en este caso.2
civil
yworker
en este caso (person
es "abstracto").3 Lo que MySQL no tiene.
fuente
civil
yworker
)civil
yworker
. ¿Quizás te perdiste la sintaxis de mano corta (soloREFERENCES
sinFOREIGN KEY
)?No hay necesidad de Civil_ID y Worker_ID distintos; simplemente continúe usando la identificación de persona como clave para las tres tablas: Persona, Civil y Trabajador. Agregue una columna PersonType a Person con los dos valores "Civil" y "Worker".
Esto ahora representa las dos subclases CivilClass y WorkerClass de la clase base abstracta PersonClass como sub-entidades Civil y Worker de la entidad base Person. Obtiene una buena correspondencia entre el modelo de datos en la base de datos con el modelo de objetos en la aplicación.
fuente
civil_id
yworker_id
, son lo mismo queperson_id
, simplemente nombrados de manera diferente, miren elFK1
marcador (clave externa) frente a ellos.Su caso es una instancia de modelado de clase / subclase. O, como lo ha diagramado en ER, generalización / especialización.
Existen tres técnicas que lo ayudarán a diseñar tablas mysql para cubrir este caso. Se denominan herencia de tabla única, herencia de tabla de clase y clave primaria compartida. Puede leerlos en la pestaña de información de la etiqueta correspondiente en SO.
/programming//tags/single-table-inheritance/info
/programming//tags/class-table-inheritance/info
/programming//tags/shared-primary-key/info
La herencia de tabla única es útil para casos simples donde la presencia de NULL no causa problemas. La herencia de la tabla de clase es mejor para casos más complicados. La clave primaria compartida es una buena manera de reforzar las relaciones uno a uno y acelerar las uniones.
fuente
Puede crear una tabla de tipo de persona y agregar un campo a todas las tablas que necesitan la aplicación de tipo. Luego cree claves foráneas. Aquí hay un ejemplo derivado del tuyo ...
fuente