Kendala kolom khusus ubahsuaian, hanya diberlakukan jika satu kolom memiliki nilai tertentu

19

Apakah mungkin untuk memiliki batasan kolom unik khusus sebagai berikut? Misalkan saya memiliki dua cols, subsetdan type, kedua string (meskipun tipe data mungkin tidak masalah).

Jika type"benar", maka saya ingin kombinasi typedan subsetmenjadi unik. Kalau tidak, tidak ada kendala. Saya menggunakan PostgreSQL 8.4 di Debian.

Faheem Mitha
sumber

Jawaban:

31

Dengan kata lain, Anda ingin subsetmenjadi unik jika type = 'true'.
Sebuah indeks yang unik parsial akan melakukannya:

CREATE UNIQUE INDEX tbl_some_name_idx ON tbl (subset) WHERE type = 'true';

Dengan cara ini Anda bahkan dapat membuat kombinasi dengan NULLunik, yang tidak mungkin sebaliknya - seperti yang dijabarkan dalam jawaban terkait ini:
PostgreSQL batasan unik multi-kolom dan nilai NULL

Erwin Brandstetter
sumber
Terima kasih, Erwin. Saya tidak melihat opsi ini ketika saya melihat dokumentasi. Tautan yang lebih langsung adalah postgresql.org/docs/current/interactive/indexes-partial.html . Lihat Contoh 11-3.
Faheem Mitha
@FaheemMitha: saya terhubung satu tingkat lebih tinggi, karena Anda perlu menggabungkan sebuah indeks parsial dengan indeks yang unik .
Erwin Brandstetter
1
@ Erwin Halaman itu (tentang indeks parsial), memiliki contoh dengan indeks unik parsial.
ypercubeᵀᴹ
@perperan: Ah, benar. Itu tautan yang lebih baik. Saya mengubah jawaban saya untuk menunjuk pada bab terakhir.
Erwin Brandstetter
6

Ini adalah tambahan untuk jawaban Erwin di atas, tetapi PostgreSQL mendukung banyak jenis indeks. Ini umumnya tidak saling eksklusif. Anda dapat menganggap ini sebagai:

  • Metode indeks (btree, GiST, GIN, dll). Pilih satu, jika perlu (btree menjadi default)
  • Sebagian atau penuh. Jika sebagian menggunakan klausa di mana
  • Langsung atau fungsional. Anda dapat mengindeks output fungsi.
  • Unik atau tidak unik

Ini semua dapat digabungkan dengan berbagai cara. Semua yang Anda lakukan di sini adalah menggunakan fitur unik dan parsial, sehingga memberi Anda sebagian indeks unik (yang sangat berguna saat Anda mengetahuinya.

Tapi misalkan Anda ingin memiliki indeks case sensitif pada bidang bagian di mana jenisnya benar. Maka Anda akan menambahkan definisi fungsional:

CREATE INDEX my_index_name_idx_u ON tbl (lower(subset)) WHERE type;

Catatan ini membuat indeks unik pada output dari fungsi lower () yang dipanggil pada atribut subset di mana tipenya benar.

Chris Travers
sumber
Jadi indeks dalam jawaban Erwin langsung, sedangkan yang di contoh Anda dalam fungsional, benar?
Faheem Mitha
@FaheemMitha: Benar.
Erwin Brandstetter