天天看点

数据库设计不求人(机房收费系统)前言概念实现小结

前言

我想在进行数据库设计之前,需要要明白为什么设计数据库,不进行数据库设计可以吗?如果只是随便在院子里搭一个棚子需不需要先画图设计,但是如果要建造一栋大厦又需不需要设计?

思考之后,可以得出结论:面对复杂的数据库时,我们需要进行数据库设计。

概念

在数据库项目开发中,一个良好设计的数据库无疑有很多的好处。有较少的数据冗余、节省存储空间,能够保证数据的完整性。那么如何设计一个数据库,又有哪些流程。

按照软件开发的流程:

数据库设计不求人(机房收费系统)前言概念实现小结

各阶段得到的文件:

数据库设计不求人(机房收费系统)前言概念实现小结

实现

这里通过设计学生使用的机房收费系统的数据库来演示:

需求分析

分析用户的业务和数据处理需求,这一阶段,我们得到数据字典和数据流图

数据流图(Data Flow Diagram,DFD):通过数据流图来表达系统内数据处理的过程。

下面以收费系统的用户登录过程为例,来说明数据流图如何描述数据处理过程。

数据库设计不求人(机房收费系统)前言概念实现小结

上图描述了用户登录系统的过程。用户在登陆界面输入用户名和密码进行登陆验证。通过查询用户信息文件来核对用户的身份,如果身份验证通过则创建一条登陆记录添加到登陆记录文件中,完成登陆登记。

数据字典和数据流图配合,能更清楚的表达数据处理的要求。用词条的方式定义在数据流图中出现的所有被命名的图形元素,包含数据流、加工、数据文件、数据元素以及数据源和数据谭。

下面是一个简单的示例:

  • 数据元素条目(数据处理中最小、不可分割的单位)
数据库设计不求人(机房收费系统)前言概念实现小结
  • 数据流条目(数据结构在系统的传播路径)
数据库设计不求人(机房收费系统)前言概念实现小结
  • 数据存储文件条目(数据保存的地方)
数据库设计不求人(机房收费系统)前言概念实现小结
  • 加工条目(对数据流的处理)
数据库设计不求人(机房收费系统)前言概念实现小结
  • 数据源及数据谭条目(即外部实体)
数据库设计不求人(机房收费系统)前言概念实现小结

概要设计

在概要阶段,我们要进行数据建模,即传统的实体-关系方法,它使用了三种互相关联的信息:数据实体、描述实体的属性、描述实体间相互连接的关系,使用E-R图来表述。

  • 数据实体

    在E-R图中,实体用矩形来表示,是具有若干属性信息的组合体。数据实体可以是外部实体(如显示器)、事物(如报表)、角色(如学生)、行为(如打电话)或者事件(如单击)、组织单位(如院系)、地点(如教室)、或结构(如文件)。

  • 属性

    属性定义数据实体的特征,在E-R图中用椭圆形来表示。

  • 关系

    各个实体之间的关系通过菱形来表示,它们之间的关联有三种:一对一(1:1)、一对多(1:m)、多对多(n:m)。

在这里为了避免属性太多而显得太乱,我去掉了实体的属性,仅展示实体和它们之间的联系。

数据库设计不求人(机房收费系统)前言概念实现小结

详细设计

在详细设计中,需要把概要设计得到的E-R图转换为关系模式,并且进行范式检查

原则:

  • 一个实体转换为一个关系模式,实体的属性就是关系的属性,实体的键就是关系的键;
  • 联系在转换为关系模式时,分为以下三种不同的情况:
  • 若联系为1:1,可以在两个实体类型转换成的两个关系模式中任意一个关系模式的属性中加入另一个关系模式的键和联系类型的属性。
  • 若联系为1:n,则在N端实体类型转换成的关系模式中加入1端实体类型的键和联系类型的属性。
  • 若联系为m:n,则将联系类型也转换成关系模式,其属性为两端实体类型的键加上联系类型的属性,而键为两端实体键的组合。

范式检查

  • 第一范式:每列都不可分割,在关系型数据库中,第一范式满足
  • 第二范式:不出现局部依赖
  • 第三范式:不出现传递依赖

最后的关系模式为下面所示:

用户(账号,密码,姓名,性别,类型,操作人)

T_User (userID,userPWD,userName,userSex,userType,signOperator)

登陆(账号,登陆时间,注销时间,机器名称)

T_UserLogin (userID,loginDateTime,logoutDateTime,loginComputer)

系统(临时费率,固定费率,至少上机时间,准备时间,至少充值金额,计费单位,修改人)

T_System (tempRate,rate,leastTime,preprareTime,limitRechargCash,unitTime,systemModifier)

学生(学号,姓名,性别,班级,年级,学院,系部,专业,注册人,注册时间)

T_Student (stuNo,stuName,stuSex,class,grade,academy,department,major,register,registerDateTime)

卡(卡号,金额,类型,使用状态,售卡人,注册时间)

T_Card (cardID,cash,type,status,register,registerDateTime)

充值(卡号,充值金额,充值人,充值时间,是否结账)

T_CardRecharge (cardID,cash,rechargeOperator,rechargeDateTime,isCheck)

退卡(卡号,退卡金额,退卡人,退卡时间,是否结账)

T_CardCancel (cardID,cash,cancelOperator,cancelDateTime,isCheck)

学生绑定卡(学号,卡号,绑定人,绑定时间,绑定状态)

T_Binding (stuNo,cardID,bindOperator,bindDateTime,isBind)

上机(卡号,上机时间,下机时间,消费时间,消费金额,上机机器)

T_OnLine (cardID,onLineDateTime,offLineDateTime,costTime,costCash,computer)

账单(充值金额,退还金额,剩余金额,结账时间,结账人)

T_Bill (rechargeCash,cancelCash,remainCash,checkDateTime,checkOperator)

实现

这里使用了PowerDesigner来实现数据库

数据库设计不求人(机房收费系统)前言概念实现小结

SQL文件为:

/*==============================================================*/
/* Database name:  JFCharge                                     */
/* DBMS name:      Microsoft SQL Server 2008                    */
/* Created on:     2016/3/10 9:54:07                            */
/*==============================================================*/


use JFCharge
go

if exists (select 
   from sys.sysreferences r join sys.sysobjects o on (o.id = r.constid and o.type = 'F')
   where r.fkeyid = object_id('T_Binding') and o.name = 'FK_T_BINDIN_REFERENCE_T_CARD')
alter table T_Binding
   drop constraint FK_T_BINDIN_REFERENCE_T_CARD
go

if exists (select 
   from sys.sysreferences r join sys.sysobjects o on (o.id = r.constid and o.type = 'F')
   where r.fkeyid = object_id('T_Binding') and o.name = 'FK_T_BINDIN_REFERENCE_T_STUDEN')
alter table T_Binding
   drop constraint FK_T_BINDIN_REFERENCE_T_STUDEN
go

if exists (select 
            from  sysobjects
           where  id = object_id('T_Bill')
            and   type = 'U')
   drop table T_Bill
go

if exists (select 
            from  sysobjects
           where  id = object_id('T_Binding')
            and   type = 'U')
   drop table T_Binding
go

if exists (select 
            from  sysobjects
           where  id = object_id('T_Card')
            and   type = 'U')
   drop table T_Card
go

if exists (select 
            from  sysobjects
           where  id = object_id('T_CardCancel')
            and   type = 'U')
   drop table T_CardCancel
go

if exists (select 
            from  sysobjects
           where  id = object_id('T_CardRecharge')
            and   type = 'U')
   drop table T_CardRecharge
go

if exists (select 
            from  sysobjects
           where  id = object_id('T_OnLine')
            and   type = 'U')
   drop table T_OnLine
go

if exists (select 
            from  sysobjects
           where  id = object_id('T_Student')
            and   type = 'U')
   drop table T_Student
go

if exists (select 
            from  sysobjects
           where  id = object_id('T_System')
            and   type = 'U')
   drop table T_System
go

if exists (select 
            from  sysobjects
           where  id = object_id('T_User')
            and   type = 'U')
   drop table T_User
go

if exists (select 
            from  sysobjects
           where  id = object_id('T_UserLogin')
            and   type = 'U')
   drop table T_UserLogin
go

/*==============================================================*/
/* Table: T_Bill                                                */
/*==============================================================*/
create table T_Bill (
   rechargeCash         decimal(,)        null,
   cancelCash           decimal(,)        null,
   remainCash           decimal(,)        null,
   checkDateTime        datetime             null,
   operator             varchar()          null
)
go

/*==============================================================*/
/* Table: T_Binding                                             */
/*==============================================================*/
create table T_Binding (
   stuNo                varchar()          not null,
   cardID               varchar()          not null,
   operator             varchar()          not null,
   bindDateTime         datetime             not null,
   isBind               char()              not null,
   constraint PK_T_BINDING primary key (stuNo, cardID)
)
go

/*==============================================================*/
/* Table: T_Card                                                */
/*==============================================================*/
create table T_Card (
   cardID               varchar()          not null,
   cash                 decimal(,)        not null,
   type                 char()              not null,
   status               char()              not null,
   register             varchar()          not null,
   registerDateTime     datetime             not null,
   constraint PK_T_CARD primary key (cardID)
)
go

/*==============================================================*/
/* Table: T_CardCancel                                          */
/*==============================================================*/
create table T_CardCancel (
   cardID               varchar()          not null,
   cash                 decimal(,)        not null,
   operator             varchar()          not null,
   cancelDateTime       datetime             not null,
   isCheck              char()              not null
)
go

/*==============================================================*/
/* Table: T_CardRecharge                                        */
/*==============================================================*/
create table T_CardRecharge (
   cardID               varchar()          not null,
   cash                 decimal(,)        not null,
   operator             varchar()          not null,
   rechargeDateTime     datetime             not null,
   isCheck              char()              not null
)
go

/*==============================================================*/
/* Table: T_OnLine                                              */
/*==============================================================*/
create table T_OnLine (
   cardID               varchar()          not null,
   onLineDateTime       datetime             not null,
   offLineDateTime      datetime             null,
   costTime             datetime             null,
   costCash             decimal(,)        null,
   computer             varchar()          not null
)
go

/*==============================================================*/
/* Table: T_Student                                             */
/*==============================================================*/
create table T_Student (
   stuNo                varchar()          not null,
   stuName              varchar()          not null,
   stuSex               char()              not null,
   class                varchar()          not null,
   grade                varchar()          not null,
   academy              varchar()          not null,
   department           varchar()          not null,
   major                varchar()          not null,
   register             varchar()          not null,
   registerDateTime     datetime             not null,
   constraint PK_T_STUDENT primary key (stuNo)
)
go

/*==============================================================*/
/* Table: T_System                                              */
/*==============================================================*/
create table T_System (
   tempRate             decimal(,)        not null,
   rate                 decimal(,)        not null,
   leastTime            int                  not null,
   preprareTime         int                  not null,
   limitRechargeCash    decimal(,)        not null,
   unitTime             int                  not null,
   systemModifier       varchar()          not null
)
go

/*==============================================================*/
/* Table: T_User                                                */
/*==============================================================*/
create table T_User (
   userID               varchar()          not null,
   userPWD              varchar()          not null,
   userName             varchar()          not null,
   userSex              char()              not null,
   userType             char()              not null,
   operator             varchar()          not null,
   constraint PK_T_USER primary key (userID)
)
go

if exists (select  from  sys.extended_properties
           where major_id = object_id('T_User') and minor_id = )
begin 
   declare @CurrentUser sysname 
select @CurrentUser = user_name() 
execute sp_dropextendedproperty 'MS_Description',  
   'user', @CurrentUser, 'table', 'T_User' 

end 


select @CurrentUser = user_name() 
execute sp_addextendedproperty 'MS_Description',  
   '用户表', 
   'user', @CurrentUser, 'table', 'T_User'
go

/*==============================================================*/
/* Table: T_UserLogin                                           */
/*==============================================================*/
create table T_UserLogin (
   userID               varchar()          not null,
   loginDateTime        datetime             not null,
   logoutDateTime       datetime             null,
   loginComputer        varchar()          not null
)
go

alter table T_Binding
   add constraint FK_T_BINDIN_REFERENCE_T_CARD foreign key (cardID)
      references T_Card (cardID)
go

alter table T_Binding
   add constraint FK_T_BINDIN_REFERENCE_T_STUDEN foreign key (stuNo)
      references T_Student (stuNo)
go


           

小结

其实我们在设计数据库时,如果只是按照标准的流程和规则来完成工作,那么很可能感觉无从下手,我们可以先通过自己的一些生活经验来完成初步的数据库设计。

比如说,分析机房收费系统在确定实体的时候,我们平时的生活经验就是这个系统应该要有学生、上机卡(需要注册、充值)、操作员(给我们办理上下机)、系统等实体,先初步确定之后再仔细分析。还有范式检查的时候还有更高的范式,但是我们一般在设计的时候使其满足第三范式就可以了。

以上就是数据库设计的大致流程,以机房收费系统为例子,这当中可能由于博主理解的偏差,会有不合适的地方,希望大家可以指出来,共同进步。