Untuk MySQL yang tidak memiliki indeks filter, Anda bisa melakukan sesuatu seperti berikut ini. Ini mengeksploitasi fakta bahwa MySQL memungkinkan beberapa NULL dalam indeks unik, dan menggunakan tabel khusus dan kunci asing untuk mensimulasikan tipe data yang hanya dapat memiliki NULL dan 1 sebagai nilai.
Dengan solusi ini, alih-alih benar / salah, Anda hanya akan menggunakan 1 / NULL.
CREATE TABLE DefaultFlag (id TINYINT UNSIGNED NOT NULL PRIMARY KEY);
INSERT INTO DefaultFlag (id) VALUES (1);
CREATE TABLE PostalCodes (
ID INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
Zip VARCHAR (32) NOT NULL,
isDefault TINYINT UNSIGNED NULL DEFAULT NULL,
CONSTRAINT FOREIGN KEY (isDefault) REFERENCES DefaultFlag (id),
UNIQUE KEY (isDefault)
);
INSERT INTO PostalCodes (Zip, isDefault) VALUES ('123', 1 );
/* Only one row can be default */
INSERT INTO PostalCodes (Zip, isDefault) VALUES ('abc', 1 );
/* ERROR 1062 (23000): Duplicate entry '1' for key 'isDefault' */
/* MySQL allows multiple NULLs in unique indexes */
INSERT INTO PostalCodes (Zip, isDefault) VALUES ('456', NULL);
INSERT INTO PostalCodes (Zip, isDefault) VALUES ('789', NULL);
/* only NULL and 1 are admitted in isDefault thanks to foreign key */
INSERT INTO PostalCodes (Zip, isDefault) VALUES ('789', 2 );
/* ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`PostalCodes`, CONSTRAINT `PostalCodes_ibfk_1` FOREIGN KEY (`isDefault`) REFERENCES `DefaultFlag` (`id`))*/
Satu-satunya hal yang bisa salah, saya pikir, adalah jika seseorang menambahkan baris ke DefaultFlag
meja. Saya pikir ini bukan masalah besar, dan Anda selalu dapat memperbaikinya dengan izin jika Anda benar-benar ingin aman.
PostalCodes
kosong? Jika suatu baris sudah memiliki properti seharusnya, itu dicegah dari disetel ke false kecuali baris lain (jika ada) disetel ke true dalam pernyataan SQL yang sama? Bisakah nol baris memiliki properti di antara batas-batas transaksi? Haruskah baris terakhir dalam tabel dipaksa untuk memiliki properti dan dicegah agar tidak dihapus? Pengalaman mengatakan kepada saya bahwa "menjamin tepat satu baris" cenderung berarti sesuatu yang berbeda dalam kenyataan, seringkali hanya "paling banyak satu baris".