PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Menyimpan dan membandingkan kombinasi unik

Simpan sebagai array (denormalisasi)

Saya akan mempertimbangkan modul tambahan intarray yang menyediakan fungsi uniq() yang nyaman (dan cepat) dan sort() . Dalam instalasi Postgres modern yang khas, semudah:

CREATE EXTENSION intarray;

Dengan menggunakan ini, CHECK simple sederhana batasan dapat menegakkan naik array dengan berbeda elemen.

CHECK (uniq(sort(cat_arr)) = cat_arr)

Anda dapat tambahan (opsional) memiliki pemicu yang menormalkan nilai array ON INSERT OR UPDATE secara otomatis. Kemudian Anda bisa melewati apa saja array (mungkin tidak disortir dan dengan penipuan) dan semuanya berfungsi. Seperti:

CREATE OR REPLACE FUNCTION trg_search_insup_bef()
  RETURNS trigger AS
$func$
BEGIN
   NEW.cat_arr := uniq(sort(NEW.cat_arr);
   RETURN NEW;
END
$func$ LANGUAGE plpgsql;

CREATE TRIGGER insup_bef
BEFORE INSERT OR UPDATE OF cat_arr ON search
FOR EACH ROW
EXECUTE PROCEDURE trg_search_insup_bef();

Intarray modul tambahan bersifat opsional, ada cara lain:

Tetapi fungsi intarray memberikan kinerja yang unggul.

Lalu Anda cukup membuat UNIQUE kendala pada kolom array untuk menegakkan keunikan seluruh array.

UNIQUE (cat_arr)

Saya menulis lebih banyak tentang keuntungan menggabungkan batasan (sangat ketat dan dapat diandalkan) dengan pemicu (kurang dapat diandalkan tetapi lebih nyaman) dalam jawaban terkait ini hanya dua hari yang lalu:

Jika, untuk setiap kombinasi, yang Anda butuhkan untuk menyimpan per kategori adalah ID (dan tidak ada info tambahan), ini sudah cukup baik.
Namun , integritas referensial tidak mudah dipastikan dengan cara ini. Tidak ada batasan kunci asing untuk elemen array (belum) - seperti didokumentasikan dalam tautan Anda :Jika salah satu kategori dihapus atau Anda mengubah ID, referensi akan rusak ...

Skema yang dinormalisasi

Jika Anda perlu menyimpan lebih banyak atau Anda lebih suka menggunakan skema yang dinormalisasi untuk menegakkan integritas referensial atau karena alasan tertentu, Anda dapat melakukannya juga, dan menambahkan pemicu untuk mengisi tampilan terwujud buatan tangan (tabel redundan) dan menegakkan keunikan dengan cara yang sama:

CREATE TABLE search (
  search_id serial PRIMARY KEY
, ... more columns
);

CREATE TABLE cat (
  cat_id serial PRIMARY KEY
, cat text NOT NULL
);

CREATE TABLE search_cat (
  search_id int REFERENCES search ON DELETE CASCADE
, cat_id    int REFERENCES cat
, PRIMARY KEY (search_id, cat_id)
);

Jawaban terkait (bukan untuk kombinasi unik, tetapi untuk elemen unik) yang menunjukkan pemicu:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apache Spark:Koneksi JDBC tidak berfungsi

  2. Kembalikan id jika ada baris, MASUKKAN sebaliknya

  3. PostgreSQL - Menginstal driver JDBC

  4. SQL Isi tabel dengan data acak

  5. Bagaimana timeofday() Bekerja di PostgreSQL