PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Ràng buộc khóa ngoại với một số giá trị cột nằm trong các bảng khác

Bạn đã bỏ qua tất cả các khóa ngoại trên tên sách.

Đó là lý do tại sao tôi trả lời với một bộ định nghĩa bảng nâng cao hoàn chỉnh, đây là về khóa ngoại, phải không? Chắc chắn bạn đã đưa ra một ví dụ rút gọn.

Vấn đề cần giải quyết là các bản ghi trong reading_event_discussion phải về các chủ đề tồn tại trong cuốn sách đó:

drop table book cascade;
drop table book_theme;
drop table reading_event cascade;
drop table reading_event_discussion;

create table book (
    name text primary key -- new, a must because it is FK in reading_event
);
insert into book (name) values ('game of thrones'),('Database design');

create table book_theme (
    bookname  text references book(name), -- new
    themename text
);
insert into book_theme (bookname, themename) values 
  ('game of thrones', 'ambition'), ('game of thrones', 'power');

create table reading_event (
  i        SERIAL primary key, 
  venue    text, 
  bookread text references book(name) -- FK is new
);
insert into reading_event (venue, bookRead) VALUES
  ('Municipal Library', 'game of thrones');  

-- this is the solution: extended reference check
create or replace function themecheck (i integer, th text) returns boolean as $$
    select 
     (th in (select themename from book_theme bt 
       join reading_event re on i=re.i and re.bookRead=bt.bookname))
$$ language sql;

create table reading_event_discussion (
    i integer references reading_event(i), 
    themeDiscussed text check (themecheck (i, themeDiscussed))
);

-- Test statements:
-- just check data
select * from reading_event;
-- this should be ok
insert into reading_event_discussion values (1,'ambition'),(1,'power');
-- this must be refused
insert into reading_event_discussion values (1,'databases');

Vì vậy, giải pháp là viết một hàm kiểm tra tùy chỉnh. Điều này không thể di động đến các hệ thống cơ sở dữ liệu khác.

Người ta có thể viết hàm này bằng một số ngôn ngữ (plpgsql, pltcl, ...), nhưng các hàm SQL có thể được đưa vào trong một truy vấn và có thể nhanh hơn.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách liệt kê Cơ sở dữ liệu và Bảng trong PostgreSQL bằng psql

  2. Khung thực thể Cốt lõi postgresql Ánh xạ loại mảng không hoạt động

  3. Cơ sở dữ liệu ngủ đông và nhiều người thuê sử dụng các lược đồ trong PostgreSQL

  4. Cách định dạng số trong PostgreSQL

  5. Django mô phỏng hành vi kích hoạt cơ sở dữ liệu khi chèn / cập nhật / xóa hàng loạt