Mysql
 sql >> база данни >  >> RDS >> Mysql

MYSQL - Една колона, препратка към множество таблици

Много късен отговор, но за всеки, който се чуди и търси в гугъл.

ДА това може да се направи, но еНЕ добра практика и въпреки че е доста проста, вероятно ще взриви в лицето ви ако не сте много наясно какво правите. Не се препоръчва.

Въпреки това виждам употреби. Например, имате голяма таблица с милиони записи и искате в изключителни случаи да се свържете с неизвестни или множество таблици (в този случай е по-добре да е много ). С множество таблици, ако направите външен ключ за всички тях, това би било огромно раздуване на размера на вашата база данни. Неизвестна таблица би била възможна например в система за техническа поддръжка, където искате да свържете за запис в таблица, където може да има проблем, и това може да са (почти) всички таблици в базата данни, включително бъдещите.

Разбира се ще ви трябватдва полета за свързване:поле за външен ключ и името на таблицата, към която се свързва. Нека ги наречем foreignId и linkedTable

linkedTable може да бъде enum или низ, за ​​предпочитане enum (по-малко място), но това е възможно само ако различните таблици, към които искате да свържете, са фиксирани.

Нека дадем един изключително глупав пример. Имате огромна потребителска таблица users от които някой потребител може да добави точно един личен набор от данни към техния профил. Това може да се отнася за хоби, домашен любимец, спорт, който практикуват или тяхната професия. Сега тази информация е различна и в четирите случая. (4 възможни таблици в действителност не достатъчно, за да оправдае тази структура)

Сега да кажем linkedTable е enum с възможни стойности pets , hobbies , sports и professions , които са имената на четири различно структурирани таблици. Да кажем id е ключът и в четирите.

Присъединявате се например по следния начин:

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

Това е само за основна шега. Тъй като вероятно се нуждаете от връзката само в редки случаи, по-вероятно ще направите търсене на вашия език за програмиране, като PHP, когато преглеждате потребителите (без присъединяване).

Искате ли да опитате? Можете да опитате сами, като създадете тази тестова база данни (уверете се, че използвате тестова база данни):

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');

След това изпълнете първата заявка.

Забавна бележка за обсъждане:Как би вие индексира ли това?



  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 create с PHP

  2. Как да инсталирате MySQLdb на Mountain Lion

  3. Има ли прост начин в моето приложение ASP.NET програмно да разберете дали mysql db сървърът не работи?

  4. Как да се показват бирмански знаци на уебсайта и да се записват в MySQL, ако потребителят няма шрифта?

  5. Открийте дали стойността е число в MySQL