sql >> データベース >  >> RDS >> Mysql

MYSQL-複数のテーブルを参照する1つの列

    非常に遅い答えですが、疑問に思っている人やグーゲルをしている人のために。

    はい これは可能ですが、できません 良い習慣であり、それは非常に単純ですが、おそらくあなたの顔に爆発する 自分が何をしているのかよくわからない場合。推奨されません。

    しかし、私は用途を見ることができます。たとえば、数百万のレコードの大きなテーブルがあり、例外的な場合には、不明なテーブルまたは複数のテーブルにリンクする必要があります(この場合、多くの )。複数のテーブルがある場合、それらすべてに対して外部キーを作成すると、データベースサイズが大幅に増大します。不明なテーブルは、たとえばテクニカルサポートシステムで、問題が発生する可能性のあるテーブルに記録するためにリンクしたい場合に発生する可能性があります。これは、将来のテーブルを含む、データベース内の(ほぼ)すべてのテーブルである可能性があります。

    もちろん、2つが必要です リンク先のフィールド:外部キーフィールドとリンク先のテーブルの名前。それらをforeignIdと呼びましょう およびlinkedTable

    linkedTable 列挙型または文字列、できれば列挙型(スペースが少ない)にすることができますが、これは、リンクするさまざまなテーブルが固定されている場合にのみ可能です。

    非常にばかげた例を挙げましょう。膨大なユーザーテーブルusersがあります そのうちの一部のユーザーは正確に1つを追加できます プロファイルへの個人的なデータセット。これは、趣味、ペット、彼らが練習するスポーツについてである可能性がありますまたは 彼らの職業。現在、この情報は4つのケースすべてで異なります。 (4つの可能なテーブルは実際にはではありません この構造を正当化するのに十分です)

    ここで、linkedTableとしましょう。 可能な値がpetsの列挙型です 、hobbiessports およびprofessions 、4つの異なる構造のテーブルの名前です。 idとしましょう 4つすべてのpkeyです。

    たとえば、次のように参加します。

    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. クエリを使用してSQLServerでテーブルを作成する方法

    2. IDが同じ場合、Laravelは一意を検証します

    3. 日ごとにグループ化された中央値を数える

    4. mysql_real_escape_string()を使用する場合