Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

MYSQL - Satu Kolom Direferensikan ke Beberapa Tabel

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?



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mysql pilih rekursif dapatkan semua anak dengan beberapa level

  2. Penggunaan UNION dan ORDER BY yang salah?

  3. Jalankan pemicu prosedur tersimpan di SqlFiddle. Mysql

  4. Hapus alamat web dari string teks

  5. Tidak Dapat Menjatuhkan kunci asing di MySQL