Apakah MySQL mengabaikan nilai nol pada batasan unik?


Jawaban:


422

Ya, MySQL memungkinkan beberapa NULL dalam kolom dengan batasan unik.

CREATE TABLE table1 (x INT NULL UNIQUE);
INSERT table1 VALUES (1);
INSERT table1 VALUES (1);   -- Duplicate entry '1' for key 'x'
INSERT table1 VALUES (NULL);
INSERT table1 VALUES (NULL);
SELECT * FROM table1;

Hasil:

x
NULL
NULL
1

Ini tidak benar untuk semua basis data. SQL Server 2005 dan yang lebih lama, misalnya, hanya memungkinkan nilai NULL tunggal dalam kolom yang memiliki batasan unik.


37
komentar yang sangat baik tentang bagaimana itu benar di mysql, tetapi tidak harus secara umum.
user2910265

11
Menurut SQLite FAQ , perilaku adalah sama di MySQL, PostgreSQL, SQLite, Oracle, dan Firebird.
Amir Ali Akbari

4
Harap perbarui jawaban Anda. SQLServer 2008+ benar-benar memungkinkan untuk itu, Anda hanya perlu menambahkan klausa WHERE ... di 2017, bagaimanapun, tidak ada yang harus menggunakan versi yang lebih tua dari 2008 ... stackoverflow.com/questions/767657/…
Mathieu Turcotte

fitur kecil ini sangat sulit untuk menemukan jawaban yang tidak perlu menambahkan kolom baru ke database atau memutakhirkan MySQL pada aplikasi yang sangat lama. Saya benar-benar mencari solusi seperti Postgres di mana saya dapat menggunakan COALESCE tapi sepertinya jawabannya selalu bukan bug tetapi bagaimana ia dirancang. Bahkan WHERE column IS NOT NULLsepertinya tidak mengecewakan saya karena tidak didukung dalam versi MySQL saya. Adakah yang tahu di mana saya bisa melihat?
newdark-it

1
Catatan: ini juga berfungsi juga indeks unik yang memiliki lebih banyak kolom. Jadi, jika Anda ingin kolom a, b dan c menjadi unik, Anda masih dapat memiliki dalam tabel baris ganda dengan null, b, c
Mihai Crăiță

111

Dari dokumen :

"indeks UNIK memungkinkan beberapa nilai NULL untuk kolom yang dapat berisi NULL"

Ini berlaku untuk semua mesin kecuali BDB .


3
BDB tidak lagi tersedia pada versi mysql saat ini (dimulai dengan 5.1.12).
Alim Özdemir

1
Pengujian saya tampaknya menunjukkan bahwa database Java Derby v10.13.1.1. demikian pula, hanya satu nol di kolom dengan indeks yang unik.
chrisinmtown

7

Saya tidak yakin apakah penulis awalnya hanya bertanya apakah ini memungkinkan nilai duplikat atau apakah ada pertanyaan tersirat di sini yang bertanya, "Bagaimana mengizinkan NULLnilai duplikat saat menggunakan UNIQUE?" Atau "Bagaimana hanya mengizinkan satu UNIQUE NULLnilai?"

Pertanyaan sudah dijawab, ya Anda bisa memiliki NULLnilai duplikat saat menggunakan UNIQUEindeks.

Karena saya menemukan jawaban ini sambil mencari "cara mengizinkan satu UNIQUE NULLnilai." Bagi siapa pun yang mungkin menemukan pertanyaan ini sambil melakukan hal yang sama, sisa jawaban saya adalah untuk Anda ...

Di MySQL Anda tidak dapat memiliki satu UNIQUE NULLnilai, namun Anda dapat memiliki satu UNIQUEnilai kosong dengan memasukkan nilai string kosong.

Peringatan: Numerik dan tipe selain string mungkin default ke 0 atau nilai default lainnya.


1
Batasan tidak ada hubungannya dengan indeks. Bahkan, Anda bahkan tidak akan dapat memiliki satu baris dengan nilai NULL meskipun faktanya tidak ada baris seperti itu.
Pijusn

1
@Pijusn Apa yang Anda maksud dengan "kendala tidak ada hubungannya dengan indeks?" Juga tentang kalimat kedua Anda, saya tidak pernah mengatakan bahwa Anda dapat memiliki baris dengan nilai NULL, itu sebabnya saya nyatakan di awal posting, bahwa ini adalah solusi hanya jika dia tidak menggunakan nilai nol.
bluegman991

Yang saya maksudkan adalah menambahkan elemen baru gagal bukan karena UNIQUEkendala tetapi karena NOT NULLkendala. Saya pikir jawaban ini tidak relevan dengan pertanyaan karena pertanyaannya secara khusus tentang perilaku UNIQUEkendala.
Pijusn

@ Pijusn, saya mengerti. Anda benar, saya telah menghapus kata-kata yang menyarankan sebaliknya. Saya salah membaca pertanyaan. Tapi saya percaya jawabannya masih mungkin berguna bagi pengguna yang menemukan pertanyaan ini seperti yang saya lakukan ketika mencoba menemukan cara untuk memiliki nilai "tidak ada" yang unik, tetapi secara keliru memungkinkan kemampuan nol.
bluegman991

1
Saya menemukan jawaban ini bermanfaat. Namun, itu juga dijawab di sini . Posting ini adalah hasil pertama dari pencarian google saya, meskipun jawaban ini dan pertanyaan terkait adalah apa yang saya cari.
kingledion

5

Hindari batasan unik yang tidak dapat dibatalkan. Anda selalu dapat meletakkan kolom di tabel baru, membuatnya non-null dan unik dan kemudian mengisi tabel itu hanya ketika Anda memiliki nilai untuk itu. Ini memastikan bahwa setiap ketergantungan utama pada kolom dapat ditegakkan dengan benar dan menghindari masalah yang dapat disebabkan oleh nol.


6
Ya, tetapi apa yang Anda usulkan hampir persis seperti yang dilakukan mysql di belakang layar. Mengapa menemukan kembali roda jika fungsi ini ada di dalamnya?
ProfileTwist

2
Karena itu bukan SQL yang valid. Saya percaya bahwa tip ini akan berguna bagi semua yang ingin (atau membutuhkan) desain agnostik database.
Arsen7

@ Arsen7 Bagaimana jika Anda memiliki banyak bisnis - masing-masing dengan banyak klien. Anda menyimpan semua bisnis dengan alamat email klien mereka dalam satu file. Jadi, Anda tidak dapat membuat email_address unik karena bisnis yang berbeda mungkin memiliki klien yang sama. Jadi, Anda harus membuat indeks unik gabungan business_id dan email_address. Apakah mungkin untuk meletakkan ini di tabel baru - seperti yang dijelaskan?
Gerhard Liebenberg

4
Saya memiliki kasus di mana kolom "email" harus unik ATAU null. Saya harus membuat tabel baru dengan satu kolom "email" jika saya mengikuti saran Anda. Mengandalkan perilaku spesifik Mysql ini jauh lebih mudah dan hasilnya sama. Pelanggan tidak peduli apakah saya menyimpan email di tabel baru atau tidak. Juga, desain database agnostik adalah semua untuk sering dilebih-lebihkan. Untuk banyak proyek, Anda tidak bisa dan mungkin tidak akan beralih dari satu DB ke yang lain dengan mudah.
conradkleinespel

1
@ djmj yakin, tetapi dependensi fungsional penting bagi kebanyakan orang dan versi kendala unik yang tidak dapat dibatalkan tidak menegakkan dependensi yang sama dengan versi BCNF. Jadi opsi mana yang lebih atau kurang praktis tergantung pada dependensi mana yang penting bagi Anda. Itu sebabnya perlu mempertimbangkan membuat tabel baru.
nvogel
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.