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

MySQL:マッピングテーブルを理解する

    多対多の関係を使用する場合、これを処理する唯一の現実的な方法は、マッピングテーブルを使用することです。

    教師と生徒がいる学校があるとしましょう。生徒は複数の教師を持つことができ、その逆も可能です。

    したがって、3つのテーブルを作成します

    student
      id unsigned integer auto_increment primary key
      name varchar
    
    teacher
      id unsigned integer auto_increment primary key
      name varchar
    
    link_st
      student_id integer not null
      teacher_id integer not null
      primary key (student_id, teacher_id)
    

    Studentテーブルには1000レコードがあります
    Teacherテーブルには20レコードがあります
    link_stテーブルにはリンクと同じ数のレコードがあります(20x1000ではなく、実際のリンクのみ)。

    選択
    たとえば、使用する教師ごとの生徒:

    SELECT s.name, t.name 
    FROM student
    INNER JOIN link_st l ON (l.student_id = s.id)   <--- first link student to the link-table
    INNER JOIN teacher t ON (l.teacher_id = t.id)   <--- then link teacher to the link table.
    ORDER BY t.id, s.id
    

    通常は、常に内部結合を使用する必要があります ここ。

    リンクを作成する
    教師を生徒に割り当てる場合(またはその逆の場合も同様です) 。あなたがする必要があるのは:

    INSERT INTO link_st (student_id, teacher_id) 
       SELECT s.id, t.id 
       FROM student s 
       INNER JOIN teacher t ON (t.name = 'Jones')
       WHERE s.name = 'kiddo'
    

    これは内部結合の誤用ですが、名前が一意である限り機能します。
    IDがわかっている場合は、もちろん直接挿入できます。
    名前がユニークではありませんが、これは失敗になります 使用しないでください。

    重複リンクを回避する方法
    重複リンクを回避することは非常に重要です。重複リンクがあると、あらゆる種類の悪いことが起こります。
    リンクテーブルへの重複リンクの挿入を防ぎたい場合は、unique<を宣言できます。 / code> リンクのインデックス(推奨)

    ALTER TABLE link_st
      ADD UNIQUE INDEX s_t (student_id, teacher_id); 
    

    または、insertステートメントでチェックを行うこともできます(実際には推奨されませんが、機能します)。

    INSERT INTO link_st (student_id, teacher_id) 
      SELECT s.id, t.id
      FROM student s
      INNER JOIN teacher t ON (t.id = 548)
      LEFT JOIN link_st l ON (l.student_id = s.id AND l.teacher_id = t.id)
      WHERE (s.id = 785) AND (l.id IS NULL)
    

    これは、 if の場合にのみ548、785を選択します そのデータはまだlink_stにありません テーブルであり、そのデータがすでにlink_stにある場合は、何も返しません。したがって、重複する値の挿入は拒否されます。

    テーブルスクールがある場合は、生徒が複数の学校に登録できるかどうか(可能性は低いですが、想定できます)と教師が複数の学校に登録できるかどうかによって異なります。非常に可能です。

    table school
      id unsigned integer auto_increment primary key
      name varchar
    
    table school_members
      id id unsigned integer auto_increment primary key
      school_id integer not null
      member_id integer not null
      is_student boolean not null
    

    次のように、学校のすべての生徒を一覧表示できます。

    SELECT s.name
    FROM school i
    INNER JOIN school_members m ON (i.id = m.school_id)
    INNER JOIN student s ON (s.id = m.member_id AND m.is_student = true)
    


    1. Slony-I2.0.xを最新バージョン2.1.xにアップグレードする

    2. 各グループの上位1行を取得

    3. postgresql戻り値がnullの場合は0を返します

    4. SQLServer-UTF-8エンコーディングでXMLタイプの列を定義する