Ich habe einige Tabellen, in denen ich Daten speichere, und abhängig von der Art der Person (Arbeiter, Zivilist), die meine Arbeit erledigt hat, möchte ich sie in einer event
Tabelle speichern. Jetzt retten diese Jungs ein Tier (es gibt eine animal
Tabelle).
Schließlich möchte ich einen Tisch zur Aufbewahrung des Ereignisses haben, dass ein Mann (Arbeiter, Zivilist) ein Tier gerettet hat, aber sollte ich einen Fremdschlüssel hinzufügen oder wissen, wie hoch der id
Wert des Zivilisten oder Arbeiters ist, der die Arbeit ausgeführt hat?
Nun, bei diesem Entwurf weiß ich nicht, wie ich sagen soll, welche Person den Job gemacht hat, wenn ich nur eine Art von Person (auch bekannt als bürgerlich) hätte. Ich würde das civil_id
Tal nur in einer person
Spalte in dieser letzten Tabelle aufbewahren ... aber wie Weiß ich, ob es sich um einen Zivil- oder einen Arbeitstisch handelt? Brauche ich einen anderen "Zwischentisch"?
Wie spiegelt sich das Design des folgenden Diagramms in MySQL wider?
Zusätzliche Details
Ich habe es folgendermaßen modelliert:
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' );
Gibt es jedoch eine Möglichkeit, Nullen loszuwerden?
Die Fragen, die ich habe, sind:
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 ;
Hier ist eine aktualisierte SQLFiddle .
quelle
TYPE_PERSON
wenn sie nur eine Spalte enthält?Antworten:
Da ich das Diagramm gemacht habe, antworte ich besser;)
Aktuelle relationale Datenbanken unterstützen die Vererbung leider nicht direkt, daher müssen Sie sie in "einfache" Tabellen umwandeln. Hierfür gibt es im Allgemeinen drei Strategien:
Weitere Informationen zu den tatsächlichen Auswirkungen und Vor- und Nachteilen finden Sie unter den in meinem ursprünglichen Beitrag angegebenen Links. Kurz gesagt sollte (3) jedoch Ihre Standardeinstellung sein, es sei denn, Sie haben einen bestimmten Grund für einen der beiden anderen. Sie können die (3) in der Datenbank einfach so darstellen:
Leider können Sie mit dieser Struktur
person
weder eincivil
noch ein habenworker
(dh Sie können die abstrakte Klasse instanziieren), und Sie können auch ein erstellenperson
, das beidescivil
und istworker
. Es gibt Möglichkeiten , die früheren auf Datenbankebene zu erzwingen, und in einem DBMS , dass Stützen Einschränkungen latenten 3 auch diese können innerhalb der Datenbank erzwungen werden, aber dies ist einer der wenige Fälle , in denen mit der Anwendungsebene Integrität tatsächlich vorzuziehen sein könnten .1
person
,civil
undworker
in diesem Fall.2
civil
undworker
in diesem Fall (person
ist "abstrakt").3 Welche MySQL nicht.
quelle
civil
undworker
)civil
und vorhandenworker
. Vielleicht haben Sie die Kurzschrift-Syntax verpasst (nurREFERENCES
ohneFOREIGN KEY
)?Es ist nicht erforderlich, Civil_ID und Worker_ID zu unterscheiden. Verwenden Sie weiterhin die Personen-ID als Schlüssel für alle drei Tabellen: Person, Civil und Worker. Fügen Sie der Person eine Spalte PersonType mit den beiden Werten "Civil" und "Worker" hinzu.
Dies repräsentiert nun die beiden Unterklassen CivilClass und WorkerClass der abstrakten Basisklasse PersonClass als Unterentitäten Civil und Worker der Basisentität Person. Sie erhalten eine gute Übereinstimmung zwischen dem Datenmodell in der DB und dem Objektmodell in der Anwendung.
quelle
civil_id
undworker_id
- sie sind dasselbe wieperson_id
, nur anders benannt - schauen Sie auf denFK1
(Fremdschlüssel-) Marker vor ihnen.Ihr Fall ist eine Instanz der Klassen- / Unterklassenmodellierung. Oder, wie Sie es in ER dargestellt haben, Generalisierung / Spezialisierung.
Es gibt drei Techniken, die Ihnen beim Entwerfen von MySQL-Tabellen helfen, um diesen Fall abzudecken. Sie heißen Single Table Inheritance, Class Table Inheritance und Shared Primary Key. Sie können sie in der Registerkarte Info vom entsprechenden Tag in SO nachlesen.
/programming//tags/single-table-inheritance/info
/programming//tags/class-table-inheritance/info
/programming//tags/shared-primary-key/info
Die Vererbung einzelner Tabellen ist in einfachen Fällen hilfreich, in denen das Vorhandensein von NULL-Werten keine Probleme verursacht. Die Vererbung von Klassentabellen ist für kompliziertere Fälle besser. Gemeinsamer Primärschlüssel ist ein guter Weg, um Eins-zu-Eins-Beziehungen zu erzwingen und Verknüpfungen zu beschleunigen.
quelle
Sie können eine Personentypentabelle erstellen und ein Feld zu allen Tabellen hinzufügen, für die die Typenerzwingung erforderlich ist. Dann erstellen Sie Fremdschlüssel. Hier ist ein Beispiel aus Ihrer ...
quelle