ว้าวคำตอบที่ถูกต้อง "ไม่อนุญาตให้มีค่า NULL เมื่อคุณไม่ต้องทำเพราะประสิทธิภาพในการทำงานลดลง" เป็นคำตอบสุดท้าย ฉันจะโหวตมันแล้วทำอย่างละเอียด เมื่อ RDBMS อนุญาตให้ NULLs สำหรับคอลัมน์ที่ไม่กระจัดกระจายคอลัมน์นั้นจะถูกเพิ่มลงในบิตแมปที่ติดตามว่าค่านั้นเป็น NULL สำหรับแต่ละแถวหรือไม่ ดังนั้นโดยการเพิ่มความสามารถของ NULL ให้กับคอลัมน์ในตารางที่คอลัมน์ทั้งหมดไม่อนุญาตให้ NULL คุณกำลังเพิ่มพื้นที่เก็บข้อมูลที่จำเป็นสำหรับการบันทึกตาราง นอกจากนี้คุณต้องการให้ RDBMS อ่านและเขียนลงในบิตแมปลดประสิทธิภาพในการดำเนินการทั้งหมด
นอกจากนี้ในหลาย ๆ กรณีการอนุญาตให้ NULLs แบ่งเป็น 3NF ในขณะที่ฉันไม่ใช่ stickler สำหรับ 3NF เหมือนเพื่อนร่วมงานหลายคนของฉันให้พิจารณาสถานการณ์สมมติต่อไปนี้:
ในตารางบุคคลมีคอลัมน์เรียกว่า DateOfDeath ซึ่งเป็นโมฆะ หากบุคคลนั้นเสียชีวิตมันจะถูกเติมด้วย DateOfDeath ของพวกเขามิฉะนั้นจะถูกปล่อยให้เป็น NULL นอกจากนี้ยังมีคอลัมน์บิตที่ไม่เป็นโมฆะเรียกว่า IsAlive คอลัมน์นี้ถูกตั้งค่าเป็น 1 ถ้าบุคคลนั้นยังมีชีวิตอยู่และ 0 ถ้าบุคคลนั้นตาย กระบวนงานที่เก็บไว้ส่วนใหญ่ใช้คอลัมน์ IsAlive พวกเขาจะดูแลเฉพาะในกรณีที่บุคคลนั้นยังมีชีวิตอยู่ไม่ใช่ DateOfDeath ของพวกเขา
อย่างไรก็ตามคอลัมน์ IsAlive แบ่งการทำให้เป็นมาตรฐานของฐานข้อมูลเนื่องจากเป็นไปได้อย่างสมบูรณ์จาก DateOfDeath แต่เนื่องจาก IsAlive มีสายแข็งใน SPs ส่วนใหญ่โซลูชันที่ตรงไปตรงมาก็คือการทำให้ DateOfDeath ไม่เป็นโมฆะและกำหนดค่าเริ่มต้นให้กับคอลัมน์ในกรณีที่บุคคลนั้นยังคงอยู่ SP ไม่กี่ตัวที่ใช้ DateOfDeath นั้นจะสามารถเขียนใหม่เพื่อตรวจสอบคอลัมน์ IsAlive และให้เกียรติ DateOfDeath เท่านั้นหากบุคคลนั้นไม่อยู่ อีกครั้งเนื่องจาก SP ส่วนใหญ่สนใจเฉพาะ IsAlive (บิต) และไม่ใช่ DateOfDeath (วันที่) โดยใช้รูปแบบนี้จะเพิ่มความเร็วในการเข้าถึงอย่างมาก
สคริปต์ T-SQL ที่มีประโยชน์สำหรับการค้นหาคอลัมน์ที่ไม่มีค่าได้โดยไม่มี NULL ในสกีมาทั้งหมดคือ:
select 'IF NOT EXISTS (SELECT 1 FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ' WHERE ' + QUOTENAME(c.name) + ' IS NULL)
AND (SELECT COUNT(*) FROM ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ') > 1 PRINT ''' + s.name + '.' + t.name + '.' + REPLACE(c.name, '''', '''''') + ''''
from sys.columns c
inner join sys.tables t ON c.object_id = t.object_id
inner join sys.schemas s ON s.schema_id = t.schema_id
where c.is_nullable = 1 AND c.is_computed = 0
order by s.name, t.name, c.name;
หากคุณเรียกใช้สิ่งนี้บนสำเนาของฐานข้อมูลการผลิตของคุณคุณสามารถค้นหานักพัฒนาคอลัมน์ที่ทำเครื่องหมายว่าอนุญาตให้ NULLs ที่ไม่มีค่า NULLs ในทางปฏิบัติ ส่วนใหญ่ของสิ่งเหล่านี้สามารถทำเครื่องหมายเป็นไม่เป็นโมฆะซึ่งจะเป็นการเพิ่มประสิทธิภาพและลดพื้นที่จัดเก็บ
อาจเป็นไปไม่ได้ที่จะกำจัด NULL ทั้งหมดในตารางทั้งหมดและยังคงมีการออกแบบที่สะอาด แต่มีข้อได้เปรียบอย่างมากในการกำจัด NULL ให้ได้มากที่สุด เครื่องมือเพิ่มประสิทธิภาพทำงานได้เร็วขึ้นมากกับข้อมูลนี้และหากคุณสามารถกำจัด NULL ทั้งหมดในตารางคุณสามารถคืนพื้นที่เก็บข้อมูลจำนวนมากได้
ฉันรู้ว่าประสิทธิภาพไม่ใช่สิ่งที่ DBA คิดเกี่ยวกับสิ่งนั้นมากนัก แต่คุณสามารถโยนหน่วยความจำและพลังงานตัวประมวลผลจำนวน จำกัด ได้ในโซลูชันซึ่งเป็นจุดที่คุณจะต้องเริ่มคิดถึงการออกแบบเชิงตรรกะและกายภาพ .
นอกจากนี้โปรดทราบว่านี่เป็นเพียงสำหรับ RDBMS ที่แท้จริงและฉันอ้างอิงส่วนทางเทคนิคของคำตอบของฉันที่อยู่นอก SQL Server T-SQL ที่แสดงรายการเพื่อค้นหาคอลัมน์ที่ไม่มีค่าได้โดยไม่มีค่า null นั้นมาจาก SQL Server