นามสกุลของ Null ทำให้เกิดปัญหาในหลายฐานข้อมูลได้อย่างไร


71

ฉันอ่านบทความเกี่ยวกับ BBC หนึ่งในตัวอย่างที่พวกเขากล่าวคือคนที่มีนามสกุล 'Null' กำลังมีปัญหาในการป้อนรายละเอียดในบางเว็บไซต์

ไม่มีคำอธิบายเกี่ยวกับข้อผิดพลาดที่พวกเขาเผชิญ

แต่เท่าที่ฉันรู้สตริง 'Null' และค่า Null จริงนั้นแตกต่างอย่างสิ้นเชิง (จากมุมมองฐานข้อมูล)

เหตุใดจึงทำให้เกิดปัญหาในฐานข้อมูล


2
นี่เป็นบทความบล็อกที่โด่งดังเกี่ยวกับสมมติฐานที่โปรแกรมเมอร์เขียนชื่อเขียนโดยหนึ่งในคนที่อ้างถึงในบทความ BBC ว่า: kalzumeus.com/2010/06/17/…
Jörg W Mittag


2
ดูเพิ่มเติม: stackoverflow.com/questions/4456438/...
Foon

4
ครั้งแรกที่ฉันเห็นผู้ชายคนนี้ในทีวีฉันคิดว่ามันเป็นฐานข้อมูลบั๊ก จากนั้นฉันก็พบว่ามันเป็นชื่อของเขาจริงๆ
Nate Eldredge

3
@JarrodRoberson คุณจะพูดว่า "หลักฐานทั้งหมดเป็นเท็จ" ได้อย่างไรเนื่องจากคำอธิบายของปัญหาที่ต้องเผชิญกับ "Jennifer Null" และชื่อที่คล้ายกันในลิงก์ที่โพสต์ OP มันเป็นปัญหาจริงที่ต้องเผชิญกับผู้ใช้จริง
Steven Burnap

คำตอบ:


102

ไม่ทำให้เกิดปัญหาฐานข้อมูล มันทำให้เกิดปัญหาในการใช้งานที่เขียนโดยนักพัฒนาที่ไม่เข้าใจฐานข้อมูล NULLที่รากของปัญหาก็คือว่าซอฟต์แวร์ฐานข้อมูลที่เกี่ยวข้องกับการแสดงมากบันทึกโมฆะเป็นสตริง เมื่อแอปพลิเคชันนั้นอาศัยรูปแบบสตริงของเร็กคอร์ด NULL (อาจใช้การดำเนินการเปรียบเทียบแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่) แอปพลิเคชันดังกล่าวจะพิจารณาว่า"null"สตริงใดเป็น NULL ดังนั้นชื่อ Null จะถูกพิจารณาว่าไม่มีอยู่ในแอปพลิเคชันนั้น

วิธีแก้ปัญหาคือการประกาศคอลัมน์ที่ไม่เป็นศูนย์เช่นเดียวกับNOT NULLในฐานข้อมูลและไม่ใช้การดำเนินการสตริงกับระเบียนฐานข้อมูล ภาษาส่วนใหญ่มี API ฐานข้อมูลที่ยอดเยี่ยมซึ่งทำให้อินเตอร์เฟสระดับสตริงไม่จำเป็น พวกเขาควรได้รับการแนะนำเสมอเนื่องจากพวกเขาทำผิดพลาดอื่น ๆ เช่นการฉีด SQL จะมีโอกาสน้อยลง


30
อย่างไรก็ตามในกรณีนี้หากคุณอ่านบทความที่เป็นปัญหาการตั้งชื่อนามสกุลNOT NULLจะทำให้เกิดปัญหากับคนอื่น "บางคนมีเพียงชื่อเดียวไม่ใช่ชื่อและนามสกุล"
MikeTheLiar

41
@Darkhogg ผู้คนจำนวนมากไม่เห็นด้วยกับฉันเกี่ยวกับเรื่องนี้ แต่ฉันคิดว่าชื่อเหมือนที่อยู่อีเมล - ไม่ต้องตรวจสอบความถูกต้องของพวกเขาให้ผู้ใช้กล่องข้อความเดียวและให้พวกเขาใส่สิ่งที่พวกเขาต้องการ นี่คือข้อมูลที่ถ้าฉันต้องการจริงๆฉันจะขอจากคุณในแบบที่แน่นอนว่าจะถูกต้อง
MikeTheLiar

8
@mikeTheLiar ฉันไม่ทราบชื่อของสิ่งนี้ แต่มีข้อผิดพลาดทั้งคลาสที่ออกมาจากการสร้างกฎที่เข้มงวดเกินไปเกี่ยวกับข้อมูล บ่อยครั้งที่คุณจะเห็นรหัสไปรษณีย์และหมายเลขโทรศัพท์ที่กำหนดเป็นตัวเลขในแอปพลิเคชันและฐานข้อมูล มันไม่ได้เป็นตัวเลขจริงๆเพราะมันไม่สมเหตุสมผลเลยที่จะทำการคำนวณทางคณิตศาสตร์กับมัน ดังนั้นเมื่อมีคนพยายามป้อนที่อยู่แคนาดาพวกเขาจะติดอยู่
JimmyJames

19
@JimmyJames ใช่รหัสไปรษณีย์ที่เก็บไว้เป็นตัวเลขและทันใดนั้นทุกคนที่อาศัยอยู่ที่นี่มีรหัสไปรษณีย์พื้นฐาน -8 "หากคุณไม่ได้ทำคณิตศาสตร์กับมันมันเป็นสตริง Full Stop"
MikeTheLiar

8
@mikeTheLiar ปัญหาเกี่ยวกับการจัดการชื่อเป็นสายอักขระเดียว (โดยทั่วไปแล้วฉันเห็นด้วย) คือเมื่อมีความต้องการสำหรับการเรียงลำดับตัวอักษรตามนามสกุล
TRiG

13

ในการตอบคำถามเฉพาะของคุณมีหลายขั้นตอนในห่วงโซ่เหตุการณ์ระหว่างเว็บฟอร์มและฐานข้อมูล หากนามสกุลNullถูกตีความอย่างผิด ๆ ว่าเป็นNULLค่าระบบอาจปฏิเสธชื่อที่ถูกต้องสมบูรณ์ว่าไม่ถูกต้อง นี้สามารถเกิดขึ้นที่ชั้นฐานข้อมูลเป็นอธิบายโดยอมร อนึ่งหากนี่เป็นปัญหาที่เฉพาะเจาะจงแล้วฐานข้อมูลก็อาจเปิดให้ฉีด SQL AKA จากการโจมตีของBobby Tables ขั้นตอนในห่วงโซ่ที่อาจจะก่อให้เกิดปัญหาอีกประการหนึ่งคือกระบวนการอันดับ

โดยรวมแล้วบทความเกี่ยวกับปัญหาที่ใหญ่กว่า โลกเป็นสถานที่ที่ยุ่งเหยิงและไม่สอดคล้องกับสมมติฐานของเรา สิ่งนี้ชัดเจนเป็นพิเศษเมื่อคุณพยายามทำให้แอพพลิเคชันของคุณเป็นสากล ในตอนท้ายของวันที่เราต้องให้แน่ใจว่างานของเราจัดการและการเข้ารหัสข้อมูลของเราอย่างถูกต้อง มันขึ้นอยู่กับธุรกิจที่จะตัดสินใจว่าทรัพยากรจำนวนมากที่เราอุทิศเพื่อสนับสนุนกรณีขอบที่ซับซ้อนมากขึ้น ในขณะที่ฉันสนับสนุนการรวมอย่างเต็มที่ฉันจะเข้าใจว่าธุรกิจตัดสินใจว่า "ศิลปินที่รู้จักกันอย่างเป็นทางการว่า Prince" จำเป็นต้องใช้อักขระ Unicode เพื่อแสดงชื่อของเขาในฐานข้อมูลของเราหรือไม่


เป็นการยากที่จะจินตนาการว่าสิ่งนี้เกิดจากการแก้ไขสตริงที่ไม่ปลอดภัยซึ่งสามารถนำไปสู่การฉีด SQL หากคุณลืมอ้างคำพูดของผู้ใช้ในแบบสอบถาม SQL (เช่นINSERT INTO users (first, last) VALUES($first, $last)ประเมินให้INSERT INTO users (first, last) VALUES(Jennifer, Null)) ทุกคนที่มีชื่อไม่ถูกต้องคำหลัก SQL หรือชื่อคอลัมน์เป็นเพียงการโยนข้อผิดพลาดและไม่ได้มีการแทรกบันทึกของพวกเขา สาเหตุต้องมีความซับซ้อนมากขึ้น
Andrew Medico

@AndrewMedico ในตัวอย่างคนฟางของคุณใช่ แต่มีหลายวิธีที่จะทำสิ่งที่ผิด อย่าประมาทพลังของความโง่เขลา <strike> <\ strike> บรรทัดล่างคือเราไม่มีความคิดว่าปัญหาที่เกิดขึ้นจริงเพราะเราไม่สามารถตรวจสอบรหัสที่เป็นปัญหา
Erik

7

ก่อนที่มันจะถูกป้อนลงในฐานข้อมูลมันเป็นองค์ประกอบ DOM จากนั้นตัวแปรจาวาสคริปต์ที่ผ่านการตรวจสอบและจัดการแล้วเป็นค่า JSON จากนั้นตัวแปรในไลบรารี JSON แบ็กเอนด์ที่คุณใช้แล้วตัวแปรผ่านไป ตรวจสอบและจัดการในภาษาการเขียนโปรแกรมแบ็กเอนด์ของคุณจากนั้นองค์ประกอบของ DAO บางส่วนจากนั้นเป็นส่วนหนึ่งของสตริง SQL จากนั้นเพื่อให้ได้ค่ากลับมาคุณก็ทำได้ทั้งหมดในสิ่งที่ตรงกันข้าม นั่นคือสถานที่มากมายสำหรับโปรแกรมเมอร์ที่จะทำผิดพลาดและมักจะเป็นจำนวนมากโดยไม่ได้รับประโยชน์จากการพิมพ์แบบคงที่


2

น่าจะเป็นปัญหาการเขียนโปรแกรม หากคุณดูคำตอบนี้ที่นี่เกี่ยวกับวิธีการส่งผ่าน NULL คุณสามารถทำให้เกิดพฤติกรรมที่ไม่พึงประสงค์ได้อย่างง่ายดายหากคุณเป็น "Mr. Null"

https://stackoverflow.com/questions/4620391/mysql-and-php-insert-null-rather-than-empty-string

คุณจะเห็นว่าถ้าองค์ประกอบข้อมูลบางอย่างถูกส่งผ่านเป็น NULL ข้อมูลจะถูกแก้ไขเป็นฐานข้อมูลเป็นโมฆะในฐานข้อมูล

"NULL"! = ฐานข้อมูล Null

กรณีการใช้งานบางอย่างและพฤติกรรมที่เกี่ยวข้อง ...

สมมติว่านามสกุลถูกทำเครื่องหมายในฐานข้อมูลว่าไม่ใช่ null ตอนนี้เมื่อมีการแทรกข้อมูลจะถูกตีความว่าเป็น NULL และการแทรกล้มเหลว

อีกกรณีหนึ่งสมมติว่านามสกุลเป็นโมฆะในฐานข้อมูล นาย NULL ถูกแทรกและถูกแปลงเป็น DBNull.Value ซึ่งไม่เหมือนกับ "NULL" หลังจากการแทรกเราไม่พบ Mr. Null เพราะนามสกุลของเขาไม่ใช่ "NULL" แต่อันที่จริงแล้วค่าฐานข้อมูลว่างเปล่า

ดังนั้นมันจะเป็น 2 กรณีของปัญหา @Amon ชี้ให้เห็นว่าฐานข้อมูลเองไม่มีปัญหาเกี่ยวกับค่า null แต่ควรเข้าใจว่าการจัดการค่า null ในแต่ละอินสแตนซ์ RDMS จะมีความแตกต่างระหว่างผู้ขายที่แตกต่างกันอย่างไร


"คุณสามารถเห็นได้ว่าถ้าองค์ประกอบข้อมูลบางอย่างถูกส่งผ่านเป็น NULL ข้อมูลจะถูกแก้ไขเป็นฐานข้อมูลว่างในฐานข้อมูล" - คำถาม / คำตอบที่ได้รับคำตอบที่เชื่อมโยงแล้วไม่ปรากฏขึ้นเพื่อแสดงสิ่งนี้?
MrWhite

2

ฉันจะแอตทริบิวต์ปัญหาในการเขียนโปรแกรมเลอะเทอะและการออกแบบที่ไม่ดีของการใช้งานบางอย่างของ SQL "ว่าง" ชื่อควรถูกนำเสนอและตีความด้วยคำพูดเสมอ null, ค่าฐานข้อมูล, ควรถูกแสดงโดยไม่มีเครื่องหมายอัญประกาศ; แต่เมื่อเขียนโค้ด ad-hoc มันง่ายที่จะสอดแทรกเข้าไปในกระบวนทัศน์ "สิ่งที่จะทำ" และยอมรับสิ่งที่เชื่อว่าเป็นสตริงในรูปแบบที่ไม่ได้ยกมา

นี่คือความจริงที่ว่าข้อมูลประเภทอื่นประกอบ; ตัวเลขตัวอย่างเช่นสามารถและเป็นที่ยอมรับในรูปแบบใดรูปแบบหนึ่งเนื่องจากการตีความไม่ชัดเจน


คุณหมายถึงการติดตั้งแอพพลิเคชั่นที่ไม่ดีโดยใช้ SQL ใช่ไหม? การใช้งาน RDBMS อย่างจริงจังนั้นจะไม่มีความเสี่ยงในเรื่องนี้ (เช่นเดียวกับที่ไม่มีแอพพลิเคชั่นที่ร้ายแรง!)
underscore_d

0

ปัญหาพื้นฐานคือว่าคำว่า "null" ถูกนำไปใช้สองแนวคิดฐานข้อมูลที่แตกต่างกันบางครั้งใช้บริบทเพื่อแยกความแตกต่างระหว่างพวกเขา:

  1. บางสิ่งบางอย่างไม่มีคุณค่าที่ทราบ
  2. บางสิ่งบางอย่างไม่มีค่า

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


หากทราบว่าสตริงไม่มีค่าแสดงว่าค่านั้นควรเป็นสตริงว่างไม่ใช่สตริงว่าง
Byron Jones

0

คำตอบที่มีอยู่ส่วนใหญ่มุ่งเน้นไปที่ส่วนที่ไม่ใช่ SQL ของแอปพลิเคชัน แต่อาจมีปัญหาใน SQL เช่นกัน:

หากได้รับคำสั่งให้กรองระเบียนที่นามสกุลของผู้ใช้จะไม่สามารถใช้ได้บางคนที่ไม่เข้าใจ SQL WHERE u.lastname != 'NULL'เป็นอย่างดีอาจจะเขียนตัวกรอง เนื่องจากวิธีการทำงานของ SQL สิ่งนี้จะปรากฏขึ้นเพื่อตรวจสอบว่าu.lastname IS NOT NULL: NULLระเบียนทั้งหมดถูกกรองออก NULLยังไม่ได้บันทึกทั้งหมด

ยกเว้นหลักสูตรสำหรับบันทึกที่u.lastname == 'NULL'แต่อาจไม่มีบันทึกดังกล่าวในระหว่างการทดสอบ

นี้จะกลายเป็นมีแนวโน้มมากขึ้นถ้า SQL ถูกสร้างขึ้นโดยการจัดเรียงของกรอบที่กรอบที่ไม่เปิดเผยวิธีการที่สามารถเข้าถึงได้ง่ายในการตรวจสอบไม่ใช่บางNULL-ness กับพารามิเตอร์และคนสังเกตเห็น "เดี๋ยวก่อนถ้าฉันผ่านในสตริงNULLมัน ทำสิ่งที่ฉันต้องการ!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.