数据设计原则:
1.实体:客观存在又相互区别的东西称为实体,也就是一个表,例如 用户表,菜单表,商品信息表 等等 。。。2.实体间的联系:
一对一 : 表与表之间的关系是一一对应的, 例如 学生信息表 里面有一个studentid, 学生成绩表里面也有一个 studentid, 这两个表之间是 一一对应的关系 一对多:比如班级表 跟学生表之间的关系,学生表里面有一个 班级id, 对应的是班级表里面的主键id,就是说一个学生只有一个 一个班级,一个班级里面 有多个学生。 多对多: 选课表 与学生表之间是 多对多的关系, 就是说 一个学生可以选多门课程,而一门课可以有多个学生,这就形成了 两个表之间是多对多的关系, 对于 多对多,一般采取的是 使用中间表 ,也就是建立一个 选课学生关系表, 用来存放 选课表的id 和 学生表的id 就可以了。
以上 各个实体 都属于基本表。
下面来看下 非 基本表: 1、中间表中间表是针对多对多关系的,就比如做公交查询系统。里面有两个表,分别是车站表、线路表。这里我们起个名字叫:t_busstation 、t_road,根据常识我们也知道,
一个站有多个线路经过,而每个线路又有多个车站,怎么才能将两个表联系起来呢,如果是一对一,一对多,我们一个表,两个表就可以将他们实现了,但是多对多呢, 这样我们就必须借助中间表用来连接两个表。一般中间表都是有一个本表的自增主键,还有另外两个表的主键。中间表是没有属性的因为它不是一个基本表。2、临时表
在本次项目中,我们就要用到临时表,首先来看看什么是临时表吧。这是我从网上书上查到的。因为我们用的是MS SQL Server 2000数据库,而在这个数据库里是支持临时表的。
临时表:其实就是那些以#号开头为名字的数据表,它主要是用来存放临时数据的,当用户断开连接但没有出去临时表里的数据时,系统会自动把临时表里的数据清空。这里要说一点,临时表是放在系统数据库 tempdb中的,而不是当前数据库。
临时表总共是分两种:本地临时表和全局临时表。
(1)这里我们需要了解的就是,在数据库中本地临时表是以一个#开头的,这种临时表只对当前的数据库用户可见,而其他的用户是不可见的。当数据库实例断开后当然也就丢失了数据了,不管是显式清空还是系统回收。
(2)还有一个就是全局临时表。它是以“##”开头的,而且是对于所有的用户都是可见的,当你断开数据库实例连接时,只要还有别的系统项目在引用它,连着数据库,那么数据就存在,只有当别的系统也断开连接时,系统才会清除全局临时表的数据。 数据库设计的三大范式: 1.原子性约束(要求属性具有原子性,不可再分解): 如果每列(或者每个属性)都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式. 比如一个工人的基本信息表,里面有工人的工号,性别,年龄,这些属性都是不可分割的,所以这个表就符合了第一范式。 2.惟一性约束(要求记录有惟一标识,即实体的惟一性) 就是在第一范式的基础上延伸,使之表里的每个字段都与主键发生关系。假如一个关系满足第一范式,并且除了主键以外的其它字段,都依赖于该主键,则满足第二范式. 例如:订单表(订单编号、产品编号、定购日期、价格、……),"订单编号"为主键,"产品编号"和主键列没有直接的关系, 即"产品编号"列不依赖于主键列,这个列我们就可以把它删除。 3.冗余性的约束:(任何字段不能由其他字段派生出来,它要求字段没有冗余) 设U是关系模式R 的属性集,F 是R 上成立的只涉及U 中属性的函数依赖集。若X→Y 和 Y→Z在R 上成立,则X →Z 在R 上成立。 因此我们就来看在网上搜索到的例子:例如:订单表(订单编号,定购日期,顾客编号,顾客姓名,……),初看该表没有问题,满足第二范式,每列都和主键列"订单编号"相关, 再细看你会发现"顾客姓名"和"顾客编号"相关,"顾客编号"和"订单编号"又相关,最后经过传递依赖,"顾客姓名"也和"订单编号"相关。 为了满足第三范式,应去掉"顾客姓名"列,放入客户表中。 其实在设计数据库的时候我们最多的要遵循的就是第三范式,但是并不是越满足第三范式数据库就设计的越完美,这种错误是错误的。有时候增加点冗余相反的会提高访问速率, 因此在实际的设计过程中应降低对范式的要求。以前对数据冗余并不是很了解,在百度知道里的定义是这样的:在一个数据集合中重复的数据称为数据冗余. 但是不是说我们表的主键在其他表里重复出现就是冗余,这不是,而是为了连接两个表。
只有非键字段就是既不是主键外键等约束的键如果重复出现,就会形成数据冗余。数据冗余也包括重复性冗余和派生冗余。比如工人表里有"基本工资","奖金"两列,然后还有一个"总工资"的列,这个总工资就是派生冗余。低级的重复性冗余一定要避免,杜绝,但是像派生冗余还是提倡的因为它能提高访问的效率。
数据库设计过程 中 经常 遇到 的两个情况:
1.树型关系的数据表 大家最常见的就是 菜单表 , 往往 会有3层 甚至更多层的 层级结构, 一般的设计 都是 些 一个 父级菜单。 然后不挺的循环遍历, 就形成菜单了,这样设计 效率太低了。 类别表_1(Type_table_1)名称 类型 约束条件 说明type_id int 无重复 类别标识,主键type_name char(50) 不允许为空 类型名称,不允许重复type_father int 不允许为空 该类别的父类别标识,如果是顶节点的话设定为某个唯一值
类别表_2(Type_table_2)
名称 类型 约束条件 说明type_id int 无重复 类别标识,主键type_name char(50) 不允许为空 类型名称,不允许重复type_father int 不允许为空 该类别的父类别标识,如果是顶节点的话设定为某个唯一值type_layer char(6) 限定3层,初始值为000000 类别的先序遍历,主要为减少检索数据库的次数type_level int 菜单的层级 0,1,2,3type_id type_name type_father type_layer
1 总类别 0 0000002 类别1 1 0100003 类别1.1 2 0101004 类别1.2 2 0102005 类别2 1 0200006 类别2.1 5 0201007 类别3 1 0300008 类别3.1 7 0301009 类别3.2 7 03020010 类别1.1.1 3 010101
现在按type_layer的大小来检索一下:SELECT * FROM Type_table_2 ORDER BY type_layer列出记录集如下:
2. 对于设计完成后的数据库, 经常要往 同一个表里面增加 字段
(前提:之前表的设计结构不能改变)商品信息表(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 内含件数,默认为1stock int 初始值为0 库存,默认为0buy_price money 不允许为空 进货价sell_price money 不允许为空 销售价discount money 不允许为空 优惠价
新增设计:
商品额外属性表(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_name1 商品图片2 商品长度