60

Tôi có 2 bảng như bạn sẽ thấy trong mã posgresql bên dưới. Học sinh bảng đầu tiên có 2 cột, một cho student_name và student_id khác là khóa chính. Trong bảng thứ hai của tôi được gọi là kiểm tra, điều này có 4 cột, một cột cho subject_id, một cho subject_name, sau đó một cho một sinh viên với điểm số cao nhất trong một chủ đề là highStudent_id. đang cố gắng để làm cho higherStudent_id tham khảo student_id trong bảng học sinh của tôi. Đây là mã tôi có bên dưới, không chắc liệu cú pháp có đúng không:cú pháp khóa ngoài bằng postgresql

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

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

là cú pháp highestStudent_id SERIAL REFERENCES students đúng? bởi vì tôi đã thấy một số khác như highestStudent_id REFERENCES students(student_id))

Cách chính xác để tạo khóa ngoại trong postgresql là gì?

+4

Có cú pháp là "đúng". Tuy nhiên, cột FK nên ** không ** được định nghĩa là 'nối tiếp', nó phải được định nghĩa là' số nguyên'. 'serial' không phải là kiểu dữ liệu" thực ", đó là một tay ngắn để điền giá trị mặc định từ chuỗi –

+0

Nếu FK tham chiếu khóa chính, không cần cột nào. Nếu FK tham chiếu một khóa thay thế, các cột là cần thiết. – jarlh

+0

@a_horse_with_no_name bạn có ý nghĩa như thế này: số nguyên cao nhấtSTINENT_id TÀI LIỆU THAM KHẢO Người chơi – Hamza

Trả lời

118

Giả sử bảng này:

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

Có bốn cách khác nhau để xác định một khóa ngoại (khi giao dịch với một PK cột duy nhất) và tất cả đều dẫn đến cùng một ràng buộc khoá ngoại:

  1. Inline mà không nhắc đến cột mục tiêu:

    CREATE TABLE tests 
    ( 
        subject_id SERIAL, 
        subject_name text, 
        highestStudent_id integer REFERENCES students 
    ); 
    
  2. tôi nline với nhắc đến cột mục tiêu:

    CREATE TABLE tests 
    ( 
        subject_id SERIAL, 
        subject_name text, 
        highestStudent_id integer REFERENCES students (student_id) 
    ); 
    
  3. Out of dòng bên trong 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. Như một tuyên bố riêng 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); 
    

Mà một trong những bạn thích là một vấn đề của hương vị. Nhưng bạn nên nhất quán trong kịch bản của bạn. Hai câu lệnh cuối cùng là tùy chọn duy nhất nếu bạn có khóa ngoài tham chiếu một PK bao gồm nhiều cột - bạn không thể xác định FK "nội tuyến" trong trường hợp đó, ví dụ: foreign key (a,b) references foo (x,y)

Chỉ phiên bản 3) và 4) sẽ cho bạn khả năng xác định tên của riêng bạn cho ràng buộc FK nếu bạn không thích hệ thống được tạo từ Postgres.


serial loại dữ liệu không thực sự là loại dữ liệu. Nó chỉ là một ký hiệu ngắn tay xác định giá trị mặc định cho cột được lấy từ một chuỗi. Vì vậy, bất kỳ cột tham khảo một cột định nghĩa là serial phải được xác định bằng cách sử dụng loại thích hợp căn cứ integer (hoặc bigint cho bigserial cột)

+0

cảm ơn bạn đã giải thích chi tiết như vậy. Tôi thực sự đánh giá cao và bây giờ tôi đã rõ ràng về cách thực hiện tham chiếu giữa các bảng của tôi và sử dụng các loại cơ sở phù hợp. thanks @a_horse_with_no_name – Hamza

+7

Ví dụ thứ hai của bạn nên nó là 'integerStudent_id số nguyên THAM KHẢO sinh viên (student_id)' thay vì 'tallStudent_id số nguyên THAM KHẢO sinh viên (id)'? Hoặc là 'id' một số loại viết tắt? – John

Các vấn đề liên quan