有效的数据库设计(降低表的相互关系)
2014-05-07 22:05
225 查看
先给出一个错误的例子
假设有两种关联的表 商品表Goods(GoodsName,GoodsCode,GoodsStockNum )
和 商品入库表GoodsIn( GoodsInID, GoodsName,GoodsCode,InStockNum )..
现在这两张表假设是在一个超市收银系统中。每次商品入库 商品库存数量就增加。
现在如果用户修改商品信息 假设它要修改商品名称 这个时候可以轻松顺利的修改商品表Update一下商品名称就修改了 但是商品入库记录里的商品名称怎么办呢 好像在这样的表设计下 为了一致性 我们就必须在Update 商品表Goods时也要Update商品入库表了。其实问题远不止如此简单 因为在设计程序时程序员根本就不会知道用户修改商品信息时会修改商品的什么属性 而只有修改商品名称时商品入库表才需要跟着一起修改。如果为了这点需要写条特别的代码 会不会感觉特别不值
很多人会放弃保持这个一致性。追求完美,是程序员的心态,那应该怎么轻松解决这个问题呢
正确的 表结构是Goods(GoodsName,GoodsCode,GoodsStockNum ),GoodsIn(GoodsInID,GoodsCode,InStockNum ) 很简单就是在商品入库表中去掉了商品名称GoodsName这个字段,当在界面要显示商品名称时我们使用联合查询就可以了例如
select Gi.*,G.GoodsName from Goods G inner join GoodsIn Gi on G.GoodsCode=Gi.GoodsCode.这样就可以保障界面显示商品入库记录时有商品名称显示了 虽然这里sql复杂了一点 但是总比修改商品表时惦记着要修改商品入库记录强。
这里其实降低了表与表之间的耦合性 使一个的变化最小化影响另外一个变化, 它是怎么降低的呢 就是应用了外键 ,依赖外键通过联合查询达到目的。在商品入库表GoodsIn中字段商品编号GoodsCode其实就是外键。
sql可以这样写Create Table GoodsIn(GoodsInID int primary key, GoodsCode Char(13) Foreign key References Goods(GoodsCode),xx) 这样写了以后在删除商品表中的某行时还会检查商品编码是不是正在被Goodsin引用 如果是就会删除失败。
再细致说一下 这个表GoodsIn( GoodsInID, GoodsName,GoodsCode,InStockNum )到底有什么问题 其实就是数据库设计要考虑的第几范式问题 也就是容许个字段之间依赖到什么程度。这里有两个依赖 商品名称可以由入库Id唯一确定,同时商品名称也可以由商品编号唯一确定 ,这就违反了第三范式(3NF) 禁止非主属性依赖于非主属性。那个商品编号可以决定商品名称就是
非主属性依赖于非主属性了 ,其实最好的就是非主键字段完全由主键决定。这张表创建的失败就是因为它还只是满足第二范式(2NF).
假设有两种关联的表 商品表Goods(GoodsName,GoodsCode,GoodsStockNum )
和 商品入库表GoodsIn( GoodsInID, GoodsName,GoodsCode,InStockNum )..
现在这两张表假设是在一个超市收银系统中。每次商品入库 商品库存数量就增加。
现在如果用户修改商品信息 假设它要修改商品名称 这个时候可以轻松顺利的修改商品表Update一下商品名称就修改了 但是商品入库记录里的商品名称怎么办呢 好像在这样的表设计下 为了一致性 我们就必须在Update 商品表Goods时也要Update商品入库表了。其实问题远不止如此简单 因为在设计程序时程序员根本就不会知道用户修改商品信息时会修改商品的什么属性 而只有修改商品名称时商品入库表才需要跟着一起修改。如果为了这点需要写条特别的代码 会不会感觉特别不值
很多人会放弃保持这个一致性。追求完美,是程序员的心态,那应该怎么轻松解决这个问题呢
正确的 表结构是Goods(GoodsName,GoodsCode,GoodsStockNum ),GoodsIn(GoodsInID,GoodsCode,InStockNum ) 很简单就是在商品入库表中去掉了商品名称GoodsName这个字段,当在界面要显示商品名称时我们使用联合查询就可以了例如
select Gi.*,G.GoodsName from Goods G inner join GoodsIn Gi on G.GoodsCode=Gi.GoodsCode.这样就可以保障界面显示商品入库记录时有商品名称显示了 虽然这里sql复杂了一点 但是总比修改商品表时惦记着要修改商品入库记录强。
这里其实降低了表与表之间的耦合性 使一个的变化最小化影响另外一个变化, 它是怎么降低的呢 就是应用了外键 ,依赖外键通过联合查询达到目的。在商品入库表GoodsIn中字段商品编号GoodsCode其实就是外键。
sql可以这样写Create Table GoodsIn(GoodsInID int primary key, GoodsCode Char(13) Foreign key References Goods(GoodsCode),xx) 这样写了以后在删除商品表中的某行时还会检查商品编码是不是正在被Goodsin引用 如果是就会删除失败。
再细致说一下 这个表GoodsIn( GoodsInID, GoodsName,GoodsCode,InStockNum )到底有什么问题 其实就是数据库设计要考虑的第几范式问题 也就是容许个字段之间依赖到什么程度。这里有两个依赖 商品名称可以由入库Id唯一确定,同时商品名称也可以由商品编号唯一确定 ,这就违反了第三范式(3NF) 禁止非主属性依赖于非主属性。那个商品编号可以决定商品名称就是
非主属性依赖于非主属性了 ,其实最好的就是非主键字段完全由主键决定。这张表创建的失败就是因为它还只是满足第二范式(2NF).
相关文章推荐
- 开发人员如何有效地进行数据库设计
- 数据库设计多对多关系的几种形态
- 关系数据库设计理论(4) 关系模式的分解
- ***(原创)关注,粉丝关系的数据库设计
- 关系数据库设计范式
- 领域驱动设计与二元关系数据库
- 关系数据库设计范式介绍
- 此数据库没有有效所有者,因此无法安装数据库关系图支持对象
- 数据库表设计时一对一关系
- 开发人员如何有效的进行数据库设计
- 预集成传感器:有效降低成本和设计风险
- 数据库设计的5种常见关系
- 关系数据库设计范式介绍
- 开发人员如何有效地进行数据库设计
- 异常:此数据库没有有效所有者,因此无法安装数据库关系图支持对象。
- 数据库中多对多的关系设计
- 关系数据库设计理论(二)函数依赖的规则
- 08关系数据库的设计
- 数据库开发(5)关系数据库设计
- 异常:此数据库没有有效所有者,因此无法安装数据库关系图支持对象。 (SQL2000转到2005)