我有四张桌子,即
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;
谢谢..
答案 0 :(得分:2)
答案 1 :(得分:1)
如果输入不匹配的数据,第二个版本将导致严重的问题。获取以下示例数据:
countries: Canada, USA
states: Saskatchewan, Michigan
cities: Saskatoon, Detroit
zipcode: 90210 (california)
insert into area (...) ('Canada', 'Michigan', 'Saskatoon', 90210)
所有单独有效,但整个记录完全错误。然而,按照你的设计,它应该是有效的。
答案 2 :(得分:0)
这可能取决于您将在这些表上运行哪些查询。通常,A是标准化的,而B不是(A将使用更少的空间)。
答案 3 :(得分:0)
我将从方法A开始,但如果结果表明性能需要链中的其他列,我只会根据需要添加它们。
请确保制作_id列索引。
答案 4 :(得分:0)
乍一看我更喜欢方法A,但是如果不知道你想要的关系和约束的具体细节,就不可能断然说一个人比另一个人“更好”。遵循您的应用程序的功能要求。
恭喜您寻求规范化的方法:很高兴看到它!
答案 5 :(得分:0)
我个人会选择第一个[方法A]。例如,如果您知道某个区域的城市ID,则会自动知道状态ID和国家/地区ID。虽然第二个可能会更方便,但如果说城市搬到了另一个州,你可能会遇到问题。
答案 6 :(得分:0)
最好从标准化表格开始。如果您的RDBMS自动管理缓存的列更新,我只会建议方法B.例如,如果您错误地将洛杉矶放置在密歇根州,则需要更新多个位置(除非您有触发器会更新非规范化表中的级联信息)。但是没有触发器,方法A毫无疑问是最好的形式。
当然,假设在查看方法A的定义时,您的约束与通用解释隐含的约束相匹配。