2010-06-08 226 views
9

組織中的數據庫開發標準聲明varchar字段不應允許空值。他們應該有一個空字符串(「」)的默認值。我知道這使得查詢和連接更容易,但今天,我的一位同事質疑我爲什麼該標準只存在於varchar類型而不是其他數據類型(int,datetime等)。我想知道其他人是否認爲這是一個有效的,可辯護的標準,或者如果varchar應該被視爲與其他數據類型的字段相同?Varchar列:可爲空或不可爲

我相信這個標準是適用於以下原因:

我相信,一個空字符串和空值,雖然在技術上有所不同,在概念上是相同的。一個空的零長度字符串是一個不存在的字符串。它沒有價值。但是,數值0與NULL不同。

例如,如果名爲OutstandingBalance的字段值爲0,則表示剩餘的金額爲0.00美元。但是,如果相同的字段爲NULL,那意味着值是未知的。另一方面,名爲CustomerName且字段值爲「」的字段與NULL的值基本相同,因爲兩者都表示名稱不存在。

我在某處讀到一個空字符串與NULL的類比是空白CD與無CD的比較。不過,我認爲這是一個錯誤的比喻,因爲空白CD仍然存在,並且仍然有物理數據空間,沒有任何有意義的數據寫入它。基本上,我相信一張空白CD相當於一串空格(「」),而不是一個空字符串。因此,我相信一個空格字符串是一個與NULL分開的實際值,但是空字符串在概念上等同於NULL。

請讓我知道,如果我對變長字符串的信仰是有效的,或者請賜教,如果他們不是。我已經閱讀了幾篇關於這個主題的博客/論點,但是仍然沒有看到NULL和空字符串之間真正的概念區別。

回答

15

這幾乎歸結爲這 - 在你的應用程序中,對於一個特定的字符串,是否有一個空字符串根本沒有字符串之間的區別?

如果沒有區別,那麼你所遵循的標準是好的。

如果您發現有差異,那麼null有明確的含義,應該允許。

根據我的經驗,null通常建模爲unknown

這裏有一個更具體的例子 - 的人中間名:

  • 如果你知道的中間名,則該值填充
  • 如果你知道這個人有沒有中間的名字,然後使用一個空字符串(「」)
  • 如果你不知道一個人是否有一箇中間名,一個null可能更合適

同樣,如果你的應用待人w ^沒有中間名和那些不明的地方,那麼使用空字符串是有意義的(即使它意味着丟失一些信息)。

+0

+1:業務規則驅動列可選性,而不是數據類型。此外,使用NULL與零長度字符串不會節省空間:http://vampirebasic.blogspot.com/2009/01/sql-server-null-varchar-vs-empty.html – 2010-06-08 20:06:55

1

不,null是一個非常獨特的價值。例如 - 只有一個 - 十幾個 - 空可能意味着「我們根本沒有價值」,而空字符串意味着「我們有一個答案,它是沒有的。」這將是有用的,例如,作爲一個問題的答案 - 從來沒有得到答案或答案是什麼...

有一個偉大的白皮書漂浮在那裏題爲像「NULL的18種含義」 - 我不記得那個整數是什麼!至少在20世紀90年代初期,那篇文章就已經出現了,如果你能找到它,那真是太棒了 - 我還沒有做過網絡搜索。

真正的問題是,它們可以「錯誤地」改變返回的行。例如,如果你說

選擇strcol1,datecol2,someint3從FUBAR哪裏...

如果strcol1恰好是空,你不會得到一個值返回該行,因爲有一個隱含的「何處strcol1不爲空「 - 因此整行可能會丟失。

這不適用於所有的RDBMS系統,但在一段時間內一直如此,所以如果您希望您的代碼能夠從一個RDBMS移動到另一個RDBMS系統,則在處理空值時應該非常小心。另一點:Oracle - 或者至少某些版本的Oracle - 將靜默地將空字符串轉換爲空值!這確實太離譜了,但不知何故,他們已經將這部作品「永遠地」製作了出來。小心!我的解決方案是使用其他字符串來表示「空字符串」,通常是單個空格字符。