Sql-Server

事實表主鍵:代理鍵還是多列自然鍵?

  • July 26, 2018

選擇事實表的主鍵(PK 為簡潔)時的最佳做法是什麼:我們應該使用自動遞增的代理鍵 (SK),還是應該使用自然鍵 (NK) 列?

我在使用 SK 時看到的優勢是 INSERT 性能,當我們每天插入近一百萬行時,這是非常相關的,這就是我的情況。我預計每天將近 2000 萬行,每月 200M 行,並且該表必須在未來幾十年內維持數據而無需拆分。

但是如果我們有一個 NK 作為 PK,查詢性能應該會更好,並且 PK 的順序設計得很好。

當然,我們可以為查詢創建非聚集索引,但這會佔用儲存空間並使 INSERT 更慢。

考慮到 INSERT 和 DELETE(是的,我們也有很多,因為數據被重新處理並且新文件版本必須“更新”)性能非常相關,幾乎與查詢性能一樣,什麼是最好的?

另一個需要考慮的問題是,當刪除行時,SK 計數不會減少。每月有 200M 行,我每年將有 2,4G 行,其中 int 數據類型將不存在,所以我需要使用 bigint 進行 PK ……

上下文是什麼?聽起來您在談論數據倉庫。如果是這樣,我強烈建議創建一個合成密鑰。我可以想到三個很好的理由,即興發揮:

  • 它將比業務密鑰更窄。雖然向事實表添加列不應該輕易完成,因為它會使您的其他索引變窄,它實際上可能會減少數據庫的總大小。
  • 自然鍵變髒。遲早會有人將產品程式碼重複用於不相關的事情,或者您需要開始跟踪子客戶。如果您在自然鍵和合成鍵之間有一個映射過程,那麼很容易解釋這些事情。
  • 您可以使用它來儲存合成值:-1 表示“不適用”,0 表示“未知”,1 表示“缺失”,2 表示“難以辨認”,等等。根據您的自然鍵,您可能能夠做到那裡也一樣,但總會有碰撞的風險。

48+ 十億條記錄很多。如果您還沒有,您應該考慮聚合數據,也許在本月之後。合成密鑰也可以使這變得更簡單:也許值 1,000,000,001..1,999,999,999 保留用於 2017/08 年的詳細資訊,並且在 10 月,8 月的數據被折疊到 ID 為 1,000,000,000 的單個記錄中(這可能不是一個好主意,它只是您可能需要如何將業務密鑰與倉庫密鑰斷開連接的範例)。

最後一點:不要忘記您對 PK 和集群密鑰的選擇絕不需要相同!每個人都應該根據自己的優點進行評估。

在星型模式的事實表中,合成鍵(代理,自動遞增)將沒有用處。事實表中所有外鍵的組合是候選鍵,perforce。否則,恆星的形成就不是很好。如果您願意,可以將其聲明為主鍵。我選擇這樣做。

但是,如果您有一個非常緊湊的 ETL 程序來定期更新星號,那麼您實際上可以在根本不聲明主鍵的情況下擺脫困境。

我贊同你所說的關於性能的說法。

引用自:https://dba.stackexchange.com/questions/184815