Lý do không sử dụng số nullable trong Oracle?


12

Công ty của chúng tôi đang giao tiếp với một công ty phần mềm khác cho một dự án chung và chúng tôi được thông báo rằng, nếu không hiển thị một giá trị cụ thể, chúng tôi nên chuyển trong -5000 (giá trị trọng tâm tùy ý của họ); Lý do là không có cột số nào trong cơ sở dữ liệu Oracle của họ hỗ trợ các giá trị null, theo khuyến nghị của nhà phát triển Oracle (hiện tại trước đây) của họ. Công ty này cũng viết phần lớn mã của họ trong VB6 (từ từ chuyển sang VB.NET, đây là một chủ đề cho một ngày khác ...). Vì tò mò thuần túy, có lý do nào hợp lệ cho khuyến nghị này không? Tôi không thể nghĩ về bất kỳ ai về phía tôi.

--- biên tập

Cảm ơn về tất cả các phản hồi. Tôi đã đặt ra câu hỏi tương tự trên CodeProject.com ( liên kết ) và nhận được phản hồi rất giống nhau. Có vẻ như lần duy nhất người ta có thể bắt đầu biện minh cho hoạt động này có liên quan đến khóa ngoại và tôi có thể nói rằng họ không sử dụng khóa ngoại ở bất kỳ đâu trong hệ thống. Nhà phát triển đưa ra quyết định này (tôi từng làm việc tại công ty đó) có nhiều kinh nghiệm hơn tôi, vì vậy tôi muốn chắc chắn rằng không có lý do chính đáng nào cho việc này trước khi sự dè bỉu xảy ra.


2
Ý bạn là, ngoài "đó là những gì API của họ chỉ định"?
Robert Harvey

Có, tôi tò mò hơn về lý do tại sao API của họ sẽ chỉ định điều đó ngay từ đầu; Có một lý do cho thực hành này, hoặc đây chỉ là một số sự mất trí?

3
Lunacy của thứ tự cao nhất!
Philᵀᴹ

Câu trả lời:


17

Thực tế, yêu cầu là điên rồ. Tuy nhiên, giống như tất cả các ý tưởng điên rồ tuyệt vời, có lẽ nó dựa trên một loạt các tính hợp lý tiềm năng được đưa ra khỏi bối cảnh bởi những người không hiểu biết về cơ sở lý luận cơ bản.

Có thể hợp lý khi thiết kế một lược đồ cơ sở dữ liệu sao cho không có NULLgiá trị nào được phép. Tuy nhiên, nếu bạn làm điều đó, bạn đang cam kết mức độ chuẩn hóa trong đó mọi phần tử không bắt buộc được chia thành một bảng riêng biệt với tham chiếu khóa ngoài thích hợp cho cha mẹ. Nó không thường được thực hiện trong thực tế nhưng trong trường hợp có ý nghĩa để làm, có thể có lợi ích.

Nếu bạn định thiết kế một lược đồ cơ sở dữ liệu sao cho không có NULLgiá trị nào được phép, sẽ không có ý nghĩa gì khi cho phép một mình yêu cầu các giá trị ma thuật để chỉ ra rằng có gì đó chưa biết. Điều đó giới thiệu tất cả các vấn đề cho phép NULLcác giá trị cộng với nó thêm mã bổ sung để kiểm tra các giá trị ma thuật phải lặp đi lặp lại ở mọi nơi. Thật vô nghĩa khi phát triển một API yêu cầu các giá trị ma thuật được truyền vào bất kể thiết kế cơ sở dữ liệu nào - nếu bạn định sử dụng mã của mình để kiểm tra các giá trị ma thuật, bạn thực sự không nên để sự điên rồ đó lan truyền sang các hệ thống khác .


+1 và mã bổ sung để kiểm tra các giá trị ma thuật không thể sử dụng các hàm nổi tiếng như COALESCE()- vì vậy nó càng trở nên phức tạp hơn.
ypercubeᵀᴹ

Và các giá trị cần được lưu trữ trong bất kỳ chỉ mục nào trên cột đó. Các chỉ mục không phải lưu trữ giá trị null.
Động học Tripp

15

Không có lý do hợp lệ để sử dụng giá trị ma thuật thay vì NULL. Đây có thể là quá trình suy nghĩ của ai đó tạo ra mớ hỗn độn này. Họ viết một cái gì đó như thế này:

 SELECT c1, c2 FROM t1 WHERE c3 < 30;

Khi điều này không trả về kết quả mà họ mong đợi, họ nhận ra rằng nó không bao gồm NULL và sẽ cần phải viết điều này:

SELECT c1, c2 FROM t1 WHERE c3 < 30 OR c3 IS NULL;

Họ không muốn viết hoặc quên trong tương lai để viết bài này, vì vậy họ đã đưa ra giải pháp tạo ra tất cả NULLS -5000. Thật kỳ diệu, truy vấn ban đầu của họ xử lý NULL mà không có bất kỳ thay đổi nào. Điều họ không nhận ra là bây giờ ai đó muốn loại trừ các giá trị này phải viết điều này:

SELECT c1, c2 FROM t1 WHERE c3 < 30 AND c3 <> -5000;

Hoặc nếu họ muốn những giá trị này và đang tìm kiếm một phạm vi cao hơn:

SELECT c1, c2 FROM t1 WHERE c3 > 40 OR c3 = -5000;

Họ cũng có thể không nhận ra rằng những điều sau đây sẽ không còn ý nghĩa:

SELECT c1, c2 FROM t1 WHERE c3 IS NULL;

Thay vào đó một người phải nhớ giá trị ma thuật. Với mỗi kiểu dữ liệu được sử dụng, họ phải nhớ nhiều giá trị ma thuật hơn, ví dụ 1/1 // 1900, "Z", -5000. Hơn nữa, khi giá trị ma thuật nằm trong dữ liệu, họ cũng phải nhớ các giá trị ma thuật thay thế.

Vì vậy, đối với một trường hợp cụ thể, nó làm cho mã đơn giản hơn với chi phí của các trường hợp khác, chưa kể đến dung lượng đĩa, kích thước chỉ mục, phân tích truy vấn, tính nhất quán, v.v.


8

Đó là sự điên rồ hoàn toàn và không có lời biện minh nào cho điều đó. NULLđược tạo ra để thể hiện sự vắng mặt của một giá trị & để sử dụng một giá trị thực tế như -5000 là các bonkers.

Thông thường tôi sẽ không viết một câu trả lời ngắn gọn này, nhưng câu hỏi xứng đáng là một trong những câu hỏi dễ thấy nhất trên dba.se & càng nhiều câu trả lời càng tốt.


5

Tôi nghĩ về điều này một chút cố gắng tỏ ra lạc quan và biện minh cho sự cần thiết của việc sử dụng một giá trị tùy ý thay vì một null và có vẻ (với tôi ít nhất) là không có lý do chính đáng cho điều này, ngoại trừ có lẽ trong một tập dữ liệu dữ liệu khai thác khép kín để cải thiện và đơn giản hóa hiệu suất và truy vấn, và sau đó chỉ trong trường hợp số không phải là giá trị có thể làm lệch dữ liệu. Ngay cả điều này sẽ phải được xem xét cẩn thận. Trong tất cả các tình huống trong thế giới thực, việc đưa ra một giá trị cho null là không thực tế. Điều này biến định nghĩa cột KHÔNG NULL từ bạn của bạn sang kẻ thù của bạn vì nó thực sự không đúng.

Một điều rất khác để nói rằng ứng dụng của chúng tôi không nên chấp nhận giá trị NULL cho một số (hoặc thậm chí tất cả) cột. Đây là thực tế hợp lý và tốt và có những lợi ích được ghi chép rõ ràng để không cho phép null (ví dụ: khóa và chỉ mục và tính toán thống kê). Tuy nhiên, việc gán một giá trị cho "ngồi tại chỗ" của null hoàn toàn không giống nhau. Đó là cây gậy cho chính bạn, vì trước tiên bạn phải chọn một giá trị sẽ không bao giờ được sử dụng, hãy lọc ra giá trị này như bạn sẽ null và nhớ không sử dụng nó trong tính toán và tóm tắt và xóa nó khỏi nguồn cấp dữ liệu ngoài . Điều này ít nhất là tồi tệ khi sử dụng null để thể hiện một giá trị thực tế, đó là những gì bạn nói với chính mình rằng bạn đang tránh, nhưng bạn thì không.

Hầu hết các vấn đề mà null gây ra, một khi đã hiểu, có thể được xử lý (bình thường hóa tốt hơn, dựa trên chức năng hoặc chỉ mục bitmap hoặc với WHERE x IS NOT NULL đơn giản). Bạn có nghĩ rằng tại một số Telco lớn hoặc tại Amazon trong cuộc họp hiệu suất hàng tháng, một số DBA đang phác thảo kế hoạch tuyệt vời này để tăng tốc truy vấn trên bộ dữ liệu khổng lồ của họ một chút "bằng cách thay thế null bằng giá trị tùy ý, như -5000 hoặc bất cứ điều gì - Tôi đang mở về giá trị ... ". Hoặc bạn có nghĩ rằng họ dành thời gian phân chia giữa thiết kế ứng dụng tốt hơn để lọc các null không mong muốn và tối ưu hóa truy vấn dựa trên dữ liệu thực tế họ nhận được không? OK, có thể một cuộc họp hàng tháng là một chút lạc quan, nhưng bất cứ khi nào chúng xảy ra tôi có thể đảm bảo với bạn rằng "Thay thế null bằng -5000 (hoặc bất cứ điều gì) cho API tốt hơn" không phải là một mục chương trình nghị sự.

Đối với tôi, thật tốt khi nói rằng tôi sẽ không chấp nhận dữ liệu bị thiếu (bạn phải có tuổi hoặc giá hoặc mã vùng hoặc bất cứ điều gì) và đôi khi thậm chí tốt để nói với cột này có một giá trị mặc định sẽ được nhập nếu bạn không đặt cái gì khác Sẽ không tốt nếu đặt sang một giá trị có nghĩa là null. Hãy nghĩ về các trường tên đệm làm ví dụ. Đôi khi những thứ này sẽ không tồn tại vì cha mẹ quá lười biếng để điền vào tất cả các ô. Chúng tôi có thêm "không" hoặc "thiếu" hoặc "không xác định" vào dữ liệu của mình để cải thiện các tìm kiếm không? Không bởi vì có thể có những người lạ thay đổi tên của họ thành các giá trị này và vì vậy khi chúng tôi in ra dữ liệu, chúng tôi không biết liệu chúng tôi có phải đưa nó vào hay không. Đó là một ví dụ đơn giản, nhưng vươn xa. Chúng tôi biết về NULL và có các chức năng được xây dựng có thể dự đoán để đối phó với nó. Bạn không thể mã này tốt hơn.

Nếu không có câu trả lời (hoặc NULL) không phải là phản hồi hợp lệ cho yêu cầu đầu vào của bạn thì đừng cho phép nó trong ứng dụng hoặc trong cơ sở dữ liệu, nếu đó là phản hồi tốt thì bạn phải cho phép nó trong cả ứng dụng và cơ sở dữ liệu của bạn và xử lý nó như một phản ứng hợp lệ Nếu nó là một phần của tập hợp các phản hồi hợp lệ, cơ sở dữ liệu của bạn phải được thiết kế để lưu trữ nó. Sau tất cả, bạn không nói hey, các trường số rất nhàm chán cho phép lưu trữ số trong các đốm màu và sử dụng hình ảnh của động vật hoang dã để đại diện cho mỗi số, bởi vì đó là các loại hạt (mát nhưng hạt). Chúng tôi cũng không quyết định rằng chúng tôi không thích chữ B và giống như cơn ác mộng Sesame Street độc ác thay thế nó bằng # trong dữ liệu của chúng tôi. Nếu B không phải là phản hồi, chúng tôi muốn chúng tôi nói với người dùng "Này, bạn không thể đặt B ở đây". Vậy tại sao đối xử với null khác nhau?

Vì vậy, tránh các null bạn không muốn ở cấp ứng dụng và xử lý chúng trong cơ sở dữ liệu của bạn, nơi bạn chấp nhận chúng nếu không chắc chắn như hươu cao cổ + hươu cao cổ = hà mã dữ liệu vô nghĩa của bạn sẽ khiến bạn gặp rắc rối.


2
Bố mẹ tôi không lười biếng và nhân tiện tôi không có tên đệm. Không phải tất cả mọi người sống ở Hoa Kỳ.
ypercubeᵀᴹ

1
Nó có nghĩa là một ví dụ nhẹ nhàng, không có ý xúc phạm. Tất nhiên, có nhiều người không có tên đệm (điểm đầu tiên) vì nhiều lý do khá hợp lệ (điểm chính). Null trong cột này cho bạn biết không có lý do tại sao nó bị thiếu. Không chắc chắn về góc độ địa chính trị của bạn - Tôi không sống ở Hoa Kỳ nhưng thực tế có tên đệm. Tôi đoán thật khó để đưa ra các giả định dựa trên dữ liệu bị thiếu.

Không có sự xúc phạm nào. Tôi nêu lên câu trả lời của bạn thực sự. Tôi nghĩ rằng bạn đã nhấn mạnh vào điểm chính của mình rằng có sự khác biệt giữa việc không chấp nhận / cho phép Nulls trong cơ sở dữ liệu và thay thế Nulls bằng một giá trị ma thuật.
ypercubeᵀᴹ

5
Tôi thích nó nếu tên đệm của tôi là "-5000"! : D
Philᵀᴹ
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.