2011-03-17 76 views
0

我被告知,在字段定義中允許使用空值是不好的設計......我知道它可能會導致錯誤......但有人可以詳細說明並解釋在什麼情況下我不應該允許空值以及爲什麼。什麼是理論,什麼是最佳實踐?我想明白。空值有什麼問題?

編輯

我的兩難困境是,我必須做出改變分貝現在,代碼將在稍後實施,所以,我很擔心創建新字段NOT NULL和冒着非現場具體INSERT陳述失敗。這是我不清楚的地方。我想要允許NULL,因爲我認爲風險較小,但其他人告訴我這是糟糕的設計。在這個階段,我更關心代碼實施時風險的最小化。如果有人能幫我澄清我的選擇,我會很感激。我缺乏信念,我需要儘快作出決定。

回答

1

這太簡單了。在許多情況下,你不知道 - 例如 - 如果一個人有孩子。 NumberOfChilds = 0表示:他有零個孩子,NULL表示:你不知道。

但是,如果您可以在整個過程中使信息成爲強制性的,那麼最好在最深層次上強制執行。

允許NULL比讓客戶規避你的邏輯,並用'-1 child'標記非空字段來指示「還不知道」更好。現在,如果你拿到這筆錢,你就會迷失方向。或者每個人都發明自己的密碼來修補你的系統。

+1

你有思考數據,你的模型。想想一個顧客:你需要一些信息,做一個交易,姓名,地址,一個唯一的ID ...... - 一些數據是可選的:例如手機。所有,必要的,應該不是NULL。我們不能說更多。 –

1

如果您不允許空值,則確保您只有完整的保存數據。 使用空值的數據可以處理難以處理的數據。

例如,如果您有要顯示的書籍,它將導致您必須處理的問題,如果您在標題上允許空值。

如果您是數據庫的新手,並且您可能正在進行web開發,請參閱教義。它從你的代碼生成你的innoDB mysql數據庫(或其他數據庫)。

1

正如計算機科學中經常發生的那樣,這並不像「從不使用功能X」那樣簡單。

基本理論是SQL NULL不應該是一個字段的值 - 而是它表示值爲未知。換句話說,如果你有一個人表,第一個人的名字是NULL,這表明他的名字是未知的,而不是他沒有名字。

問題是這違反了「被排除的中間的規律」,它表明命題是真或假---一旦你引入了NULL,就有第三個「未知」的真值。這可能會導致各種棘手的邏輯相關的錯誤。

實際上,構建一個必須容納NULL值的模式並不是那麼常見,但它肯定會發生。所以最簡單的答案就是你應該要求你所有的字段都不是NULL,除非你有很好的理由不這樣做。

關於appropriate Wikipedia page上的整個問題有一個相當詳盡的討論。

1

NULL只有在數據庫設計不佳或其目的不明確或不明確的情況下才會出錯。例如,假設您的數據庫考慮了每個用戶的地址,並且您創建了多個列來保存它們:address_1,address_2,...。當然,這是糟糕的設計:正確的做法是創建一個將多個地址鏈接到用戶的新表。如果您的用戶只有一個地址,其餘列將不得不保留NULL值,這純粹是設計錯誤的結果。 此外,這個NULL值是不明確的。用戶是否有一個地址?用戶是否有兩個地址,其中第二個地址我們不知道?地址信息不適用?

但是,當然,即使數據庫設計正確並且規範化了,這些問題也必須得到解答。那是NULL發揮作用:它代表缺失和/或不適用的信息。例如,如果您知道用戶有第二個地址,但您不知道其郵政編碼,則NULL將作爲該字段中的值適用。重要的是你知道你的數據庫中有什麼NULL,並且你是一致的。一個理想的設計和填充的數據庫不會有NULL,因爲從理論上講,數據庫管理員將擁有所有相關信息,但在現實世界中並非如此。

+0

我同意用戶未知,所有這些對於您的DB +應用程序的正確工作而言絕對必要的應該是NOT NULL,其餘的應該被允許爲NULL,以允許缺少信息。 –

2

其中一個,空值引導你進入一些3值邏輯的領域。 「一些」邏輯,因爲可能有很多(其中一個可能的區別是邏輯蘊涵是如何定義的)。無論如何,無論使用哪種特定的3VL,它總是會帶來一些令人討厭的驚喜,並且最好是有點不直觀,或者在最壞的情況下完全無法理解。

保持在2VL中的大量等價(/同義反義詞)在大多數3VL中不能被維持,或者只是非常困難。以邏輯含義:在2VL中,通常知道'p暗示q'等價於'NOT(p)或q'。你可能會試圖找出經典2VL中的一些非常基本的套套語言是如何在3VL中產生的。

例如p值=> q < =>不(Q)=>不(P)

p或不(P)< =>真

p和不(對)< => false。

其次,SQL在各種情況下處理空值的方式大都是特設的方式。添加兩個數字,其中一個爲空,並且結果爲空。使用某種形式的SUM()(使用相同的參數)執行相同的操作,並獲得數字零!在Oracle數據庫中插入一個零長度的字符串,並將其轉換爲null,但其他DBMS可能不會這樣做(我不知道是否將某些CHAR列與零長度字符串進行比較(不一定是字面值,請注意,你的行爲是正確的)

第三,人們必須記住,空值本質上是布爾型標誌,表示存在/缺失,增加了查詢寫入的複雜性,但大部分複雜性都是由SQL語言在地毯下掃描,因爲它提供了很多「默認行爲」(例如,當真實結果應該是UNKNOWN時比較結果會返回FALSE),從而使開發人員錯誤地認爲複雜性不存在,並且開發人員不需要關心那額外的複雜性。

+0

如果開發人員不用'WHERE'來編寫針對'NULL'列的查詢來清除它們不需要的行,那麼這就是PEBKAC錯誤,而不是SQL的任何特定實現中的缺陷。大多數實現,甚至是Oracle,都可以明確其行爲。 – Blrfl