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

Giá trị NULL cho cột tham chiếu_constraints.unique_constraint_ * trong lược đồ thông tin

Thiết lập thử nghiệm

Bạn giả sử tên ràng buộc test_def_abc_id_fkey , tên mặc định do thiết lập của bạn trong Postgres 11 trở lên. Tuy nhiên, đáng chú ý là các tên mặc định đã được cải thiện cho Postgres 12, trong đó thiết lập tương tự dẫn đến test_def_abc_id_abc_id2_fkey . Ghi chú phát hành cho Postgres 12:

Xem:

db <> fiddle tại đây

Vì vậy, hãy sử dụng tên rõ ràng test_def_abc_fkey đối với ràng buộc FK để tránh nhầm lẫn:

CREATE TABLE test_abc (
  pk  int PRIMARY KEY
, id  int NOT NULL
, id2 int NOT NULL
);

CREATE UNIQUE INDEX test_abc_ids ON test_abc(id,id2);

CREATE TABLE test_def (
  id      int PRIMARY KEY
, abc_id  int
, abc_id2 int
, CONSTRAINT test_def_abc_fkey  -- !
     FOREIGN KEY (abc_id,abc_id2) REFERENCES test_abc(id,id2)
);

hoạt động trong Postgres 9.5 - Postgres 12.
Ngay cả trong Postgres 9.3.
(Tôi đã có ấn tượng sai về một ràng buộc thực tế sẽ được yêu cầu.)

Trả lời

Quan sát của bạn từ việc truy vấn lược đồ thông tin nắm giữ:

SELECT *
FROM   information_schema.referential_constraints
WHERE  constraint_name = 'test_def_abc_fkey';  -- unequivocal name

Chúng tôi nhận được một hàng, nhưng ba trường unique_constraint_catalog , unique_constraint_schemaunique_constraint_nameNULL .

Lời giải thích có vẻ đơn giản. Các cột đó mô tả, như sách hướng dẫn sử dụng:

Nhưng không có UNIQUE ràng buộc , chỉ là UNIQUE chỉ mục . Một UNIQUE ràng buộc được thực hiện bằng cách sử dụng UNIQUE chỉ mục trong Postgres. Các ràng buộc được xác định bởi tiêu chuẩn SQL, các chỉ mục là chi tiết triển khai. Có những khác biệt giống như một trong những bạn đã phát hiện ra. Có liên quan:

Thử nghiệm tương tự với UNIQUE thực tế ràng buộc hiển thị dữ liệu như mong đợi:

db <> fiddle tại đây

Vì vậy, điều này dường như có ý nghĩa. Đặc biệt là vì lược đồ thông tin cũng được xác định bởi ủy ban tiêu chuẩn SQL và các chỉ mục không được tiêu chuẩn hóa, chỉ có các ràng buộc. (Không có thông tin chỉ mục trong các chế độ xem giản đồ thông tin.)

Tất cả rõ ràng? Không hoàn toàn.

Tuy nhiên

Có một chế độ xem giản đồ thông tin khác key_column_usage . Cột cuối cùng của nó được mô tả là:

In đậm nhấn mạnh của tôi. Đây, vị trí thứ tự của cột trong chỉ mục vẫn được liệt kê:

SELECT *
FROM   information_schema.key_column_usage
WHERE  constraint_name = 'test_def_abc_fkey';

Xem:

db <> fiddle tại đây

Có vẻ không nhất quán.

Còn tệ hơn, hướng dẫn sử dụng tuyên bố rằng một PRIMARY KEY thực tế hoặc UNIQUE ràng buộc sẽ được yêu cầu để tạo FOREIGN KEY ràng buộc:

Có vẻ là một lỗi tài liệu ? Nếu không ai có thể chỉ ra nơi tôi làm sai ở đây, tôi sẽ gửi một báo cáo lỗi.

Có liên quan:

Giải pháp

Trong Postgres, danh mục hệ thống là nguồn chân lý thực tế. Xem:

Vì vậy, bạn có thể sử dụng một cái gì đó như thế này (như tôi cũng đã thêm vào fiddle trên):

SELECT c.conname
     , c.conrelid::regclass  AS fk_table, k1.fk_columns
     , c.confrelid::regclass AS ref_table, k2.ref_key_columns
FROM   pg_catalog.pg_constraint c
LEFT   JOIN LATERAL (
   SELECT ARRAY (
      SELECT a.attname
      FROM   pg_catalog.pg_attribute a
           , unnest(c.conkey) WITH ORDINALITY AS k(attnum, ord)
      WHERE  a.attrelid = c.conrelid
      AND    a.attnum = k.attnum
      ORDER  BY k.ord
      ) AS fk_columns
   ) k1 ON true
LEFT   JOIN LATERAL (
   SELECT ARRAY (
      SELECT a.attname
      FROM   pg_catalog.pg_attribute a
           , unnest(c.confkey) WITH ORDINALITY AS k(attnum, ord)
      WHERE  a.attrelid = c.confrelid
      AND    a.attnum = k.attnum
      ORDER  BY k.ord
      ) AS ref_key_columns
   ) k2 ON true
WHERE  conname = 'test_def_abc_fkey';

Lợi nhuận:

conname           | fk_table | fk_columns       | ref_table | ref_key_columns
:---------------- | :------- | :--------------- | :-------- | :--------------
test_def_abc_fkey | test_def | {abc_id,abc_id2} | test_abc  | {id,id2}       

Có liên quan:




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgres mảng json ngày gần đây

  2. Postgresql Nhiều số lượng cho một bảng

  3. Tên bảng động trong postgreSQL 9.3

  4. Mac OSX Lion Postgres không chấp nhận kết nối trên /tmp/.s.PGSQL.5432

  5. Quản lý và tự động hóa PostgreSQL với ClusterControl