Sql 数据库规范化混乱?
我有5张桌子:Sql 数据库规范化混乱?,sql,normalization,Sql,Normalization,我有5张桌子: TBL省 特伯迪森 TBL严格 tblCity TBL稳定性 tblprovance: 身份证 名字 区域 TblDivision: 身份证 名字 区域 省id tblDistrict: 身份证 名字 区域 省id 部门id tblCity: 身份证 名字 区域 省id 部门id 区号 tblconstance: 身份证 名字 区域 省id 部门id 区号 城市标识 这是存储数据的正确方法吗?添加该区域的完整细节 或者我应该只保存上一个区域的id(比如城市是选
tblprovance
:
- 身份证
- 名字
- 区域
TblDivision
:
- 身份证
- 名字
- 区域
- 省id
tblDistrict
:
- 身份证
- 名字
- 区域
- 省id
- 部门id
tblCity
:
- 身份证
- 名字
- 区域
- 省id
- 部门id
- 区号
tblconstance
:
- 身份证
- 名字
- 区域
- 省id
- 部门id
- 区号
- 城市标识
tblCity
+-------------+
| ID |
+-------------+
| Name |
+-------------+
| Area |
+-------------+
| District_id |
+-------------+
TblConstituency
+-------------+
| ID |
+-------------+
| Name |
+-------------+
| Area |
+-------------+
| City_id |
+-------------+
若我想得到选区的完整细节,我可以得到城市的id,从城市我可以得到地区,从地区我可以得到分区等等
但是,我觉得这是一个巨大的过度杀伤力。每次我需要获得详细信息时,这将是一个很长的查询
那么,最好的方法是什么
附言:很抱歉,我的问题描述得很糟糕。不要将同一信息存储两次。这意味着您必须手动保持该信息的同步,而且同步很困难且容易出错。基本上,任何时候你有多个真相来源,你就没有真相来源 考虑一下您的桌子:
Division
+-------------+
| ID |
+-------------+
| Name |
+-------------+
| Area |
+-------------+
| Province_id |
+-------------+
District
+-------------+
| ID |
+-------------+
| Name |
+-------------+
| Area |
+-------------+
| Province_id |
+-------------+
| Division_id |
+-------------+
部门
已在存储省id。那么为什么地区也需要存储它呢?如果地区
存储的省id
与其对应的分区
记录不同,会发生什么情况?对于该地区
,哪一个是正确的
只需链接到直接父记录:
District
+-------------+
| ID |
+-------------+
| Name |
+-------------+
| Area |
+-------------+
| Division_id |
+-------------+
与部门
表相关的信息已经存在,可以查询。(基本上,JOIN
关键字就是为了这个目的。)既然你已经有了这些信息,你就不需要重复了。永远不要存储相同的信息两次。这意味着您必须手动保持该信息的同步,而且同步很困难且容易出错。基本上,任何时候你有多个真相来源,你就没有真相来源
考虑一下您的桌子:
Division
+-------------+
| ID |
+-------------+
| Name |
+-------------+
| Area |
+-------------+
| Province_id |
+-------------+
District
+-------------+
| ID |
+-------------+
| Name |
+-------------+
| Area |
+-------------+
| Province_id |
+-------------+
| Division_id |
+-------------+
部门
已在存储省id
。那么为什么地区也需要存储它呢?如果地区
存储的省id
与其对应的分区
记录不同,会发生什么情况?对于该地区
,哪一个是正确的
只需链接到直接父记录:
District
+-------------+
| ID |
+-------------+
| Name |
+-------------+
| Area |
+-------------+
| Division_id |
+-------------+
与部门
表相关的信息已经存在,可以查询。(基本上,这就是JOIN
关键字的作用。)因为您已经有了信息,所以不需要重复它。为了澄清另一个答案并消除冗余,这可能会通过相应的查询/连接来澄清。我正在重新命名专栏,以确保对上下文的澄清,但可能缺少您的“区域”领域的上下文
注意从一个表到下一个表的联接的层次表示。您可以看到表之间的直接关联。然后,如果您正在寻找有问题的特定区域,只需应用WHERE子句。为了澄清另一个答案并消除冗余,这可能会通过相应的查询/连接进行澄清。我正在重新命名专栏,以确保对上下文的澄清,但可能缺少您的“区域”领域的上下文
注意从一个表到下一个表的联接的层次表示。您可以看到表之间的直接关联。然后,如果您正在查找有问题的特定区域,只需应用WHERE子句。通过BCNF进行规范化是基于函数依赖关系的。什么
数据中的函数依赖关系是这样的吗?有什么问题
候选密钥
Cities
State County City
--
Alabama Pike Troy
Arkansas Pike Delight
Florida Bay Springfield
Maine Penobscot Springfield
现在你会发现插入无效元组是不可能的
{特洛伊,洛杉矶,阿拉巴马州}和{特洛伊,派克,威尔士}
使用代理ID号而不是自然关键点不会改变
范式。但它确实改变了数据库的工作方式。而不是
必须以一种好的方式
使用上面的SQL表,此更新将失败
update states
set state = 'Wibble'
where state = 'Alabama';
这是件好事
让我们用代理ID号来构建这些表
create table states (
state_id integer primary key,
state varchar(100) not null unique
);
insert into states values
(1, 'Alabama'), (2, 'Arkansas'), (3, 'California'), (4, 'Florida'),
(5, 'Maine'); -- and more . . .
create table counties (
county_id integer not null,
county varchar(100) not null,
state_id integer not null,
foreign key (state_id) references states (state_id)
on update restrict on delete restrict,
primary key (county_id, state_id),
unique (county, state_id)
);
insert into counties values
(1, 'Autauga', 1), (2, 'Baldwin', 1), (3, 'Pike', 1),
(4, 'Pike', 2),
(5, 'Los Angeles', 3),
(6, 'Bay', 4),
(7, 'Penobscot', 5); -- and more . . .
create table cities (
city_id integer not null,
city varchar(100) not null,
county_id integer not null,
state_id integer not null,
foreign key (county_id, state_id) references counties (county_id, state_id)
on update restrict on delete restrict,
primary key (city_id, county_id, state_id),
unique (city, county_id, state_id)
);
insert into cities values
(1, 'Troy', 3, 1),
(2, 'Delight', 4, 2),
(3, 'Springfield', 7, 5),
(4, 'Springfield', 6, 4); -- and more . . .
所有这三张表至少仍处于5NF状态。但是这个
(无效)更新现在将成功
update states
set state = 'Wibble'
where state = 'Alabama';
那是件坏事
使用代理ID号会使每个外键引用
与在更新级联时声明它们的行为相同。恢复
更新限制时的部分语义,您必须
撤销服务器上的更新权限的额外的、非直观的步骤
引用的表
几乎没有人能把那部分做好
没有任何实际原则可以证明分割主键是正确的
为了获得一条路径,您可以按照该路径恢复原始文件
关系换句话说,没有关系原则
有理由改变这个
Cities
city_id city county_id state_id
--
1 Troy 3 2
城市
城市识别号城市县识别号州识别号
--
1特洛伊3 2
…对这件事
Cities
city_id city county_id
--
1 Troy 3
城市
城市识别号城市县识别号
--
1特洛伊3
县
县id县州id
--
3派克1
不仅没有关系原则可以证明分裂是正确的
主键,它创建了关系模型的一个问题
要解决的数据。查找“IMS”,一个分层数据库
管理系统,要求用户通过
数据文件。通过BCNF进行规范化是基于函数的
create table states (
state_id integer primary key,
state varchar(100) not null unique
);
insert into states values
(1, 'Alabama'), (2, 'Arkansas'), (3, 'California'), (4, 'Florida'),
(5, 'Maine'); -- and more . . .
create table counties (
county_id integer not null,
county varchar(100) not null,
state_id integer not null,
foreign key (state_id) references states (state_id)
on update restrict on delete restrict,
primary key (county_id, state_id),
unique (county, state_id)
);
insert into counties values
(1, 'Autauga', 1), (2, 'Baldwin', 1), (3, 'Pike', 1),
(4, 'Pike', 2),
(5, 'Los Angeles', 3),
(6, 'Bay', 4),
(7, 'Penobscot', 5); -- and more . . .
create table cities (
city_id integer not null,
city varchar(100) not null,
county_id integer not null,
state_id integer not null,
foreign key (county_id, state_id) references counties (county_id, state_id)
on update restrict on delete restrict,
primary key (city_id, county_id, state_id),
unique (city, county_id, state_id)
);
insert into cities values
(1, 'Troy', 3, 1),
(2, 'Delight', 4, 2),
(3, 'Springfield', 7, 5),
(4, 'Springfield', 6, 4); -- and more . . .
update states
set state = 'Wibble'
where state = 'Alabama';
Cities
city_id city county_id state_id
--
1 Troy 3 2
Cities
city_id city county_id
--
1 Troy 3
Counties
county_id county state_id
--
3 Pike 1