淺談資料庫字串型別的處理方式
最近寫 .NET 文章寫膩了,想找別的主題來瞎掰。
在處理資料庫字串時,常見的做法可以分為三種:區分 NULL 和空字串、一律存 NULL,以及一律設為 NOT NULL 並存空字串。這些做法各有其優缺點。
區分 NULL 和空字串
NULL 代表使用者未曾輸入過任何資料,而空字串則代表使用者輸入了資料,但值為空。這種做法的好處在於可以擁有更明確的語意。
但這種做法因為缺乏強制性,需要開發人員在程式設計上謹慎處理,確保在正確的情境下使用 NULL 和空字串。
一律存 NULL
這種做法通常見於 Oracle 的使用者,因為 Oracle 的資料庫在存儲空字串時會自動轉換為 NULL。在這種情況下,Oracle 資料庫具有較高的強制性,即使開發人員存入空字串,資料庫也會自動將其轉換為 NULL,確保一致性。但是在其他資料庫系統可能就需要使用 CHECK 約束來進行限制。
一律設 NOT NULL 並存空字串
這種做法通常見於一些早期的資料庫應用。其優點如下:
- 因為欄位被設成
NOT NULL,可以強制使用者只能存空字串。 - 早期資料庫在某些情況下,對空字串的索引處理效能可能優於
NULL。當然,不同資料庫對此的處理方式可能不同,而近年來資料庫對於NULL的最佳化策略是否有更新我並不確定。但是,現今實務上NULL仍有可能無法有效利用索引。例如,MSDN 的這篇文章「您與 IS NULL 述詞一起建立的篩選索引不會用於 SQL Server」就有提到其中一個情境。 - 在沒有 ORM(物件關係映射)的情況下,SQL 語句中
WHERE 欄位 = NULL會返回false,而必須使用WHERE 欄位 IS NULL,導致在撰寫程式自動產生 SQL 時,需要針對NULL做特別處理,這樣的情況下,使用空字串可以避免這個問題。 NULL在一些條件運算和函數處理上,可能會產生預期外的結果,存空字串可以避免這些情況。有關這些預期外情況,可以參考黑暗執行緒大神的以下文章:
缺點則是當 Foreign Key 為字串型別時,如果沒有值必須存 NULL,不能存空字串,這會導致該欄位處理與其他字串型別欄位不一致。
個人喜好
現在我大部分都是使用 Entity Framework 來處理資料庫操作,不用再像過去手刻 Library,並在其中做 NULL 處理。儘管如此,考量到 NULL 可能引發預期外的問題,我個人在寫自己專案,或是公司或團隊沒特別規定的情況下,除非涉及到 Foreign Key,否則會選擇將欄位設為 NOT NULL 並存儲空字串。對於字串型態的 Foreign Key,只能盡量避免使用。當然,在使用 Oracle 資料庫時,還是只能存儲 NULL。
異動歷程
- 2024-07-12 初版文件建立。
