簡體   English   中英

這是此數據庫設計的正確方法

[英]which is the correct way for this database design

我有四個表,即

countries,states,cities,areas

這將是我的數據庫表的最佳可行解決方案

方法A:

CREATE TABLE IF NOT EXISTS `countries` (
`id` int(11) auto_increment NOT NULL,
`name` varchar(50) NOT NULL,
PRIMARY KEY  (`id`),
UNIQUE(`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `states` (
`id` int(11) auto_increment NOT NULL,
`name` varchar(50) NOT NULL,
`country_id` int(11) NOT NULL,
PRIMARY KEY  (`id`),
UNIQUE(`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `cities` (
`id` int(11) auto_increment NOT NULL,
`name` varchar(50) NOT NULL,
`state_id` int(11) NOT NULL,
PRIMARY KEY  (`id`),
UNIQUE(`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `areas` (
`id` int(11) auto_increment NOT NULL,
`name` varchar(50) NOT NULL,
`zipcode` int(11) NOT NULL,
`city_id` int(11) NOT NULL,
PRIMARY KEY  (`id`),
UNIQUE(`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

方法B:

CREATE TABLE IF NOT EXISTS `countries` (
`id` int(11) auto_increment NOT NULL,
`name` varchar(50) NOT NULL,
PRIMARY KEY  (`id`),
UNIQUE(`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `states` (
`id` int(11) auto_increment NOT NULL,
`name` varchar(50) NOT NULL,
`country_id` int(11) NOT NULL,
PRIMARY KEY  (`id`),
UNIQUE(`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `cities` (
`id` int(11) auto_increment NOT NULL,
`name` varchar(50) NOT NULL,
`state_id` int(11) NOT NULL,
`country_id` int(11) NOT NULL,
PRIMARY KEY  (`id`),
UNIQUE(`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `areas` (
`id` int(11) auto_increment NOT NULL,
`name` varchar(50) NOT NULL,
`zipcode` int(11) NOT NULL,
`city_id` int(11) NOT NULL,
`state_id` int(11) NOT NULL,
`country_id` int(11) NOT NULL,
PRIMARY KEY  (`id`),
UNIQUE(`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

謝謝..

第一種不太可能出現同步問題。

第二種將通過非規范化提供更好的性能。

可能的相關線程: 什么是使mysql數據庫非規范化的好方法?

如果輸入的數據不匹配,則第二個版本將導致嚴重的麻煩。 取得以下樣本數據:

countries: Canada, USA
states: Saskatchewan, Michigan
cities: Saskatoon, Detroit
zipcode: 90210 (california)

insert into  area (...) ('Canada', 'Michigan', 'Saskatoon', 90210)

全部單獨有效,但整個記錄完全錯誤。 但是,根據您的設計,它應該是有效的。

這可能取決於要在這些表上運行的查詢。 通常,將A標准化,而將B標准化(A將使用較少的空間)。

我將從方法A開始,但是如果事實證明性能需要在鏈的更下游添加其他列,則僅根據需要添加它們。

只要確保使_id列索引即可。

我乍看之下更喜歡方法A,但是在不了解您想要的關系和約束條件的具體細節的情況下,不可能一概而論地說一個比另一個更好。 遵循應用程序的功能要求。

恭喜您尋求標准化方法:很高興看到!

我個人會選擇第一個[方法A]。 例如,如果您知道某個地區的城市ID,那么您將自動知道州ID和國家ID。 雖然第二個可能更方便,但是如果說某個城市搬到另一個州,您可能會遇到很多問題。

最好總是從規范化形式開始。 如果您讓RDBMS自動管理緩存的列更新,我只會建議方法B。 例如,如果您錯誤地將洛杉磯放置在密歇根州,則需要更新多個位置(除非您有觸發器可以更新非規范化表中的級聯信息)。 但是,如果沒有觸發器,方法A無疑是最佳形式。

當然,這是假定您的約束與查看方法A的定義時由常見解釋隱式規定的約束匹配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM