可以在關係數據庫中添加表年份嗎?
我如何向我的同事解釋這是不必要的複雜性和冗餘數據?
他想要一張年份表,因為許多表都有“年份”值,而且他還想要有名稱和年份的關係表,這會增加不必要的內部連接和外來我堅持認為這是錯誤的,我只想確保這不是一個好習慣……
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
) 以便每個人都可以輕鬆地引用它。在表格中,您有一個可列印的名稱、一個位置、一個“點贊”計數器等。