web-dev-qa-db-ja.com

postgresql外部キー構文

以下のposgresqlコードでわかるように、2つのテーブルがあります。最初のテーブルの学生には2つの列があり、1つはstudent_name用で、もう1つは主キーであるstudent_idです。 testsという2番目のテーブルには、subject_id、subject_name、thestestStudent_idの科目の最高スコアを持つ学生用の4つの列があります。 studentsStudent_idがstudentsテーブルのstudent_idを参照するようにしています。これは私が以下に持っているコードです、構文が正しいかどうかはわかりません:

CREATE TABLE students ( student_id SERIAL PRIMARY KEY,
                 player_name TEXT);

CREATE TABLE tests ( subject_id SERIAL,
                   subject_name,
                   highestStudent_id SERIAL REFERENCES students);

構文highestStudent_id SERIAL REFERENCES studentsは正しいですか?私はhighestStudent_id REFERENCES students(student_id))のような別のものを見たので

Postgresqlで外部キーを作成する正しい方法は何ですか?

101
Hamza

このテーブルを仮定:

CREATE TABLE students 
( 
  student_id SERIAL PRIMARY KEY,
  player_name TEXT
);

外部キーを定義するには4つの異なる方法があり(単一の列PKを処理する場合)、それらはすべて同じ外部キー制約につながります。

  1. ターゲット列に言及せずにインライン:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students
    );
    
  2. ターゲット列について言及するインライン:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students (student_id)
    );
    
  3. create table内の行外:

    CREATE TABLE tests 
    ( 
      subject_id SERIAL,
      subject_name text,
      highestStudent_id integer, 
      constraint fk_tests_students
         foreign key (highestStudent_id) 
         REFERENCES students (student_id)
    );
    
  4. 別のalter tableステートメントとして:

    CREATE TABLE tests 
    ( 
      subject_id SERIAL,
      subject_name text,
      highestStudent_id integer
    );
    
    alter table tests 
        add constraint fk_tests_students
        foreign key (highestStudent_id) 
        REFERENCES students (student_id);
    

どちらを好むかは好みの問題です。ただし、スクリプトは一貫している必要があります。最後の2つのステートメントは、複数の列で構成されるPKを参照する外部キーがある場合の唯一のオプションです。その場合、FKを「インライン」で定義することはできません。 foreign key (a,b) references foo (x,y)

バージョン3)および4)のみが、Postgresからシステム生成されたものが気に入らない場合に、FK制約に独自の名前を定義する機能を提供します。


serialデータ型は、実際にはデータ型ではありません。これは、シーケンスから取得した列のデフォルト値を定義する簡単な表記法です。したがって、すべての列参照serialとして定義された列は、適切なベース型integer(またはbigint列の場合はbigserial)を使用して定義する必要があります

190