Làm thế nào một họ của Null gây ra vấn đề trong nhiều cơ sở dữ liệu?


71

Tôi đọc một bài viết trên BBC. Một trong những ví dụ họ nói là những người có họ 'Null' đang gặp vấn đề với việc nhập thông tin chi tiết của họ vào một số trang web.

Không có lời giải thích nào được đưa ra về lỗi mà họ đang gặp phải.

Nhưng theo như tôi biết thì chuỗi 'Null' và giá trị Null thực tế hoàn toàn khác nhau (theo quan điểm của cơ sở dữ liệu).

Tại sao điều này sẽ gây ra vấn đề trong cơ sở dữ liệu?


2
Đây là một bài viết blog hơi nổi tiếng về lập trình giả định rằng chắc về tên, được viết bởi một trong những người được trích dẫn trong bài báo đó BBC: kalzumeus.com/2010/06/17/...
Jörg W Mittag



4
Lần đầu tiên tôi thấy anh chàng này trên TV, tôi cho rằng đó là lỗi cơ sở dữ liệu. Sau đó tôi phát hiện ra tên thật của mình.
Nate Eldredge

3
@JarrodRoberson Làm thế nào bạn có thể nói "toàn bộ tiền đề là sai", được đưa ra mô tả về các vấn đề mà "Jennifer Null" phải đối mặt và tên tương tự trong liên kết mà OP đã đăng? Đây là một vấn đề thực sự phải đối mặt với người dùng cuối thực sự.
Gort Robot

Câu trả lời:


102

Nó không gây ra vấn đề cơ sở dữ liệu. Nó gây ra sự cố trong các ứng dụng được viết bởi các nhà phát triển không hiểu cơ sở dữ liệu. Nguyên nhân của vấn đề là nhiều phần mềm liên quan đến cơ sở dữ liệu hiển thị bản ghi NULL dưới dạng chuỗi NULL. Khi đó, một ứng dụng dựa vào dạng chuỗi của bản ghi NULL (cũng có thể sử dụng các hoạt động so sánh không phân biệt chữ hoa chữ thường), thì một ứng dụng như vậy sẽ coi bất kỳ "null"chuỗi nào là NULL. Do đó, một cái tên Null sẽ được coi là không tồn tại bởi ứng dụng đó.

Giải pháp là khai báo các cột không null như NOT NULLtrong cơ sở dữ liệu và không áp dụng các hoạt động chuỗi cho các bản ghi cơ sở dữ liệu. Hầu hết các ngôn ngữ có API cơ sở dữ liệu tuyệt vời làm cho giao diện cấp chuỗi không cần thiết. Chúng nên luôn luôn được ưu tiên, vì chúng ít gây ra các lỗi khác như SQL SQL.


30
Tuy nhiên, trong trường hợp này, nếu bạn đọc bài viết được đề cập, việc tạo trường tên cuối cùng NOT NULLsẽ gây ra một loạt các vấn đề cho người khác. "Một số cá nhân chỉ có một tên duy nhất, không phải tên và họ."
MikeTheLiar

41
@Darkhogg rất nhiều người không đồng ý với tôi về điều này nhưng tôi nghĩ rằng tên đó giống như địa chỉ email - đừng bận tâm xác thực chúng, cung cấp cho người dùng một hộp văn bản duy nhất và để họ đặt bất cứ thứ gì họ muốn. Đây là thông tin mà nếu tôi thực sự cần nó tôi sẽ lấy nó từ bạn theo cách chắc chắn là chính xác.
MikeTheLiar

8
@mikeTheLiar Tôi không biết tên cho việc này nhưng có cả một nhóm lỗi xuất phát từ việc tạo ra các quy tắc hạn chế quá mức đối với dữ liệu. Thông thường bạn sẽ thấy mã bưu chính và số điện thoại được xác định là số trong các ứng dụng và cơ sở dữ liệu. Chúng không thực sự là những con số bởi vì thật vô nghĩa khi thực hiện các phép toán trên chúng. Vì vậy, khi ai đó cố gắng nhập địa chỉ Canada, họ bị mắc kẹt.
JimmyJames

19
@JimmyJames yeah, mã zip được lưu trữ dưới dạng số và đột nhiên bất cứ ai sống ở đây đều có mã zip cơ sở 8. "Nếu bạn không làm toán với nó, thì đó là một chuỗi, Dừng hoàn toàn."
MikeTheLiar

8
@mikeTheLiar. Vấn đề với việc xử lý tên như một chuỗi đơn (thường là tốt hơn, tôi đồng ý) là khi có yêu cầu sắp xếp theo thứ tự chữ cái theo họ.
TRIG

13

Để trả lời câu hỏi cụ thể của bạn, có nhiều bước dọc theo chuỗi sự kiện giữa biểu mẫu web và cơ sở dữ liệu. Nếu tên cuối cùng Nullbị hiểu nhầm là một NULLgiá trị thì hệ thống có thể từ chối một tên hoàn toàn hợp lệ là không hợp lệ. Điều này có thể xảy ra ở lớp cơ sở dữ liệu như được giải thích bởi amon . Ngẫu nhiên nếu đây là vấn đề cụ thể thì cơ sở dữ liệu cũng có thể mở cho SQL tiêm AKA cuộc tấn công Bobby Bảng . Một bước khác trong chuỗi có thể gây ra vấn đề là quá trình tuần tự hóa .

Nhìn chung, bài viết là về một vấn đề lớn hơn. Thế giới là một nơi lộn xộn lớn không phải lúc nào cũng phù hợp với các giả định của chúng tôi. Điều này đặc biệt rõ ràng khi bạn cố gắng quốc tế hóa ứng dụng của mình. Vào cuối ngày, chúng tôi cần đảm bảo các ứng dụng của chúng tôi xử lý và mã hóa dữ liệu của chúng tôi đúng cách . Tùy thuộc vào doanh nghiệp quyết định có bao nhiêu nguồn lực chúng tôi dành cho việc hỗ trợ các trường hợp cạnh ngày càng phức tạp. Mặc dù tôi hoàn toàn ủng hộ việc bao gồm, tôi sẽ hiểu nếu doanh nghiệp quyết định rằng "nghệ sĩ chính thức được gọi là Hoàng tử" cần sử dụng ký tự Unicode để thể hiện tên của mình trong cơ sở dữ liệu của chúng tôi.


Thật khó để tưởng tượng điều này được gây ra bởi kiểu nội suy chuỗi không an toàn có thể dẫn đến việc tiêm SQL. Nếu bạn quên trích dẫn đầu vào của người dùng trong truy vấn SQL (ví dụ: INSERT INTO users (first, last) VALUES($first, $last)đánh giá INSERT INTO users (first, last) VALUES(Jennifer, Null)) tất cả mọi người có tên không phải là từ khóa SQL hoặc tên cột hợp lệ sẽ chỉ đưa ra lỗi và không chèn hồ sơ của họ. Nguyên nhân phải phức tạp hơn.
Andrew Medico

@AndrewMedico trong ví dụ người đàn ông rơm của bạn có nhưng có rất nhiều cách để làm những điều sai trái. Đừng bao giờ đánh giá thấp sức mạnh của sự ngu ngốc <đình công> ngu ngốc <\ strike>. Điểm mấu chốt là chúng tôi không biết vấn đề thực sự là gì vì chúng tôi không thể xem lại mã được đề cập
Erik

7

Chà, trước khi nó được nhập vào cơ sở dữ liệu, đó là một phần tử DOM, sau đó một biến javascript được truyền qua, xác thực và thao tác, sau đó là một giá trị JSON, sau đó là một biến trong bất kỳ thư viện JSON phụ trợ nào bạn đang sử dụng, sau đó một biến được truyền qua, được xác thực và thao tác trong ngôn ngữ lập trình phụ trợ của bạn, sau đó là một phần tử của một loại DAO nào đó, sau đó là một phần của chuỗi SQL. Sau đó, để lấy lại giá trị, bạn làm ngược lại. Đó là rất nhiều nơi để các lập trình viên mắc lỗi, và thường là rất nhiều trong số đó mà không có lợi ích của việc gõ tĩnh.


2

Rất có thể đó là một vấn đề lập trình. Nếu bạn xem câu trả lời này ở đây về cách NULL được thông qua, bạn có thể dễ dàng gây ra một số hành vi không mong muốn nếu bạn là "Ông Null".

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

Bạn có thể thấy rằng nếu một số phần tử dữ liệu được truyền dưới dạng NULL, dữ liệu sẽ được nội suy dưới dạng cơ sở dữ liệu null trong cơ sở dữ liệu.

"NULL"! = Cơ sở dữ liệu Null

Một số trường hợp sử dụng và hành vi liên quan ...

Giả sử tên cuối cùng được đánh dấu trong cơ sở dữ liệu là không rỗng, bây giờ khi dữ liệu được chèn, nó sẽ được hiểu là NULL và không chèn được.

Một trường hợp khác là giả sử tên cuối cùng là nullable trong cơ sở dữ liệu. Ông NULL được chèn và được chuyển đổi thành DBNull.Value không giống với "NULL". Sau khi chèn, chúng tôi không thể tìm thấy ông Null vì họ của ông không phải là "NULL" mà thực tế là một giá trị null cơ sở dữ liệu.

Vì vậy, đó sẽ là 2 trường hợp vấn đề. Như @Amon chỉ ra, bản thân cơ sở dữ liệu không có vấn đề gì với null, mặc dù người ta nên hiểu cách xử lý null trong mỗi cá thể RDMS vì sẽ có sự khác biệt giữa các nhà cung cấp khác nhau.


"Bạn có thể thấy rằng nếu một số phần tử dữ liệu được truyền dưới dạng NULL, dữ liệu sẽ được nội suy dưới dạng cơ sở dữ liệu null trong cơ sở dữ liệu." - câu hỏi SO được liên kết / câu trả lời được chấp nhận không xuất hiện để hiển thị điều này?
MrWhite

2

Tôi sẽ gán vấn đề cho lập trình cẩu thả và thiết kế kém của một số triển khai SQL. "Không" tên luôn luôn phải được trình bày và giải thích với dấu ngoặc kép. null, giá trị cơ sở dữ liệu, phải luôn luôn được trình bày mà không có dấu ngoặc kép; nhưng khi viết mã ad-hoc, thật dễ dàng để đi vào mô hình "mọi thứ sẽ làm" và chấp nhận những thứ được cho là một chuỗi ở dạng không trích dẫn.

Điều này được kết hợp bởi thực tế là các loại dữ liệu khác; các số chẳng hạn, có thể và được chấp nhận dưới bất kỳ hình thức nào vì cách giải thích không rõ ràng.


Bạn có nghĩa là triển khai ứng dụng kém bằng SQL, chắc chắn? Bản thân RDBMS không thực hiện nghiêm túc việc này (cũng như không có ứng dụng nghiêm trọng nào!)
underscore_d

0

Một vấn đề, về cơ bản, là thuật ngữ "null" được áp dụng hai khái niệm cơ sở dữ liệu khác nhau, đôi khi sử dụng bối cảnh để phân biệt giữa chúng:

  1. Một cái gì đó không có giá trị được biết đến
  2. Một cái gì đó được biết là không có giá trị

Mặc dù bối cảnh đôi khi có thể đủ để phân biệt giữa các khái niệm đó, nhưng có những lúc nó thực sự không. Ví dụ: nếu một người đang sử dụng một bản ghi để giữ một truy vấn tìm kiếm, thì sẽ có một sự khác biệt giữa việc nói "Tôi muốn ai đó bằng tên [bất cứ thứ gì], không có họ", so với "Tôi muốn ai đó có tên là [ sao cũng được] nhưng không biết họ của họ là gì. " Nhiều công cụ cơ sở dữ liệu có xu hướng thiên về nghĩa này hay nghĩa khác, nhưng chúng không giống nhau. Mã đang mong đợi một công cụ cơ sở dữ liệu hoạt động một chiều có thể gặp trục trặc nếu chạy trên một công cụ khác chạy khác nhau.


Nếu một chuỗi được biết là không có giá trị, thì giá trị đó phải là một chuỗi rỗng, không phải là một chuỗi rỗng.
Byron Jones

0

Hầu hết các câu trả lời hiện có tập trung vào các phần không phải SQL của ứng dụng, nhưng cũng có thể có một vấn đề trong SQL:

Nếu được hướng dẫn lọc ra các bản ghi không có họ của người dùng, ai đó không hiểu rõ về SQL có thể viết bộ lọc WHERE u.lastname != 'NULL'. Do cách SQL hoạt động, điều này sẽ xuất hiện để kiểm tra xem u.lastname IS NOT NULL: tất cả các NULLbản ghi có được lọc ra không. Tất cả các NULLhồ sơ không còn lại.

Tất nhiên ngoại trừ các hồ sơ ở đâu u.lastname == 'NULL', nhưng có thể không có bất kỳ hồ sơ nào như vậy có sẵn trong quá trình thử nghiệm.

Điều này trở nên có khả năng hơn nếu SQL được tạo bởi một loại khung công tác nào đó, trong đó khung đó không phơi bày một cách dễ dàng truy cập để kiểm tra tính không liên quan NULLvới các tham số và ai đó thông báo "hey, nếu tôi chuyển qua chuỗi NULL, nó làm chính xác những gì tôi muốn! "

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.