2010-01-13 48 views
4

我有這樣的數據庫,我設計。負整數索引:它們是邪惡的嗎?

它需要包含與我們提供的記錄一對夫婦十幾桌(一堆默認的),以及用戶可以添加記錄。爲了防止用戶在腳下自拍,有必要防止他修改默認記錄。

有很多方法來推動這項工作,但我喜歡的給予保護的記錄負整數索引的想法,同時保留0作爲無效記錄ID,並給用戶記錄正整數索引。

CREATE TABLE t1 (
    ixt1 integer AUTOINCREMENT, 
    d1 double, 
    CONSTRAINT pk_ixt1 PRIMARY KEY (ixt1), 
    CONSTRAINT ch_zero CHECK (ixt1 <> 0) 
); 

-2 | 171.3 <- canned record 
-1 | 100.0 <- canned record 
1 | 666.6 <- user record 

原因,這似乎不錯:

  • 它不使用顯著更多的空間

  • 很容易理解

  • 它不需要大量的附加表實施

  • 「選擇表*」獲取所有的相關記錄,沒有額外的間接

  • 罐頭記錄可以在負方向生長,並且用戶記錄可以在正方向生長

然而,我對數據庫設計比較陌生。而使用這種解決方案一小會兒後,我開始擔心,使用負索引可能是壞的,因爲

  • 負指標可能無法始終如一地不同的DBMS之間的支持,因此很難編寫代碼,是數據庫無關的

  • 它可能是太容易通過recid 0

  • 插入的東西它可能使它很難用工具擰東西了(如DB網格,也許),其期望與整數索引非負值。

也許還有一些其他真正明顯的原因會使這是一個非常糟糕的想法。

那麼,有什麼明確的答案?負整數索引是否邪惡?

+1

我注意到你在這個主鍵上有'AUTOINCREMENT',這怎麼會最終與你的策略一起工作?你是手動計算所有新記錄的正確主鍵還是私人(負)記錄? – Nicole 2010-01-13 17:12:54

+0

只有私鑰(負)纔會被明確設置。順便提一句,我不知道這個特定的SQL語法在任何DBMS上都能工作。這只是爲了說明。 – 2010-01-13 17:48:41

回答

13

其中最重要的缺陷是「智能鑰匙」問題。

負整數正常工作的關鍵。在所有數據庫中。

沒有工具需要正整數索引值。

這很容易搞砸了,因爲索引有一個「規則」,這是不明顯的,沒有人會記得中彩票和離開後。當你發明第三個狀態代碼('預罐裝'與'客戶特定罐裝'相對'另一個罐裝產品'發明'與'舊罐裝3版'之前')時,你註定了。

「智能鑰匙」的問題是您要求鑰匙做兩個不相關的工作。

  1. 這是記錄的唯一標識符。這就是關鍵所在。

  2. 您還要求它提供狀態,控制和授權以更改屬性。哎呀。這充滿了危險。你無法擴大意義,因爲它只是一個隱藏在密鑰中的位。

只需添加一列「擁有」。如果它屬於「神奇的超級用戶」,那麼它不會顯示給用戶。如果您不能相信應用程序開發人員執行此操作,請使用VIEW來保證這一點。

如果它屬於「神奇的超級用戶」,那麼它就是默認數據,並且任何規則適用於該所有權。

+1

+1使關鍵做兩個工作。一把鑰匙是一把鑰匙,這就是它應該需要的一切。通過添加其他列來增加行的特殊性。 – Parrots 2010-01-13 17:17:11

+0

壞主意。負整數索引不是邪惡的,但你的設計並不明顯。 「易於理解」,可能。但立即從架構明顯,沒有。 最好有一個名爲is_canned或is_protected的布爾/位列。 – 2010-01-13 17:30:15

+0

+1高亮顯示第三狀態的可能性 – MikeD 2010-01-13 20:06:51

6

我工作一個非常大的結算系統。我們有一個非常類似的問題......需要將某些記錄標記爲「特殊」。客戶在其受影響的表中的數據庫中有數千萬行現有數據,並且認爲將所有數據遷移到新結構(即添加列)是不可接受的。

決定採取了你的建議。

問題在於,您需要每一點業務邏輯來了解(並記住)負指數的特殊含義並正確對待它。這很容易出錯(根據經驗)。

除非您有非常強烈的支持這種非傳統方法的異常情況,否則我建議您堅持使用更傳統的額外色譜柱。這是大多數開發人員習慣的,因此不太可能導致錯誤。我希望我們能夠咬住子彈並添加額外的列。

+0

+1「所有商業邏輯必須知道的特殊含義」。 – 2010-01-13 17:17:02

+1

我真的很感謝這是來自經驗。但在我看來,就難度而言,增加額外的列將是等同的。如果你添加了一個額外的列而不是使用負向索引,你的代碼會有什麼不同? – 2010-01-13 19:28:48

+0

我認爲最大的問題是開發人員(現在都是這樣,而且在5年內保持這種狀態的人在你做得更好時)會期望將其作爲一個專欄進行建模,而不是對專欄的數值應用特殊解釋指數。其他人也指出,如果將來需要額外的「特殊」含義,這種設計無法擴展,因此人們必須檢查索引的符號,並檢查列是否有新的狀態。 – 2010-01-13 19:37:51

1

這是你的數據,但我不認爲這是一個好主意。像這樣的「索引」值應該是沒有意義的 - 不要使用符號或數字範圍,或者用其他任何詞來表示「某事」或「其他」。我認爲,從長遠來看,有一個'記錄類型'的專欄清楚地表明您正在查看哪種類型的記錄。根據我的經驗,這是一個更好的方法。

祝你好運。