PHP程序员站--PHP编程开发平台
 当前位置:主页 >> 数据库 >> 数据库编程技术 >> 

浅谈数据库的设计技巧

浅谈数据库的设计技巧

来源:互联网  作者:  发布时间:2008-03-14
说到数据库,我认为不能不先谈数据结构。1996年,在

  二、商品信息表的设计

  假设你是一家百货公司电脑部的开发人员,某天老板要求你为公司开发一套网上电子商务平台,该百货公司有数千种商品出售,不过目前仅打算先在网上销售数十种方便运输的商品,当然,以后可能会陆续在该电子商务平台上增加新的商品出售。现在开始进行该平台数据库的商品信息表的设计。每种出售的商品都会有相同的属性,如商品编号,商品名称,商品所属类别,相关信息,供货厂商,内含件数,库存,进货价,销售价,优惠价。你很快就设计出4个表:商品类型表(Wares_type),供货厂商表(Wares_provider),商品信息表(Wares_info):

商品类型表(Wares_type)
名称     类型    约束条件            说明
type_id     int       无重复           类别标识,主键
type_name   char(50)   不允许为空         类型名称,不允许重复
type_father   int     不允许为空         该类别的父类别标识,如果是顶节点的话设定为某个唯一值
type_layer   char(6)   限定3层,初始值为000000   类别的先序遍历,主要为减少检索数据库的次数



供货厂商表(Wares_provider)
名称     类型    约束条件            说明
provider_id   int       无重复           供货商标识,主键
provider_name char(100)   不允许为空         供货商名称

商品信息表(Wares_info)
名称     类型    约束条件            说明
wares_id   int     无重复             商品标识,主键
wares_name   char(100) 不允许为空           商品名称
wares_type   int   不允许为空           商品类型标识,和Wares_type.type_id关联
wares_info   char(200) 允许为空           相关信息
provider   int   不允许为空           供货厂商标识,和Wares_provider.provider_id关联
setnum     int   初始值为1           内含件数,默认为1
stock     int   初始值为0           库存,默认为0
buy_price   money   不允许为空           进货价
sell_price   money   不允许为空           销售价
discount   money   不允许为空           优惠价

  你拿着这3个表给老板检查,老板希望能够再添加一个商品图片的字段,不过只有一部分商品有图片。OK,你在商品信息表(Wares_info)中增加了一个haspic的BOOL型字段,然后再建了一个新表——商品图片表(Wares_pic):

商品图片表(Wares_pic)
名称     类型    约束条件            说明
pic_id   int       无重复             商品图片标识,主键
wares_id   int     不允许为空           所属商品标识,和Wares_info.wares_id关联
pic_address  char(200)   不允许为空           图片存放路径

  程序开发完成后,完全满足老板目前的要求,于是正式启用。一段时间后,老板打算在这套平台上推出新的商品销售,其中,某类商品全部都需添加“长度”的属性。第一轮折腾来了……当然,你按照添加商品图片表的老方法,在商品信息表(Wares_info)中增加了一个haslength的BOOL型字段,又建了一个新表——商品长度表(Wares_length):

商品长度表(Wares_length)
名称     类型    约束条件            说明
length_id   int       无重复             商品图片标识,主键
wares_id   int     不允许为空           所属商品标识,和Wares_info.wares_id关联
length    char(20)   不允许为空           商品长度说明

  刚刚改完没多久,老板又打算上一批新的商品,这次某类商品全部需要添加“宽度”的属性。你咬了咬牙,又照方抓药,添加了商品宽度表(Wares_width)。又过了一段时间,老板新上的商品中有一些需要添加“高度”的属性,你是不是开始觉得你所设计的数据库按照这种方式增长下去,很快就能变成一个迷宫呢?那么,有没有什么办法遏制这种不可预见性,但却类似重复的数据库膨胀呢?我在阅读《敏捷软件开发:原则、模式与实践》中发现作者举过类似的例子:7.3 “Copy”程序。其中,我非常赞同敏捷软件开发这个观点:在最初几乎不进行预先设计,但是一旦需求发生变化,此时作为一名追求卓越的程序员,应该从头审查整个架构设计,在此次修改中设计出能够满足日后类似修改的系统架构。下面是我在需要添加“长度”的属性时所提供的修改方案:



  去掉商品信息表(Wares_info)中的haspic字段,添加商品额外属性表(Wares_ex_property)和商品额外信息表(Wares_ex_info)2个表来完成添加新属性的功能。

商品额外属性表(Wares_ex_property)
名称     类型    约束条件            说明
ex_pid   int       无重复             商品额外属性标识,主键
p_name   char(20)   不允许为空           额外属性名称

商品额外信息表(Wares_ex_info)
名称       类型    约束条件            说明
ex_iid     int       无重复             商品额外信息标识,主键
wares_id   int     不允许为空           所属商品标识,和Wares_info.wares_id关联
property_id    int     不允许为空           商品额外属性标识,和Wares_ex_property.ex_pid关联
property_value char(200)   不允许为空           商品额外属性值

  在商品额外属性表(Wares_ex_property)中添加2条记录:
ex_pid       p_name
1       商品图片
2       商品长度

  再在整个电子商务平台的后台管理功能中追加一项商品额外属性管理的功能,以后添加新的商品时出现新的属性,只需利用该功能往商品额外属性表(Wares_ex_property)中添加一条记录即可。不要害怕变化,被第一颗子弹击中并不是坏事,坏的是被相同轨道飞来的第二颗、第三颗子弹击中。第一颗子弹来得越早,所受的伤越重,之后的抵抗力也越强8)(待续)

  三、多用户及其权限管理的设计

  开发数据库管理类的软件,不可能不考虑多用户和用户权限设置的问题。尽管目前市面上的大、中型的后台数据库系统软件都提供了多用户,以及细至某个数据库内某张表的权限设置的功能,我个人建议:一套成熟的数据库管理软件,还是应该自行设计用户管理这块功能,原因有二:
  1.那些大、中型后台数据库系统软件所提供的多用户及其权限设置都是针对数据库的共有属性,并不一定能完全满足某些特例的需求;
  2.不要过多的依赖后台数据库系统软件的某些特殊功能,多种大、中型后台数据库系统软件之间并不完全兼容。否则一旦日后需要转换数据库平台或后台数据库系统软件版本升级,之前的架构设计很可能无法重用。

  下面看看如何自行设计一套比较灵活的多用户管理模块,即该数据库管理软件的系统管理员可以自行添加新用户,修改已有用户的权限,删除已有用户。首先,分析用户需求,列出该数据库管理软件所有需要实现的功能;然后,根据一定的联系对这些功能进行分类,即把某类用户需使用的功能归为一类;最后开始建表:

功能表(Function_table)
名称     类型    约束条件   说明
f_id     int       无重复     功能标识,主键
f_name   char(20)   不允许为空   功能名称,不允许重复
f_desc   char(50)   允许为空   功能描述

用户组表(User_group)
名称     类型    约束条件   说明
group_id   int     无重复   用户组标识,主键
group_name   char(20)   不允许为空   用户组名称
group_power   char(100)   不允许为空   用户组权限表,内容为功能表f_id的集合

用户表(User_table)
名称     类型    约束条件   说明
user_id   int     无重复   用户标识,主键
user_name   char(20)   无重复   用户名
user_pwd   char(20)   不允许为空   用户密码
user_type   int     不允许为空   所属用户组标识,和User_group.group_id关联

  采用这种用户组的架构设计,当需要添加新用户时,只需指定新用户所属的用户组;当以后系统需要添加新功能或对旧有功能权限进行修改时,只用操作功能表和用户组表的记录,原有用户的功能即可相应随之变化。当然,这种架构设计把数据库管理软件的功能判定移到了前台,使得前台开发相对复杂一些。但是,当用户数较大(10人以上),或日后软件升级的概率较大时,这个代价是值得的。

Tags: 数据库   设计   数据   技巧