Mam kilka tabel, w których przechowuję dane i w zależności od rodzaju osoby (pracownik, pracownik służby cywilnej), która wykonała zadanie, chcę je przechowywać w event
tabeli, teraz ci faceci ratują zwierzę (jest tam animal
tabela).
Na koniec chcę mieć stolik do przechowywania zdarzenia, w którym facet (pracownik, pracownik służby cywilnej) uratował zwierzę, ale ukłon powinienem dodać klucz obcy lub jak poznać id
wartość pracownika służby cywilnej lub pracownika, który wykonał pracę?
Teraz, w tym projekcie nie wiem, jak powiązać, która osoba wykonała pracę, gdybym miał tylko rodzaj osoby (inaczej cywilnej), tylko przechowałbym civil_id
dolinę w person
kolumnie w tej ostatniej tabeli ... ale jak wiesz, czy był to pracownik cywilny czy pracownik, czy potrzebuję innego „pośredniego” stołu?
Jak odzwierciedlić projekt poniższego diagramu w MySQL?
Dodatkowe Szczegóły
Modelowałem to w następujący sposób:
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' );
Czy jest jednak sposób na pozbycie się zer?
Mam pytania:
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 ;
Oto zaktualizowane narzędzie sqlfiddle .
źródło
TYPE_PERSON
gdy zawiera ona tylko jedną kolumnę?Odpowiedzi:
Odkąd wykonałem schemat, lepiej odpowiem;)
Obecne relacyjne bazy danych niestety nie obsługują bezpośrednio dziedziczenia, dlatego należy przekształcić je w „zwykłe” tabele. Istnieją na ogół 3 strategie:
Aby uzyskać więcej informacji na temat tego, co to właściwie oznacza, a także niektórych zalet i wad, zapoznaj się z linkami podanymi w moim oryginalnym poście , ale w skrócie (3) prawdopodobnie powinno być twoim domyślnym, chyba że masz konkretny powód jednego z dwóch pozostałych. Możesz reprezentować (3) w bazie danych w następujący sposób:
Niestety, ta struktura pozwoli ci mieć coś,
person
co nie jestcivil
aniworker
(tj. Możesz utworzyć instancję klasy abstrakcyjnej), a także pozwoli ci stworzyć coś,person
co jest jednocześniecivil
iworker
. Istnieją sposoby egzekwowania tego pierwszego na poziomie bazy danych, aw systemie DBMS, który obsługuje odroczone ograniczenia 3, nawet ten drugi może być egzekwowany w bazie danych, ale jest to jeden z niewielu przypadków, w których stosowanie integralności na poziomie aplikacji może być rzeczywiście preferowane .1
person
,civil
iworker
w tym przypadku.2
civil
iwworker
tym przypadku (person
jest „abstrakcyjny”).3 Który MySQL nie.
źródło
civil
iworker
)civil
i wworker
. Być może przegapiłeś składnię krótkiej ręki (tylkoREFERENCES
bezFOREIGN KEY
)?Nie ma potrzeby podawania odrębnego identyfikatora_ Civil_ID i identyfikatora_ Worker_ID; po prostu nadal używaj Person-ID jako klucza dla wszystkich trzech tabel: Person, Civil i Worker. Dodaj kolumnę PersonType do Person z dwiema wartościami „Civil” i „Worker”.
To reprezentuje teraz dwie podklasy CivilClass i WorkerClass abstrakcyjnej klasy bazowej PersonClass jako podelementy Civil i Pracownik bazowej osoby Person. Otrzymujesz ładną zgodność między modelem danych w DB a modelem obiektowym w aplikacji.
źródło
civil_id
iworker_id
- są tym samym, coperson_id
inaczej nazwane - spójrz na znajdujący sięFK1
przed nimi znacznik (klucz obcy).Twoja sprawa jest przykładem modelowania klas / podklas. Lub, tak jak to naszkicowałeś w ER, uogólnienie / specjalizacja.
Istnieją trzy techniki, które pomogą Ci zaprojektować tabele mysql na ten przypadek. Nazywa się je dziedziczeniem pojedynczej tabeli, dziedziczeniem tabeli klas i wspólnym kluczem podstawowym. Możesz przeczytać o nich na karcie informacyjnej z odpowiedniego tagu w SO.
/programming//tags/single-table-inheritance/info
/programming//tags/class-table-inheritance/info
/programming//tags/shared-primary-key/info
Dziedziczenie pojedynczej tabeli jest przydatne w prostych przypadkach, w których obecność wartości NULL nie powoduje problemów. Dziedziczenie tabel klas jest lepsze w bardziej skomplikowanych przypadkach. Wspólny klucz podstawowy to dobry sposób na wymuszenie relacji jeden na jeden i przyspieszenie łączenia.
źródło
Możesz utworzyć tabelę typów osób i dodać pole do wszystkich tabel wymagających wymuszania typu. Następnie utwórz klucze obce. Oto przykład pochodzący od twojego ...
źródło