Saya memiliki data besar di mana saya hanya memilih interval data kecil pada suatu waktu sehingga pemilihannya selalu berurutan. Saya mencoba menerapkan PostgreSQL seperti Partial index di MySQL yang ditargetkan untuk keperluan seperti itu. Saya tidak yakin apakah batasan unik parsial sama dengan yang saya inginkan.
Kode dalam PostgreSQL 9.4
CREATE UNIQUE INDEX dir_events
ON events (measurement_id)
USING btree
(eventBody)
WHERE is_active;
Cobalah indeks parsial ypercube di MySQL
CREATE UNIQUE INDEX dir_events
[index_type] -- TODO what here?
ON events (measurement_id, is_active)
[index_type] -- TODO what here?
Bagaimana Anda bisa membuat indeks parsial mirip PostgreSQL di MySQL 5.5 atau serupa?
is_active = TRUE
(atau hanya memiliki satu kolom, PKdir_events
).Jawaban:
Baik MySQL maupun saudara kandung (MariaDB, Drizzle, dll) telah menerapkan indeks parsial.
Apa yang dapat Anda lakukan, dengan batasan ini:
a) membuat indeks sederhana (tidak parsial) pada
(is_active, measurement_id)
. Ini akan digunakan dalam kueri di mana indeks parsial akan. Tentu saja jikais_active
kolomnya 3% Benar dan 97% salah, indeks ini akan jauh lebih besar (dari sebagian indeks). Tetapi masih lebih kecil dari tabel dan berguna untuk pertanyaan ini.Keterbatasan lain adalah indeks tidak dapat
UNIQUE
dengan solusi ini sehingga kendala tidak ditegakkan. Jika indeks dibuat denganUNIQUE
, keunikan akan diberlakukan untuk barisis_active = FALSE
juga. Saya berasumsi Anda tidak menginginkan itu:b1) (variasi sederhana b): tambahkan tabel lain dalam desain Anda, dengan hanya kolom kunci utama
events
dan kunci asingevents
. Tabel ini hanya boleh memiliki baris yangis_active
benar dalam tabel asli (ini akan diberlakukan oleh aplikasi / prosedur Anda). Kueri denganis_active = TRUE
akan diubah untuk bergabung ke tabel itu (alih-alihWHERE
kondisi.)Tidak
UNIQUE
diberlakukan baik dengan solusi ini tetapi kueri hanya akan melakukan gabungan sederhana (ke indeks yang jauh lebih kecil) dan harus cukup efisien:b2) solusi yang lebih kompleks: tambahkan tabel lain dalam desain Anda, dengan hanya kolom kunci utama dari tabel dan
measurement_id
. Seperti pada saran sebelumnya, tabel ini seharusnya hanya memiliki baris-baris yangis_active
benar dalam tabel asli (ini akan diberlakukan juga oleh aplikasi / prosedur Anda). Kemudian gunakan tabel ini sebagai gantinya untuk kueri yang memilikiWHERE is_active = TRUE
dan hanya membutuhkanmeasurement_id
kolom. Jika diperlukan lebih banyak kolomevents
, Anda harusjoin
, seperti sebelumnya.The
UNIQUE
kendala dapat ditegakkan dengan solusi ini. Duplikasimeasurement_id
kolom juga dapat dijamin konsisten (dengan batasan unik ekstraevents
dan kunci asing gabungan):c) mungkin yang paling sederhana: gunakan PostgreSQL. Saya yakin ada paket untuk distribusi Linux Anda. Itu mungkin bukan versi terbaru dari Postgres tetapi indeks parsial ditambahkan pada 7.0 (atau lebih awal?) Sehingga Anda seharusnya tidak memiliki masalah. Plus, saya yakin Anda dapat menginstal versi terbaru di hampir semua distribusi Linux - bahkan dengan sedikit kerumitan. Anda hanya perlu menginstalnya sekali.
sumber
Ini tidak ideal, tetapi jika Anda memiliki validasi di lapangan, Anda bisa membuat perubahan yang membuat nilai tidak valid. Misalnya karakter ilegal, atau angka negatif. Anda dapat melakukan perubahan ini saat menghapus lunak dan Anda tahu itu tidak akan berbenturan dengan nilai yang valid. Anda juga perlu memperhatikan nilai-nilai lunak yang dihapus tidak saling bertabrakan juga.
Dalam 1 kasus, saya memiliki kolom email dengan kendala unik dan id integer autoincrement untuk setiap baris. Pada penghapusan lunak, saya menambahkan "id @", di mana id adalah ID baris unik, sebelum email yang sebenarnya.
@
tidak diperbolehkan dalam email kecuali dikutip, jadi saya tahu tidak ada email yang valid akan berbenturan dengan nilai baru, dan jadi ini tidak akan pernah berbenturan dengan email yang valid. ID integer unik juga menjamin setiap baris yang dihapus akan unik, bahkan jika email yang sama dihapus beberapa kali.Saya tahu ini tidak ideal, tetapi ini adalah cara sederhana untuk mengatasi masalah ini.
CATATAN: Perubahan yang saya sebutkan menambahkan karakter ke bidang unik, jadi saya harus melakukan trik tambahan jika nilai saat ini sudah di / dekat panjang maks. Mereka adalah aplikasi spesifik, jadi tidak layak disebutkan di sini, tetapi berhati-hatilah dan mencari solusi untuk itu juga dan ini adalah cara sederhana untuk mengatasi kehilangan sebagian fitur indeks.
sumber