Saya memiliki beberapa tabel tempat saya menyimpan data dan tergantung pada tipe orang (pekerja, sipil) yang melakukan pekerjaan yang ingin saya simpan dalam sebuah event
tabel, sekarang orang-orang ini menyelamatkan seekor binatang (ada sebuah animal
meja).
Akhirnya, saya ingin memiliki meja untuk menyimpan acara bahwa seorang pria (pekerja, sipil), menyelamatkan seekor hewan, tetapi haluan haruskah saya menambahkan kunci asing atau bagaimana mengetahui id
nilai sipil atau pekerja yang melakukan pekerjaan itu?
Sekarang, dalam desain ini saya tidak tahu bagaimana menghubungkan orang yang melakukan pekerjaan itu jika, saya hanya akan memiliki tipe orang (alias sipil). Saya hanya akan menyimpan civil_id
lembah di person
kolom di tabel terakhir ini ... tetapi bagaimana tahu kalau itu sipil atau pekerja, apakah saya perlu meja "perantara" lainnya?
Bagaimana cara merefleksikan desain diagram berikut ini di MySQL?
Detil tambahan
Saya telah memodelkannya dengan cara berikut:
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' );
Namun, apakah ada cara untuk menghilangkan nol?
Pertanyaan yang saya miliki adalah:
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 ;
Berikut adalah sqlfiddle yang diperbarui .
sumber
TYPE_PERSON
ketika hanya berisi satu kolom?Jawaban:
Karena saya membuat diagram, saya lebih baik menjawab;)
Sayangnya, basis data relasional saat ini tidak mendukung warisan secara langsung, oleh karena itu Anda perlu mengubahnya menjadi tabel "biasa". Secara umum ada 3 strategi untuk melakukannya:
Untuk lebih lanjut tentang apa arti sebenarnya ini dan beberapa pro dan kontra, silakan lihat tautan yang disediakan di posting asli saya , tetapi singkatnya (3) mungkin harus menjadi default Anda kecuali Anda memiliki alasan khusus untuk salah satu dari dua lainnya. Anda dapat mewakili (3) dalam database cukup seperti ini:
Sayangnya, struktur ini akan membiarkan Anda memiliki
person
yang bukancivil
atau tidakworker
(yaitu Anda dapat membuat instance kelas abstrak), dan juga akan membiarkan Anda membuatperson
yang keduanyacivil
danworker
. Ada cara untuk menegakkan yang pertama di tingkat basis data, dan dalam DBMS yang mendukung hambatan yang ditangguhkan 3 bahkan yang terakhir dapat ditegakkan di dalam basis data, tetapi ini adalah salah satu dari sedikit kasus di mana menggunakan integritas tingkat aplikasi mungkin sebenarnya lebih disukai .1
person
,civil
danworker
dalam hal ini.2
civil
danworker
dalam hal ini (person
bersifat "abstrak").3 MySQL mana yang tidak.
sumber
civil
danworker
)civil
danworker
. Mungkin Anda melewatkan sintaks tangan pendek (hanyaREFERENCES
tanpaFOREIGN KEY
)?Tidak perlu untuk Civil_ID dan Worker_ID yang berbeda; terus gunakan Person-ID sebagai kunci untuk ketiga tabel: Person, Sipil, dan Pekerja. Tambahkan kolom PersonType ke Orang dengan dua nilai "Sipil" dan "Pekerja".
Ini sekarang mewakili dua sub-kelas CivilClass dan WorkerClass dari kelas dasar PersonClass sebagai sub-entitas Sipil dan Pekerja dari entitas entitas dasar. Anda mendapatkan korespondensi yang bagus antara model data dalam DB dengan model objek dalam aplikasi.
sumber
civil_id
danworker_id
- mereka adalah hal yang sama sepertiperson_id
, hanya dinamai berbeda - lihatFK1
penanda (kunci asing) di depan mereka.Kasing Anda adalah turunan dari pemodelan kelas / subkelas. Atau, seperti yang telah Anda diagramkan di ER, generalisasi / spesialisasi.
Ada tiga teknik yang akan membantu Anda mendesain tabel mysql untuk membahas kasus ini. Mereka disebut Single Table Inheritance, Class Table Inheritance, dan Shared Primary key. Anda dapat membacanya di tab info dari tag terkait di SO.
/programming//tags/single-table-inheritance/info
/programming//tags/class-table-inheritance/info
/programming//tags/share-primary-key/info
Warisan tabel tunggal berguna untuk kasus-kasus sederhana di mana keberadaan NULLs tidak menyebabkan masalah. Warisan tabel kelas lebih baik untuk kasus yang lebih rumit. Kunci utama bersama adalah cara yang baik untuk menegakkan hubungan satu-ke-satu, dan untuk mempercepat bergabung.
sumber
Anda bisa membuat tabel tipe orang dan menambahkan bidang ke semua tabel yang membutuhkan penegakan tipe. Kemudian buat kunci asing. Berikut adalah contoh yang berasal dari Anda ...
sumber