Database-Design
有兩個相同的實體,除了 1 個不同的屬性
在數據庫設計任務的範例場景中,一家公司提供酒店房間(分為兩個實體 - 酒店和房間)和公寓。因此數據庫將包含以下實體:
Hotel (hotelNo(PK), name, address, telephone) Room (roomNo(PK), hotelNo(PK), dailyRentalRate) Apartment (apartmentNo(PK), address, numberOfRooms, dailyRentalRate)
在規範中,公司希望數據庫包含一個儲存以下數據的檢查實體:
- 檢查日期,
- 房間/公寓的狀況,
- 進行檢查的工作人員。
- 酒店和房間號和公寓號取決於檢查是在酒店房間還是公寓上。
我的問題是最好將其拆分為兩個實體,如下所示,或者擁有一個實體(也如下所示),該實體的酒店和房間號都為空值(當檢查是針對公寓時),或公寓號碼(當檢查是酒店房間時)。
兩個獨立的實體:
HotelInspection (hotelInspectionNo, date, condition, staffNo(FK), roomNo(FK), hotelNo(FK)) ApartmentInspection (apartmentInspectionNo, date, Condition, staffNo(FK), apartmentNo(FK))
一個實體:
Inspection (inspectionNo, date, condition, staffNo(FK), roomNo(FK), hotelNo(FK), apartmentNo(FK))
如果我是你,我會做如下的事情:
(tl;dr) - 你應該有一個檢查實體 - 它們相距一縷頭髮,在這種情況下,本質上是一回事!稍微修改您的架構會使它們變得相同。
CREATE TABLE location -- "master" room/apartment (could be called "accomomation" or similar) ( location_id INTEGER PRIMARY_KEY, location_type VARCHAR (10) NOT NULL, -- CHECK accommodation_type IN ('Hotel', 'Appartment'), could also have 'Hostel', 'AirBNB', 'Tent'... -- MySQL doesn't support `CHECK` constraints - use a lookup table! location_name VARCHAR (25), -- colloquial name location_phone VARCHAR (20) -- either the switch or owner's mobile/cell. );
筆記:
表名全部小寫 - 易於閱讀:SQL 大寫,標識符小寫,下劃線。
總是(取決於您的 RDBMS - 儘管現在所有主要的 RDBMS 都符合),給您
PRIMARY KEY
的 s、FOREIGN KEY
s 和UNIQUE INDEX
es(即所有數據庫對象)提供有意義的名稱 - 使調試更容易。您會注意到我為我的欄位輸入了長名稱 - 這是因為
- a) 更易於調試,並且,
- b) 程式碼/程序 99% 的時間都花在維護上——輸入幾個額外的字元是為了讓生活更輕鬆而付出的小代價!
永遠不要使用關鍵字(例如
DATE
)作為表名或列名!使用帶引號的標識符 &c 讓生活陷入困境。
NULL
始終嘗試減少(在合理範圍內)架構中可以輸入 s的點數。它使邏輯更容易,並且可以幫助優化器!我的大部分列定義都可以跟在NOT NULL
下面!您可能還想查看此站點以獲取其他想法。我的想法只是“第一關”。
CREATE TABLE hotel ( hotel_id INTEGER PRIMARY KEY, hotel_name VARCHAR (50) NOT NULL, -- full business name hotel_address INTEGER, -- FK reference to address table? ); CREATE TABLE room ( room_id INTEGER PRIMARY KEY, -- as opposed to room_no - room numbers in hotels can change, renovations, buidling works! location_id INTEGER, -- FK to location. Also `UNIQUE INDEX` to prevent dups. hotel_id INTEGER, -- FK to hotel room_no INTEGER, room_rate INTEGER -- FLOAT/DECIMAL/whatever ); CREATE TABLE apartment ( apartment_id INTEGER PRIMARY KEY location_id INTEGER, -- FK to location! Also, `UNIQUE INDEX` to prevent dups! apartment_address INTEGER, -- FK to address table apartment_room_count INTEGER, apartment_rate INTEGER -- FLOAT, DECIMAL... ); CREATE TABLE location_rating ( location_rating_id INTEGER NOT NULL PRIMARY KEY, -- if possible give your PK a meaningful name. accomodation_rating_text VARCHAR (20) NOT NULL ); INSERT INTO accomodation_rating VALUES (1, 'Call the police!'), (2, 'Totally unaccptable'), (3, 'Very poor'), (4, 'Poor'), (5, 'Acceptable'), (6, 'Reasonable'), (7, 'Good'), (8, 'Very good'), (9, 'Excellent'), (10, 'Kiss the cleaners!'); CREATE TABLE inspection ( inspection_id INTEGER PRIMARY KEY, accommodation_id INTEGER, -- FK to accomodation inspection_date DATE, -- more meaningful than just date - anyway, NEVER call a table or field by a KEYWORD! inspection_rating INTEGER, -- FK to your accomodation_rating table - NEVER allow people to write free text if possible! -- NOW, no need for hotelNo or apartmentNo - plus no NULLs! );