Sql-Server

可以在關係數據庫中添加表年份嗎?

  • February 10, 2020

我如何向我的同事解釋這是不必要的複雜性和冗餘數據?

他想要一張年份表,因為許多表都有“年份”值,而且他還想要有名稱和年份的關係表,這會增加不必要的內部連接和外來我堅持認為這是錯誤的,我只想確保這不是一個好習慣……

數據庫圖圖片

vehicle_year應該是數據類型YEAR

日期應該是 datatype DATE。即使您需要將日期拆分為其組成部分,這樣做幾乎總是比使用包含日期及其部分的維度表更好。

一般來說,不要*“*規範化”任何“連續”值——日期、整數、浮點數等。

正如 kevensky 指出的那樣,對於需要在缺失年份(或其他任何內容)顯示零的“報告”,有一個案例可以朝另一個方向發展。但這並沒有以任何方式連結到主表。相反,它被用來像

SELECT y.year,
      COALESCE(SUM(m.stuff), 0),
      ...
   FROM Years AS y
   LEFT JOIN my_table AS m
   GROUP BY...

請注意如何LEFT JOIN包括 Years 表中的所有年份。(您可能希望使用WHERE子句來限制範圍。)

COALESCE是用來把NULL缺失的年份變成0。或N/A。或No data。管他呢。

雖然我在這裡,但我建議規範化“模型”也是“過度規範化”。Vehicle表格中拼出的型號名稱非常好。

什麼時候應該正常化?

  • 不是唯一的——人們的名字。
  • 當值可能發生變化時——車主(但這需要一個多:多表)
  • 有很多輔助數據——公司(有地址等)
  • 節省空間——名字長,桌子大;不適用於 2-letter country_code 與 4-byte INT

型號年份是自我辨識的,從不改變,不大,沒有輔助數據。

車輛品牌和型號大多與車型年份相似。同樣適用於發動機尺寸、顏色、價格等。

讓我提出一個假設性的問題:“雪佛蘭生產他們的 Impala 模型是幾年(model_years,即)?”

這可以通過“SELECT DISTINCT model_year FROM Vehicle WHERE make = …;”來回答。這可以從表中可用的車輛中得到答案。

或者,您可能從列出答案的歷史網站上獲得它。現在你需要一張桌子,上面有PRIMARY KEY(make, model)關於舊車歷史的各種資訊。

這導致了一個更混亂的情況——分層資訊。注:通用 > 雪佛蘭 > Impala > LT。“位置”有類似的問題:美國 > 喬治亞 > 富爾頓縣 > 亞特蘭大 > 地址。通常,每個級別的規範化都是大材小用,應該避免。

因為許多表都有“年份”值

好吧,規範化的“教科書”論點在這裡慘敗。它說您應該規範化,以便將值放在一個位置以便於更改。但是,如果這year代表車輛的 model_year 在一張桌子上,但您孩子的生日在另一張桌子上,而您的畢業日期在另一張桌子上,您當然不希望更改該值。

將規範化表想像成一個“實體”,例如一個人、一個地方、一個公司、一張圖片、一個網路文章等。你給實體一個唯一的標識符 ( PRIMARY KEY) 以便每個人都可以輕鬆地引用它。在表格中,您有一個可列印的名稱、一個位置、一個“點贊”計數器等。

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