2010-02-17 73 views

回答

14

我的規則:如果許多記錄將使用該默認值(至少在最初),那麼我喜歡使用它作爲默認值。例如,在線商店中的產品的圖像表可能有一個默認路徑images/NoPictureYet.png。最終,這些將被替換,但對於圖片根本不存在的批量加載數據(也許大多數圖片根本不存在!),默認情況下(至少對我而言)是有意義的。

如果沒有合理的默認值(例如客戶數據庫中的「名字」 - 我不希望我的名字默認爲「名字」),那麼我將它設置爲非空和默認值 - 這是應用程序的確保輸入正確值的責任。

但沒有硬性規定。這一切都有所不同;)

7

我個人發現使用默認值的一個實際案例是last_modified列。

此列絕不會被存儲過程或業務邏輯更新,而是在行中的任何值更改時通過觸發器自動更新。不過,它也默認設置爲GETDATE(),這樣新行的值將包含創建時間的時間戳,基本上是上次修改時的時間戳。

ALTER TABLE users ADD CONSTRAINT dc_users_last_modified 
        DEFAULT GETDATE() 
        FOR last_modified; 

更新觸發器會那麼像這樣的事情:

CREATE TRIGGER trigUpdate_users 
ON users 
FOR UPDATE 
AS 
BEGIN 
    IF NOT UPDATE(last_modified) 
     UPDATE users SET last_modified = GETDATE() 
     WHERE user_id IN (SELECT user_id FROM inserted); 
END 
GO 
+2

不是真正意義上的「默認」。 – Andrew 2010-02-17 21:50:58

+1

我更喜歡'created_date'和'modified_date'列的觸發器。 – FrustratedWithFormsDesigner 2010-02-17 21:52:20

+0

@Daniel Vassallo:'modified_date'必須在更新時作爲觸發器完成,我喜歡'created_date'的代碼與'modified_date'一致。 ;)也許不是最好的理由,但是...哦! – FrustratedWithFormsDesigner 2010-02-17 22:00:00

4

沒有硬性的規定可以適用。這取決於列。例如,默認的訂單類型可能是完全明智的,但客戶電話號碼默認的想法沒有意義。

2

它應該很簡單。如果數據通常對於每行都是唯一的,例如客戶電話號碼,或者默認值很可能隨時間而改變,那麼我不會使用它。這意味着它僅用於填充CreateDate,ModifiedDate或其他性質的列。

3

我會說它是一個灰色地帶。通常我不會設計一個具有很多默認值的新數據庫,但是在增強現有系統時通常需要使用它們。

例如將新的非空列添加到現有數據庫。您可能不希望(或能夠)更新插入到該表中的所有代碼,因此您需要在其上放置一個默認值以確保任何「遺留」代碼仍然可以插入數據(假設默認值是合適的對於遺留代碼當然)。

0

絕對是灰色區域。這是傳統數據庫問題的經典邏輯。

如果我們想成爲純粹主義者,並且說數據庫中沒有商業邏輯屬性,那麼答案將永遠不會使用它們。

實際上,我們可以像我們經常做的那樣做一個例外,並允許將缺省邏輯放入數據庫中。

+2

如何愚蠢,必須在數據庫級別強制執行數據完整性,或者您沒有數據完整性。在應用程序中強制執行缺省值或約束或觸發邏輯最好是短視的。這幾乎是錯誤數據的保證,因爲數據庫經常在應用程序之外受到影響。 – HLGEM 2010-02-17 22:44:52

+0

同意約束條件。但不是默認值,它不是數據完整性。 – ctrlShiftBryan 2010-02-18 03:00:18

3

如果該列必須有一個值(它不爲空),那麼缺省值很重要。事實上,如果您將列從允許空值更改爲不允許它們,則默認值非常必要,因爲並非所有現有代碼都可能會填充值。有時在這種情況下,默認值就像'UNKNOWN'。如果要使用WITH VALUES將缺省值提供給ALTER TABLE語句中的字段爲空的現有記錄(將列更改爲NOT NULL),那麼尤其如此。對於用戶字段,缺省值對於字段非常重要界面通常不會涉及。例如,我們在date_inserted和user_inserted列上有默認值,用戶甚至不知道它們在那裏。如果許多不同的應用程序可以填充數據以確保沒有人忘記這些列,這一點尤其重要。

然後有一些列在數據錄入時會給出一個值,以後可能會改變。像狀態欄這樣的東西。

許多列不能真正具有默認值。什麼是用戶的默認地址或名稱?

+0

你所做的一個區別似乎取決於數據是真的「信息」還是隻是看家?用戶的電話號碼是關於有問題的實體(特定用戶)的一段數據。記錄添加或更改的時間不是。從某種意義上說,這些東西根本不是「信息」,更像審計線索。一種解決方案是將所有內務管理信息(內部和外部主鍵,添加時間和更改時間以及由誰發出,是否將記錄標記爲已刪除等)存儲在實際數據的單獨表格中。然後,您可以刪除數據並分發該更改。 – 2016-09-06 20:04:56

1

以下是我個人使用的關於默認值的指導原則,這些指導原則對我來說很好。在以下示例中,請考慮具有多個應用程序並具有對後端的讀/寫訪問權限的數據庫後端。在這些情況下,數據庫必須定義如何對數據進行建模,從而確保數據的完整性。

1)CreatedDate和ModifiedDate列。這些列通常會將getdate()(sql server)定義爲默認值。如其他帖子所述,這些字段可以隨後用觸發器等更新。

2)布爾狀態列。示例:「IsDefault」,「IsDeleted」(用於審計),「IsActive」等。所有這些字段通常都會有一個邏輯默認狀態,應該由數據模型來定義。對此的例外顯然是可空的三態布爾字段,其中null狀態表示關於存儲在記錄中的數據的某些內容。

3)數據約束定義:AllowNull = false且沒有默認定義的列。換句話說,應用程序需要一個值。

4)查找表外鍵標識:這可能不是常態,但對於很多查找表外鍵我將定義一個默認值,其中包含記錄的初始狀態。因此,例如,在「Event」表中,外鍵列「EventTypeId」(int-autoincrement)將具有默認值1並表示「常規」或其他內容。這將涵蓋大多數情況下,例如,我想記錄一個事件,但不關心特定的類型ID。

5)非關鍵字符串列:「Description」,「Comment」等。對於這些列,我通常將''默認定義爲簡化System.DbNull =>空應用程序中的空值轉換處理。這可能不適用於所有情況,特別是當有關表包含數百萬行並且存儲空間是問題時。

所以總之,使用默認值來確保存儲在數據庫中的實際數據的數據完整性。數據模型應該在其自身內定義這些數據完整性規則,並且任何與其交互的應用程序都將被強制遵守這些規則。另請注意,這不是教義,並且總會有例外。分別考慮每種情況,以便對您的數據庫/應用程序有意義。

1

tl; dr:默認值是業務邏輯,我希望在對象模型中使用業務邏輯。因此,數據庫不能包含默認值。

E.g.在數據庫中我有一個位域:IsANicePerson。此字段轉換爲Person類上的屬性。本質上樂觀,我想這個屬性的默認值是'真'。所以在Person類中我實現了這個(作爲isANicePerson後臺字段的默認值)。如果我會允許數據庫中的默認值,我將不得不復制這個邏輯。重複的代碼/邏輯是不好的。因此我反對默認值。

聲明:我住在OO世界並使用Linq2Sql。