2013-02-07 97 views
3

我通常可以在SO中找到我的問題的答案,但我無法找到關於此主題的信息(可能是我做錯了問題)。背景:六年前,一些開發人員將Visual FoxPro數據庫升級到SQL Server 2005(表結構和數據)。該過程引入了現在我試圖修復的各種錯誤,以便改進數據結構和性能(將TEXT更改爲VARCHAR(MAX),某些浮點更改爲DECIMAL,刪除未使用的列......)SQL列中char/varchar的缺省值:空格(1)或空字符串?

我之前的任務是:找到所有默認約束分配給所有表中的所有列,其對應的默認對象並沒有sys.default_constraints存在並修復它們分配一個空字符串char/varchar0Decimal,等...(更多我的腳本工作很順利,到目前爲止這麼好。

只是爲了好玩我執行了SP_HELP在其中一個表中驗證固定列,但注意到我沒有更改的char列的默認值爲(space((1))),而不是我正在使用的普通空字符串''

我的問題是:我應該保留這些列完好無缺的默認值(space((1)))?或者我應該將其更改爲''(更改腳本來做到這一點非常簡單)?

我敢打賭,我應該改變它(調用每個插入的函數不能自由),但要先確定。

PD:我不是DBA,而是一個不時需要使用DBA帽子的開發人員。

+1

我讚揚你的努力,重構你的數據庫,使之更接近理想。 –

+1

我想在過去的2年裏做到這一點,但沒有時間,總是有一場火災,我必須先爭取:S – Roimer

回答

2

很多時候,辯論是關於null vs a default empty string(dba.se辯論here)。在這種情況下,我認爲主要關注的是應用程序的任何部分是否根據列中的單個空格執行邏輯。與此相比,存儲和速度方面的問題是微不足道的,除了最大的桌面和最高的TPS情況之外,甚至可能忽略不計。我也想象一下,即使您已經說過它不能免費,但仍然很難可靠地檢測到insert ' ',insert ''insert space(1)之間的任何有意義的性能差異。

更新

我只注意到你提到只有char列具有默認值。在這種情況下,我不認爲這真的很重要,你要插入空字符串或單個空格,因爲它們會被存儲爲空間到列的長度:

create table #CharTest (Chars char(2)) 
insert into #CharTest select '' 
insert into #CharTest select ' ' 
insert into #CharTest select ' ' 
select distinct Chars from #CharTest 
-- returns 1 row! 

在這一點上我會喜歡說,你可以擺脫空間,只是空的字符串默認。一個潛在的警告是,如果你有一個可爲空的字符列,並且ANSI_PADDING在創建時關閉。然而,在測試各種ansi-nulls,char,varchar和無效組合時,我無法想出'' = ' '爲false的情況(無論如何,在SQL Server 2008 R2中)。嗯...我需要去做一些閱讀。

+0

我有機會閱讀應用程序的最後四個代碼年,並且我確定所有尾隨空格在進行比較之前(在應用程序邏輯,腳本或報告中)都被修剪,所以具有空格或空字符串對於當前代碼而言是不相關的。我只是因爲擁有一個能夠完成這項工作的函數而感到不安。 – Roimer

+0

關於你的更新:是的,'TEXT'列也有'(space((1)))'作爲默認值,但是在將它們全部更新爲'VARCHAR(MAX)'後,我也將默認值更改爲'''' ;當時我注意到了字符。謝謝,我正在編輯腳本:我將要擺脫空間,主要是爲了獲得_consistent/uniform_數據庫。 – Roimer

1

如果您的應用程序對該問題不可知,那麼需要考慮的一件事是零長度的varchar列將佔用比單個空間列略少的空間。

如果沒有任何非空的可變長度列,那麼對於列值每列可能會保存1個字節,而在列偏移量數組中可能會另存兩個字節。

我可能會使用NULL,而不是這兩者之一。

+0

我寧願在許多這些領域使用NULL,但應用邏輯不會(也不會)處理空值,所以我必須盡我所能地做到最好,而無需更改當前正在生產的應用程序。並感謝在大小上的提示:有很多列通常插入默認值,我的下一步是減少行大小 – Roimer