Mysql
最大正規化
我一直在研究範式規則來指導我進行數據庫設計和數據儲存,我遇到的問題是,一旦我優化了第一個範式(1NF),我想我可能會一直走下去(即使不是強制性的)。
然而,在我的設計中出現了一個我在網上或書籍中沒有遇到的例子。
一個範例概念。
我們希望儲存有關某些汽車變體的所有數據。
我們必須儲存品牌、系列、型號、開始年份、結束年份的值。
非標準化
+------+--------+-------+------------+----------+ | make | series | model | start year | end year | +------+--------+-------+------------+----------+ | BMW | 5 | E12 | 1972 | 1981 | | BMW | 5 | E28 | 1981 | 1988 | | BMW | 5 | E34 | 1988 | 1996 | | BMW | 5 | E39 | 1995 | 2004 | +------+--------+-------+------------+----------+
正規化
car_make +----+------+ | id | make | +----+------+ | 1 | BMW | +----+------+ car_series +----+--------+---------+ | id | series | make_id | +----+--------+---------+ | 1 | 1 | 1 | | 2 | 3 | 1 | | 3 | 5 | 1 | | 4 | 7 | 1 | +----+--------+---------+ car_model +----+-------+------------+----------+-------- --+ | id | model | start year | end year | series_id | +----+-------+------------+----------+-----------+ | 1 | E12 | 1972 | 1981 | 3 | | 2 | E28 | 1981 | 1988 | 3 | | 3 | E34 | 1988 | 1996 | 3 | | 4 | E39 | 1995 | 2004 | 3 | +----+-------+------------+----------+-----------+
最後一張表中出現了一個問題,我是否還應該在 car_model 表中包含一列 make_id ?
這是有益的,因為我不必加入 car_series,然後選擇 make_id,通過 id 選擇 make,但是我相信這可能不會堅持規範化,因為我會重複數據(即使它是一個 id 它仍然重複) .
這個設計可以進一步規範化嗎?
關於開始年和年末處理的另一個注意事項,您的專業人士將如何做到這一點?如果有任何範圍技巧來強製完整性,我很好奇(儘管 E39 重疊,讓我們說好像沒有日期重疊)。
提前感謝您的任何想法。
不,您不應該在 car_model 表中包含列 make_id,它由 series_id 隱式定義。如果您需要查看製作詳細資訊,您可以製作一個看起來像未規範化表的視圖。
不,這種設計不能進一步標準化。
要強制年份範圍不重疊,您可以添加一個觸發器(因為 MySql 不支持檢查約束)以確保
start_year >= max(end_year)
和end_year >= start_year
.觸發器看起來像這樣:
create trigger trg_car_model_date_range_unique before insert on car_model for each row begin if new.start_year < (select max(end_year) from car_model) then signal sqlstate '45000' set message_text = 'Date range is not unique'; end if; if new.end_year < new.start_year then signal sqlstate '45000' set message_text = 'Date range is invalid'; end if; end