MySQL เพิกเฉยต่อค่าที่ไม่เป็นธรรมกับข้อ จำกัด ที่ไม่ซ้ำกันหรือไม่?


289

ฉันมีคอลัมน์อีเมลที่ฉันต้องการให้เป็นเอกลักษณ์ แต่ฉันต้องการให้มันยอมรับค่าว่าง ฐานข้อมูลของฉันสามารถมีอีเมลที่ไม่มีค่าได้ 2 ฉบับ


คำตอบ:


423

ใช่ MySQL อนุญาตให้ NULL หลายอันในคอลัมน์มีข้อ จำกัด ที่ไม่เหมือนใคร

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;

ผลลัพธ์:

x
NULL
NULL
1

สิ่งนี้ไม่เป็นความจริงสำหรับฐานข้อมูลทั้งหมด ตัวอย่างเช่น SQL Server 2005 และเก่ากว่าอนุญาตให้มีค่า NULL เดียวในคอลัมน์ที่มีข้อ จำกัด ที่ไม่ซ้ำกัน


37
ความคิดเห็นที่ยอดเยี่ยมเกี่ยวกับวิธีการที่เป็นจริงใน mysql แต่ไม่จำเป็นต้องโดยทั่วไป
user2910265

11
ตามคำถามที่พบบ่อยของ SQLiteพฤติกรรมจะเหมือนกันใน MySQL, PostgreSQL, SQLite, Oracle, และ Firebird
Amir Ali Akbari

4
โปรดอัปเดตคำตอบของคุณ SQLServer 2008+ ช่วยให้คุณสามารถเพิ่ม WHERE clause ... ในปี 2017 ไม่มีใครควรอยู่ในเวอร์ชั่นที่เก่ากว่า 2008 ต่อไป ... stackoverflow.com/questions/767657/
Mathieu Turcotte

ฟีเจอร์เล็ก ๆ น้อย ๆ นี้เป็นเรื่องยากมากที่จะหาคำตอบที่ไม่ต้องการเพิ่มคอลัมน์ใหม่ในฐานข้อมูลหรืออัพเกรด MySQL ในแอปพลิเคชันที่เก่ามาก ฉันกำลังมองหาวิธีแก้ปัญหาอย่าง Postgres ที่ฉันสามารถใช้ COALESCE ได้ แต่ดูเหมือนว่าคำตอบมักจะไม่ใช่ข้อผิดพลาดที่ออกแบบมา ไม่ได้WHERE column IS NOT NULLดูเหมือนจะล้มเหลวฉันเป็นมันไม่ได้รับการสนับสนุนในรุ่นของฉัน MySQL ใครรู้ว่าฉันสามารถดูได้ที่ไหน
newdark-it

1
หมายเหตุ: วิธีนี้ใช้งานได้กับดัชนีเฉพาะที่มีคอลัมน์มากขึ้น ดังนั้นหากคุณต้องการให้คอลัมน์ a, b และ c เป็นเอกลักษณ์คุณยังสามารถมีในแถวสองแถวที่มีค่า null, b, c
Mihai Crăiță

111

จากเอกสาร :

"ดัชนี UNIQUE อนุญาตให้มีค่า NULL หลายค่าสำหรับคอลัมน์ที่สามารถมีค่า NULL"

นี้ใช้กับเครื่องยนต์ แต่BDB


3
BDB ไม่สามารถใช้ได้กับเวอร์ชัน mysql ปัจจุบัน (เริ่มต้นด้วย 5.1.12)
Alim Özdemir

1
การทดสอบของฉันดูเหมือนว่าแสดงว่าฐานข้อมูล Java Derby v10.13.1.1 ในทำนองเดียวกันอนุญาตเพียงหนึ่ง null ในคอลัมน์ที่มีดัชนีที่ไม่ซ้ำกัน
chrisinmtown

7

ฉันไม่แน่ใจว่าในตอนแรกผู้เขียนเพิ่งถามว่าสิ่งนี้อนุญาตให้มีค่าซ้ำกันหรือไม่หากมีคำถามโดยนัยที่นี่ถามว่า "จะอนุญาตNULLค่าที่ซ้ำกันในขณะใช้งานได้UNIQUEอย่างไร" หรือ "จะอนุญาตเพียงหนึ่งUNIQUE NULLค่าได้อย่างไร"

ตอบคำถามแล้วใช่คุณสามารถมีNULLค่าซ้ำกันในขณะที่ใช้UNIQUEดัชนี

เนื่องจากฉันสะดุดกับคำตอบนี้ในขณะที่ค้นหา "วิธีอนุญาตหนึ่งUNIQUE NULLค่า" สำหรับคนอื่นที่อาจสะดุดกับคำถามนี้ในขณะที่ทำเช่นเดียวกันคำตอบที่เหลือของฉันสำหรับคุณ ...

ใน MySQL คุณไม่สามารถมีUNIQUE NULLค่าหนึ่งค่าได้ แต่คุณสามารถมีUNIQUEค่าว่างได้หนึ่งค่าโดยการแทรกด้วยค่าสตริงว่าง

คำเตือน: ตัวเลขและชนิดอื่นที่ไม่ใช่สตริงอาจเป็นค่าเริ่มต้นเป็น 0 หรือค่าเริ่มต้นอื่น


1
ข้อ จำกัด ไม่มีอะไรเกี่ยวข้องกับดัชนี ในความเป็นจริงคุณจะไม่สามารถมีแถวเดียวที่มีค่า NULL ได้แม้ว่าจะไม่มีแถวอื่น ๆ
Pijusn

1
@Pijusn คุณหมายถึงอะไรโดย "ข้อ จำกัด ไม่มีส่วนเกี่ยวข้องกับดัชนี" เกี่ยวกับประโยคที่สองของคุณฉันไม่เคยบอกว่าคุณสามารถมีแถวที่มีค่า NULL ได้นั่นคือเหตุผลที่ฉันระบุไว้ที่จุดเริ่มต้นของการโพสต์ว่านี่เป็นวิธีแก้ปัญหาเฉพาะเมื่อเขาไม่ได้ตั้งค่าโดยใช้ค่า Null
bluegman991

สิ่งที่ฉันหมายถึงคือการเพิ่มองค์ประกอบใหม่ไม่ได้เกิดจากUNIQUEข้อ จำกัด แต่เนื่องมาจากNOT NULLข้อ จำกัด ฉันคิดว่าคำตอบนี้ไม่เกี่ยวข้องกับคำถามเพราะคำถามนั้นเกี่ยวกับพฤติกรรมของUNIQUEข้อ จำกัด
Pijusn

@Pijusn ฉันได้รับคุณ คุณพูดถูกฉันได้ลบข้อความที่แนะนำเป็นอย่างอื่น ฉันอ่านคำถามผิด แต่ฉันเชื่อว่าคำตอบอาจยังมีประโยชน์สำหรับผู้ใช้ที่สะดุดกับคำถามนี้เหมือนที่ฉันทำในขณะที่พยายามหาวิธีที่จะมีค่า "ไม่มีอะไร" ที่ไม่เหมือนใคร
bluegman991

1
ฉันพบคำตอบนี้มีประโยชน์ แต่มันก็ยังตอบที่นี่ โพสต์นี้เป็นผลลัพธ์แรกจากการค้นหา google ของฉันแม้ว่าคำตอบนี้และคำถามที่เชื่อมโยงเป็นสิ่งที่ฉันกำลังมองหา
kingledion

5

หลีกเลี่ยงข้อ จำกัด ที่ไม่ซ้ำกันแบบ nullable คุณสามารถวางคอลัมน์ในตารางใหม่ทำให้มันไม่เป็นโมฆะและไม่ซ้ำกันแล้วเติมตารางนั้นเฉพาะเมื่อคุณมีค่า สิ่งนี้ทำให้มั่นใจได้ว่าการพึ่งพาคีย์ใด ๆ ในคอลัมน์สามารถบังคับใช้ได้อย่างถูกต้องและหลีกเลี่ยงปัญหาใด ๆ ที่อาจเกิดจากค่า Null


6
ใช่ แต่สิ่งที่คุณเสนอนั้นเกือบจะเป็นสิ่งที่ mysql ทำอยู่เบื้องหลัง ทำไมต้องคิดค้นล้อใหม่หากฟังก์ชันนี้สร้างขึ้นภายใน
ProfileTwist

2
เพราะมันไม่ถูกต้อง SQL ฉันเชื่อว่าเคล็ดลับนี้จะเป็นประโยชน์สำหรับทุกคนที่ต้องการ (หรือต้องการ) การออกแบบฐานข้อมูลไม่เชื่อเรื่องพระเจ้า
Arsen7

@ Arsen7 จะเกิดอะไรขึ้นถ้าคุณมีธุรกิจหลายแห่ง - แต่ละแห่งมีลูกค้าหลายราย คุณเก็บธุรกิจทั้งหมดด้วยที่อยู่อีเมลของลูกค้าในไฟล์เดียว ดังนั้นคุณจึงไม่สามารถสร้างอีเมลที่ไม่เหมือนใครเพราะธุรกิจที่แตกต่างกันอาจมีลูกค้ารายเดียวกัน ดังนั้นคุณต้องสร้างดัชนีเฉพาะของ business_id และ email_address เป็นไปได้หรือไม่ที่จะใส่ลงในตารางใหม่ - ตามที่อธิบายไว้?
Gerhard Liebenberg

4
ฉันมีกรณีที่คอลัมน์ "อีเมล" ต้องไม่ซ้ำกันหรือไม่มีค่า ฉันจะต้องสร้างตารางใหม่ที่มีคอลัมน์ "อีเมล" เดียวหากฉันต้องทำตามคำแนะนำของคุณ การใช้งานพฤติกรรมเฉพาะของ Mysql นี้นั้นง่ายกว่ามากและผลลัพธ์ก็เหมือนกัน ลูกค้าไม่สนใจว่าฉันจะเก็บอีเมลไว้ในตารางใหม่หรือไม่ นอกจากนี้การออกแบบผู้ไม่เชื่อเรื่องพระเจ้าฐานข้อมูลก็มักจะ overrated สำหรับโครงการจำนวนมากคุณทำไม่ได้และอาจจะไม่เปลี่ยนจากฐานข้อมูลหนึ่งไปสู่อีกโครงการหนึ่งที่ง่ายดาย
conradkleinespel

1
@djmj แน่ใจว่า แต่การพึ่งพาการทำงานมีความสำคัญต่อคนส่วนใหญ่และเวอร์ชันข้อ จำกัด ที่ไม่ซ้ำกันซึ่งไม่สามารถใช้ได้นั้นไม่บังคับใช้การพึ่งพาเช่นเดียวกับเวอร์ชัน BCNF ดังนั้นตัวเลือกใดที่ใช้ประโยชน์ได้มากกว่าหรือน้อยกว่านั้นขึ้นอยู่กับว่าการพึ่งพาใดมีความสำคัญต่อคุณ นั่นเป็นเหตุผลว่าทำไมจึงควรพิจารณาสร้างตารางใหม่
nvogel
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.