MySQL có bỏ qua các giá trị null trên các ràng buộc duy nhất không?


Câu trả lời:


422

Có, MySQL cho phép nhiều NULL trong một cột với một ràng buộc duy nhất.

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;

Kết quả:

x
NULL
NULL
1

Điều này không đúng với tất cả các cơ sở dữ liệu. Ví dụ, SQL Server 2005 trở lên chỉ cho phép một giá trị NULL duy nhất trong một cột có ràng buộc duy nhất.


37
nhận xét tuyệt vời về cách nó đúng trong mysql, nhưng không nhất thiết phải nói chung.
dùng2910265

11
Theo SQLite FAQ , hành vi như nhau trong MySQL, PostgreSQL, SQLite, Oracle, và Firebird.
Amir Ali Akbari

4
Hãy cập nhật câu trả lời của bạn. SQLServer 2008+ hoàn toàn cho phép, bạn chỉ cần thêm mệnh đề WHERE ... vào năm 2017, không ai nên có phiên bản cũ hơn 2008 ... stackoverflow.com/questions/767657/
Mathieu Turcotte

tính năng nhỏ này rất khó tìm ra câu trả lời cho việc không yêu cầu thêm cột mới vào cơ sở dữ liệu hoặc nâng cấp MySQL trên một ứng dụng rất cũ. Tôi đã thực sự tìm kiếm một giải pháp như Postgres nơi tôi có thể sử dụng COALESCE nhưng có vẻ như câu trả lời luôn luôn không phải là lỗi mà nó được thiết kế như thế nào. Thậm chí WHERE column IS NOT NULLdường như không làm tôi thất bại vì nó không được hỗ trợ trong phiên bản MySQL của tôi. Bất cứ ai biết nơi tôi có thể nhìn?
newdark-it 20/11/18

1
lưu ý: điều này cũng hoạt động cũng chỉ mục duy nhất có nhiều cột. Vì vậy, nếu bạn muốn các cột a, b và c là duy nhất, bạn vẫn có thể có trong các hàng kép của bảng với null, b, c
Mihai Crăiță

111

Từ các tài liệu :

"một chỉ mục UNIQUE cho phép nhiều giá trị NULL cho các cột có thể chứa NULL"

Điều này áp dụng cho tất cả các công cụ trừ BDB .


3
BDB không còn khả dụng trên các phiên bản mysql hiện tại (bắt đầu từ 5.1.12).
Alim zdemir

1
Thử nghiệm của tôi dường như cho thấy rằng cơ sở dữ liệu Java Derby v10.13.1.1. tương tự chỉ cho phép một null trong một cột có chỉ mục duy nhất.
chrisinmtown

7

Tôi không chắc liệu ban đầu tác giả chỉ hỏi liệu điều này có cho phép các giá trị trùng lặp hay không nếu có một câu hỏi ngụ ý ở đây, "Làm thế nào để cho phép NULLcác giá trị trùng lặp trong khi sử dụng UNIQUE?" Hoặc "Làm thế nào để chỉ cho phép một UNIQUE NULLgiá trị?"

Câu hỏi đã được trả lời, vâng, bạn có thể có NULLcác giá trị trùng lặp trong khi sử dụng UNIQUEchỉ mục.

Vì tôi vấp phải câu trả lời này trong khi tìm kiếm "cách cho phép một UNIQUE NULLgiá trị". Đối với bất kỳ ai khác có thể vấp phải câu hỏi này trong khi làm tương tự, phần còn lại của câu trả lời của tôi là dành cho bạn ...

Trong MySQL, bạn không thể có một UNIQUE NULLgiá trị, tuy nhiên bạn có thể có một UNIQUEgiá trị trống bằng cách chèn với giá trị của chuỗi rỗng.

Cảnh báo: Số và các loại khác ngoài chuỗi có thể mặc định là 0 hoặc giá trị mặc định khác.


1
Ràng buộc không có gì để làm với chỉ số. Trên thực tế, bạn thậm chí sẽ không thể có một hàng với giá trị NULL mặc dù thực tế không có hàng nào khác như vậy.
Pijusn

1
@Pijusn Ý của bạn là "ràng buộc không liên quan gì đến chỉ mục?" Cũng về câu thứ hai của bạn, tôi chưa bao giờ nói rằng bạn có thể có một hàng có giá trị NULL, đó là lý do tại sao tôi đã nói ở đầu bài, rằng đây chỉ là giải pháp nếu anh ta không đặt giá trị null.
bluegman991

Ý tôi là việc thêm phần tử mới thất bại không phải vì UNIQUEràng buộc mà vì NOT NULLràng buộc. Tôi nghĩ rằng câu trả lời này không liên quan đến câu hỏi vì câu hỏi đặc biệt về hành vi của sự UNIQUEràng buộc.
Pijusn

@Pijusn Tôi có bạn. Bạn nói đúng, tôi đã loại bỏ từ ngữ gợi ý khác. Tôi đọc sai câu hỏi. Nhưng tôi tin rằng câu trả lời vẫn có thể hữu ích cho những người dùng vấp phải câu hỏi này như tôi đã làm trong khi cố gắng tìm cách để có một giá trị "không có gì" duy nhất, nhưng lại cho phép khả năng vô hiệu.
bluegman991

1
Tôi thấy câu trả lời này hữu ích. Tuy nhiên, nó cũng được trả lời ở đây . Bài đăng này là kết quả đầu tiên từ tìm kiếm google của tôi, mặc dù câu trả lời này và câu hỏi được liên kết là những gì tôi đang tìm kiếm.
kingledion

5

Tránh các ràng buộc độc đáo nullable. Bạn luôn có thể đặt cột vào một bảng mới, làm cho nó không rỗng và duy nhất và sau đó chỉ điền vào bảng đó khi bạn có giá trị cho nó. Điều này đảm bảo rằng bất kỳ sự phụ thuộc chính nào vào cột có thể được thực thi chính xác và tránh mọi vấn đề có thể gây ra bởi null.


6
Vâng, nhưng những gì bạn đề xuất gần như chính xác những gì mysql làm đằng sau hậu trường. Tại sao phải phát minh lại bánh xe nếu chức năng này được tích hợp?
ProfileTwist

2
Bởi vì đó không phải là SQL hợp lệ. Tôi tin rằng mẹo này sẽ hữu ích cho tất cả những ai muốn (hoặc cần) một thiết kế bất khả tri cơ sở dữ liệu.
Arsen7

@ Arsen7 Điều gì xảy ra nếu bạn có nhiều doanh nghiệp - mỗi doanh nghiệp có nhiều khách hàng. Bạn lưu trữ tất cả doanh nghiệp với địa chỉ email của khách hàng của họ trong một tệp. Vì vậy, bạn không thể làm cho email_address trở nên độc đáo vì các doanh nghiệp khác nhau có thể có cùng một khách hàng. Vì vậy, bạn phải tạo một chỉ mục duy nhất tổng hợp gồm business_id và email_address. Có thể đặt cái này trong một bảng mới - như đã giải thích?
Gerhard Liebenberg 2/215

4
Tôi có một trường hợp cột "email" cần phải là duy nhất HOẶC null. Tôi phải tạo một bảng mới với một cột "email" nếu tôi làm theo lời khuyên của bạn. Dựa vào hành vi cụ thể Mysql này dễ dàng hơn nhiều và kết quả là như nhau. Khách hàng không quan tâm liệu tôi có lưu trữ email trong một bảng mới hay không. Ngoài ra, thiết kế cơ sở dữ liệu là tất cả thường được đánh giá cao. Đối với nhiều dự án, bạn không thể và có thể sẽ không dễ dàng chuyển đổi từ DB này sang DB khác.
conradkleinespel

1
@djmj chắc chắn, nhưng phụ thuộc chức năng rất quan trọng đối với hầu hết mọi người và phiên bản ràng buộc duy nhất không thể hủy bỏ không thực thi các phụ thuộc giống như phiên bản BCNF. Vì vậy, tùy chọn nào nhiều hay ít thực tế có thể phụ thuộc vào sự phụ thuộc nào là quan trọng đối với bạn. Đó là lý do tại sao nó đáng để xem xét việc tạo một bảng mới.
nvogel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.