2012-01-12 76 views
1

一目瞭然,數據庫架構是這樣的:如何最好地設計DB在這種情況下

enter image description here

架構必須處於第三範式(和我知道hotels.average_rating否則建議,試圖監督這一點,因爲數據庫還沒有完全設計)。這是一個旅遊推薦系統。

的SQL:

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; 
SET time_zone = "+00:00"; 

CREATE TABLE `activities` (
    `activity_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `activity_name` varchar(277) COLLATE utf8_bin NOT NULL, 
    PRIMARY KEY (`activity_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

CREATE TABLE `bookings` (
    `from_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    `to_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `belong_user` int(10) unsigned NOT NULL, 
    `belong_hotel` int(10) unsigned NOT NULL, 
    `rating` int(3) unsigned NOT NULL, 
    KEY `belong_user` (`belong_user`), 
    KEY `belong_hotel` (`belong_hotel`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

CREATE TABLE `countries` (
    `cuntry_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `country_name` varchar(20) COLLATE utf8_bin NOT NULL, 
    PRIMARY KEY (`cuntry_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

CREATE TABLE `hotels` (
    `hotel_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `hotel_name` varchar(128) COLLATE utf8_bin NOT NULL, 
    `hotel_stars` int(3) NOT NULL, 
    `hotel_description` text COLLATE utf8_bin NOT NULL, 
    `average_price` float unsigned NOT NULL, 
    `average_rating` float unsigned NOT NULL, 
    `total_rooms` int(10) unsigned NOT NULL, 
    `free_rooms` int(10) unsigned NOT NULL, 
    `belong_region` int(10) unsigned NOT NULL, 
    PRIMARY KEY (`hotel_id`), 
    KEY `belong_region` (`belong_region`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

CREATE TABLE `hotels_activity_offers` (
    `belong_hotel` int(10) unsigned NOT NULL, 
    `belong_activity` int(10) unsigned NOT NULL, 
    UNIQUE KEY `belong_hotel_2` (`belong_hotel`,`belong_activity`), 
    KEY `belong_hotel` (`belong_hotel`), 
    KEY `belong_activity` (`belong_activity`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

CREATE TABLE `regions` (
    `region_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `belong_country` int(10) unsigned NOT NULL, 
    `region_name` varchar(255) COLLATE utf8_bin NOT NULL, 
    PRIMARY KEY (`region_id`), 
    KEY `belong_country` (`belong_country`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

CREATE TABLE `regions_activity_offers` (
    `belong_region` int(10) unsigned NOT NULL, 
    `belong_activity` int(10) unsigned NOT NULL, 
    KEY `belong_region` (`belong_region`), 
    KEY `belong_activity` (`belong_activity`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

CREATE TABLE `users` (
    `user_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `username` varchar(20) COLLATE utf8_bin NOT NULL, 
    `password` varchar(40) COLLATE utf8_bin NOT NULL COMMENT 'MD5', 
    `first_name` varchar(20) COLLATE utf8_bin NOT NULL, 
    `last_name` varchar(20) COLLATE utf8_bin NOT NULL, 
    `email` varchar(255) COLLATE utf8_bin NOT NULL, 
    `is_admin` tinyint(1) NOT NULL, 
    `is_active` tinyint(1) NOT NULL, 
    PRIMARY KEY (`user_id`), 
    KEY `is_active` (`is_active`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

CREATE TABLE `users_favourite_activities` (
    `belong_user` int(10) unsigned NOT NULL, 
    `belong_activity` int(10) unsigned NOT NULL, 
    UNIQUE KEY `belong_user_2` (`belong_user`,`belong_activity`), 
    KEY `belong_user` (`belong_user`), 
    KEY `belong_activity` (`belong_activity`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 


ALTER TABLE `bookings` 
    ADD CONSTRAINT `bookings_ibfk_3` FOREIGN KEY (`belong_hotel`) REFERENCES `hotels` (`hotel_id`) ON DELETE CASCADE, 
    ADD CONSTRAINT `bookings_ibfk_2` FOREIGN KEY (`belong_user`) REFERENCES `users` (`user_id`) ON DELETE CASCADE; 

ALTER TABLE `hotels` 
    ADD CONSTRAINT `hotels_ibfk_1` FOREIGN KEY (`belong_region`) REFERENCES `regions` (`region_id`) ON DELETE CASCADE; 

ALTER TABLE `hotels_activity_offers` 
    ADD CONSTRAINT `hotels_activity_offers_ibfk_2` FOREIGN KEY (`belong_activity`) REFERENCES `activities` (`activity_id`) ON DELETE CASCADE, 
    ADD CONSTRAINT `hotels_activity_offers_ibfk_1` FOREIGN KEY (`belong_hotel`) REFERENCES `hotels` (`hotel_id`) ON DELETE CASCADE; 

ALTER TABLE `regions` 
    ADD CONSTRAINT `regions_ibfk_1` FOREIGN KEY (`belong_country`) REFERENCES `countries` (`cuntry_id`) ON DELETE CASCADE; 

ALTER TABLE `regions_activity_offers` 
    ADD CONSTRAINT `regions_activity_offers_ibfk_2` FOREIGN KEY (`belong_activity`) REFERENCES `activities` (`activity_id`) ON DELETE CASCADE, 
    ADD CONSTRAINT `regions_activity_offers_ibfk_1` FOREIGN KEY (`belong_region`) REFERENCES `regions` (`region_id`) ON DELETE CASCADE; 

ALTER TABLE `users_favourite_activities` 
    ADD CONSTRAINT `users_favourite_activities_ibfk_1` FOREIGN KEY (`belong_user`) REFERENCES `users` (`user_id`) ON DELETE CASCADE, 
    ADD CONSTRAINT `users_favourite_activities_ibfk_2` FOREIGN KEY (`belong_activity`) REFERENCES `activities` (`activity_id`) ON DELETE CASCADE; 
  1. 的問題是:如何最好添加一個「用戶活動日誌」功能,存儲用戶已經參加的活動?請注意,這兩個地區和酒店都可以舉辦活動,而且我需要知道該活動是發生在某個地區還是酒店。參照完整性應得到保證。

  2. 現在查詢(它應該使用JOIN不應該嗎?)其中列出了所有用戶和他們的活動與酒店ID 區域ID一起。(如果需要,不適用的可以是NULL)。

簡單的解決方案更 - 所以最好不用存儲過程或任何其挖太多的MySQL特定的功能。

+1

類似的,如果不是相同的話,可以這樣:http://stackoverflow.com/questions/5537779/multiple-tables-need-one-to-many-relationship – bububaba 2012-01-12 14:31:42

+0

酒店屬於地區。區域活動報價是否適用於該區域內的所有酒店,還是地區活動報價與酒店活動報價完全無關? – 2012-01-12 14:36:44

+0

一個活動可以直接屬於一個地區,就像你在圖片中看到的那樣。例如「滑雪」。當然,也可以提供酒店的滑雪優惠(例如:全包)。然而他們是「不」相關的。 – Flavius 2012-01-12 15:21:57

回答

-1

你的數據庫沒有正常化 - 你做這件事的方式看起來像一個海報孩子,爲什麼規範化是一個好主意。

hotels.average_rating?

WTF?

儘管可以對數據進行非規範化處理是有意義的,但這不是如何去做的。考慮用戶提交酒店評級時需要做什麼 - 您需要根據提交的所有評級重新計算價值。相反,如果您持有sum_of_ratings(甚至保留了當前的平均值)許多評分,則可以根據酒店記錄和新評分計算新值,而無需查看其他評分。

+0

想象一下,當你想到真正的問題的解決方案時,該領域暫時不存在。請改善您的答案,以便它也回答我的問題。 > WTF 將被固定在最終的數據庫中,請不要擔心:-) – Flavius 2012-01-12 16:05:12