postgresql yabancı anahtar sözdizimi


122

Aşağıdaki posgresql kodumda göreceğiniz gibi 2 tablom var. İlk tablodaki öğrenciler, biri öğrenci_adı ve diğeri de birincil anahtar olan öğrenci_kimliği için 2 sütun içerir. Testler adlı ikinci tablomda, biri konu_kimliği için, biri konu_adı için, sonra da en yüksek Öğrenci_kimliği olan bir konudaki en yüksek puana sahip öğrenci için olmak üzere 4 sütun var. öğrenciler tablomdaki en yüksekStudent_id öğesini öğrenci_kimliği ile ilişkilendirmeye çalışıyorum. Aşağıdaki kod bu, sözdiziminin doğru olup olmadığından emin değilim:

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

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

sözdizimi highestStudent_id SERIAL REFERENCES studentsdoğru mu? çünkü bir tane daha gördümhighestStudent_id REFERENCES students(student_id))

Lütfen postgresql'de yabancı anahtarı oluşturmanın doğru yolu nedir?


4
Evet sözdizimi "doğru". Ancak FK kolon gerekir olup olarak tanımlanabilir serialgibi tanımlanır gerekir integer. serial"gerçek" bir veri türü değil, varsayılan değeri diziden
doldurmak

FK bir birincil anahtara başvurursa, sütun gerekmez. FK alternatif bir anahtara başvurursa, sütunlar gereklidir.
jarlh

1
Yabancı anahtarınız "oyuncular" tablosuna referans veriyor. Sen görünmüyor sahip "Oyuncular" adlı bir tablo.
Mike Sherrill'in 'Cat Recall'

@Mike Sherrill 'Cat Hatırlama Üzgünüm, benim hatam en yüksekÖğrenci_id tamsayısını kastettim REFERANSLAR öğrenciler
Hamza

Yanıtlar:


251

Bu tabloyu varsayarsak:

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

Bir yabancı anahtarı tanımlamanın dört farklı yolu vardır (tek sütun PK ile uğraşırken) ve hepsi aynı yabancı anahtar kısıtlamasına yol açar:

  1. Hedef sütundan bahsetmeden satır içi:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students
    );
  2. Hedef sütundan bahsederek satır içi:

    CREATE TABLE tests 
    ( 
       subject_id SERIAL,
       subject_name text,
       highestStudent_id integer REFERENCES students (student_id)
    );
  3. Çizginin dışında 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. Ayrı bir alter tableifade olarak:

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

Hangisini tercih edeceğiniz bir zevk meselesi. Ancak senaryolarınızda tutarlı olmalısınız. Birden fazla sütundan oluşan bir PK'ye referans veren yabancı anahtarlarınız varsa son iki ifade tek seçenektir - bu durumda FK "satır içi" tanımlayamazsınız, örn.foreign key (a,b) references foo (x,y)

Yalnızca sürüm 3) ve 4), Postgres'ten oluşturulan sistemden hoşlanmıyorsanız, FK kısıtlaması için kendi adınızı tanımlama olanağı sağlar.


serialVeri türü gerçekten veri türü değil. Bir diziden alınan sütun için varsayılan bir değer tanımlayan kısa bir el notasyonudur. Herhangi bir sütun yüzden referans olarak tanımlanan bir sütun serialuygun bir baz türü kullanarak tanımlanması gerekmektedir integer(veya bigintiçin bigserialsütunlar)


Bu bağlantı ( postgresqltutorial.com/postgresql-foreign-key ), yalnızca 3 ve 4'te 'kısıtlama' komutu ile yapılabileceğini söylediğinizi yapmanın başka bir yolunu gösterir. Ayrıca, FOREIGN KEY'i FK'den önce koymaya ne dersiniz? Görünüşe göre bunu yaptığımızda, değişken türünü bildirmemiz gerekmiyor mu?
wordsforthewise
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.