Jawaban yang sangat terlambat, tetapi untuk siapa pun yang bertanya-tanya &googling.
YA ini bisa dilakukan, tetapi TIDAK latihan yang baik dan meskipun cukup sederhana, itu mungkin meledak di wajah Anda jika Anda tidak terlalu sadar dengan apa yang Anda lakukan. Tidak disarankan.
Namun, saya bisa melihat kegunaannya. Misalnya, Anda memiliki tabel besar berisi jutaan catatan, dan Anda ingin dalam kasus luar biasa menautkan ke tabel yang tidak dikenal atau beberapa tabel (dalam hal ini sebaiknya banyak ). Dengan beberapa tabel, jika Anda membuat kunci asing untuk semuanya, itu akan menjadi pembengkakan besar dalam ukuran database Anda. Tabel yang tidak diketahui akan dimungkinkan misalnya dalam sistem dukungan teknis, di mana Anda ingin menautkan untuk merekam dalam tabel di mana mungkin ada masalah, dan ini bisa (hampir) semua tabel dalam database, termasuk yang akan datang.
Tentu saja Anda membutuhkan dua bidang untuk ditautkan:bidang kunci asing dan nama tabel yang ditautkan. Sebut saja mereka foreignId
dan linkedTable
linkedTable
bisa berupa enum atau string, sebaiknya enum (ruang lebih sedikit), tetapi itu hanya mungkin jika tabel berbeda yang ingin Anda tautkan, diperbaiki.
Mari kita berikan contoh yang sangat konyol. Anda memiliki tabel pengguna yang sangat besar users
yang beberapa pengguna dapat menambahkan tepat satu kumpulan data pribadi ke profil mereka. Ini bisa tentang hobi, hewan peliharaan, olahraga yang mereka latih atau profesi mereka. Sekarang info ini berbeda dalam keempat kasus. (4 tabel yang mungkin sebenarnya tidak cukup untuk membenarkan struktur ini)
Sekarang katakanlah linkedTable
adalah enum dengan kemungkinan nilai pets
, hobbies
, sports
dan professions
, yang merupakan nama dari empat tabel terstruktur yang berbeda. Katakanlah id
adalah pkey di keempatnya.
Anda bergabung misalnya sebagai berikut:
SELECT * FROM users
LEFT JOIN pets ON linkedTable = 'pets' AND foreignId = pets.id
LEFT JOIN hobbies ON linkedTable = 'hobbies' AND foreignId = hobbies.id
LEFT JOIN sports ON linkedTable = 'sports' AND foreignId = sports.id
LEFT JOIN professions ON linkedTable = 'professions' AND foreignId = professions.id
Ini hanya untuk memberikan lelucon dasar. Karena Anda mungkin hanya memerlukan tautan dalam kasus yang jarang terjadi, kemungkinan besar Anda akan melakukan pencarian dalam bahasa pemrograman Anda, seperti PHP, saat Anda mengulang pengguna (tanpa bergabung).
Ingin mencoba? Anda dapat mencobanya sendiri dengan membangun database pengujian ini (pastikan Anda menggunakan database pengujian):
CREATE TABLE IF NOT EXISTS `users` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(100) NOT NULL ,
`linkedTable` ENUM('pets','hobbies','sports','professions') NULL DEFAULT NULL ,
`foreignId` INT NULL DEFAULT NULL ,
PRIMARY KEY (`id`), INDEX (`linkedTable`)
) ;
CREATE TABLE IF NOT EXISTS `pets` (
`id` INT NOT NULL AUTO_INCREMENT ,
`animalTypeId` INT NOT NULL ,
`name` VARCHAR(100) NOT NULL ,
`colorId` INT NOT NULL ,
PRIMARY KEY (`id`), INDEX (`animalTypeId`), INDEX (`colorId`)
) ;
CREATE TABLE IF NOT EXISTS `hobbies` (
`id` INT NOT NULL AUTO_INCREMENT ,
`hobbyTypeId` INT NOT NULL ,
`hoursPerWeekSpend` INT NOT NULL ,
`websiteUrl` VARCHAR(300) NULL ,
PRIMARY KEY (`id`), INDEX (`hobbyTypeId`)
) ;
CREATE TABLE IF NOT EXISTS `sports` (
`id` INT NOT NULL AUTO_INCREMENT ,
`sportTypeId` INT NOT NULL ,
`hoursPerWeekSpend` INT NOT NULL ,
`nameClub` VARCHAR(100) NULL ,
`professional` TINYINT NOT NULL DEFAULT 0,
PRIMARY KEY (`id`), INDEX (`sportTypeId`)
) ;
CREATE TABLE IF NOT EXISTS `professions` (
`id` INT NOT NULL AUTO_INCREMENT ,
`professionId` INT NOT NULL ,
`hoursPerWeek` INT NOT NULL ,
`nameCompany` VARCHAR(100) NULL ,
`jobDescription` VARCHAR(400) NULL,
PRIMARY KEY (`id`), INDEX (`professionId`)
) ;
INSERT INTO `users` (`id`, `name`, `linkedTable`, `foreignId`)
VALUES
(NULL, 'Hank', 'pets', '1'),
(NULL, 'Peter', 'hobbies', '2'),
(NULL, 'Muhammed', 'professions', '1'),
(NULL, 'Clarice', NULL, NULL),
(NULL, 'Miryam', 'professions', '2'),
(NULL, 'Ming-Lee', 'hobbies', '1'),
(NULL, 'Drakan', NULL, NULL),
(NULL, 'Gertrude', 'sports', '2'),
(NULL, 'Mbase', NULL, NULL);
INSERT INTO `pets` (`id`, `animalTypeId`, `name`, `colorId`)
VALUES (NULL, '1', 'Mimi', '3'), (NULL, '2', 'Tiger', '8');
INSERT INTO `hobbies` (`id`, `hobbyTypeId`, `hoursPerWeekSpend`, `websiteUrl`)
VALUES (NULL, '123', '21', NULL), (NULL, '2', '1', 'http://www.freesoup.org');
INSERT INTO `sports` (`id`, `sportTypeId`, `hoursPerWeekSpend`, `nameClub`, `professional`)
VALUES (NULL, '2', '3', 'Racket to Racket', '0'), (NULL, '12', '34', NULL, '1');
INSERT INTO `professions` (`id`, `professionId`, `hoursPerWeek`, `nameCompany`, `jobDescription`)
VALUES (NULL, '275', '40', 'Ben & Jerry\'s', 'Ice cream designer'), (NULL, '21', '24', 'City of Dublin', 'Garbage collector');
Kemudian jalankan kueri pertama.
Catatan menyenangkan untuk diskusi:Bagaimana dengan Anda indeks ini?