代码改变世界

数据设计总结

2015-11-10 13:50  刘晶  阅读(290)  评论(0编辑  收藏  举报

数据设计原则:


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,3

type_id      type_name          type_father          type_layer
1              总类别                 0                        000000
2              类别1                  1                        010000
3              类别1.1                2                        010100
4              类别1.2                2                        010200
5              类别2                  1                        020000
6              类别2.1                5                        020100
7              类别3                  1                         030000
8              类别3.1                7                        030100
9              类别3.2                7                        030200
10            类别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                      内含件数,默认为1
stock             int               初始值为0                      库存,默认为0
buy_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_name
1                   商品图片
2                   商品长度