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

Nilai unik PostgreSQL di beberapa kolom

Sayangnya, ini tidak dapat diselesaikan dengan mudah dengan batasan/indeks unik yang sederhana (jika dapat diselesaikan dengan mereka sama sekali).

Yang Anda butuhkan adalah pengecualian batasan :kemampuan untuk mengecualikan beberapa baris, berdasarkan sesuatu seperti tabrakan . Batasan unik hanyalah batasan pengecualian khusus (berdasarkan persamaan tabrakan ).

Jadi, secara teori, Anda hanya perlu mengecualikan setiap row1 , di mana sudah ada row2 , yang ekspresinya benar:ARRAY[row1.cola, row1.colb] && ARRAY[row2.cola, row2.colb]

Indeks ini bisa melakukan pekerjaan (saat ini hanya gist indeks mendukung batasan pengecualian):

ALTER TABLE table_name
  ADD CONSTRAINT table_name_exclusion
  EXCLUDE USING gist ((ARRAY[cola, colb]) WITH &&);

Tapi sayangnya, tidak ada kelas operator default untuk array (yang menggunakan gist ). Ada intarray modul , yang menyediakan satu hanya untuk integer array, tetapi tidak ada untuk text array.

Jika Anda benar-benar ingin menyelesaikannya, Anda selalu dapat menyalahgunakan range jenis (mis. Saya menggunakan -|- . yang berdekatan operator, yang menangani semua kasus, yang tidak dapat ditangani dengan unique ) ...

-- there is no built-in type for text ranges neither,
-- but it can can be created fairly easily:
CREATE TYPE textrange AS RANGE (
  SUBTYPE = text
);

ALTER TABLE table_name
  ADD CONSTRAINT table_name_exclusion
  EXCLUDE USING gist ((textrange(least(cola, colb), greatest(cola, colb))) WITH -|-);

-- the exclusion constraint above does not handle all situations:

ALTER TABLE table_name
  ADD CONSTRAINT table_name_check
  CHECK (cola is distinct from colb); -- without this, empty ranges could be created,
                                      -- which are not adjacent to any other range

CREATE UNIQUE INDEX table_name_unique
  ON table_name ((ARRAY[least(cola, colb), greatest(cola, colb)]));
     -- without this, duplicated rows could be created,
     -- because ranges are not adjacent to themselves

... tapi saya khawatir, masalah awal Anda dapat diselesaikan dengan lebih mudah dengan sedikit refactoring basis data; yang membawa kita ke pertanyaan:masalah apa, yang ingin Anda selesaikan dengan ini?




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. psql:FATAL:otentikasi kata sandi gagal untuk pengguna windows 8

  2. Cara mencadangkan dan memulihkan database PostgreSQL

  3. Bolehkah kita berinteraksi dengan skrip psql?

  4. Cara membuat Postgres Copy mengabaikan baris pertama file txt besar

  5. Bagaimana cara memeriksa apakah pemicu ada di PostgreSQL?