数据库课程设计
题 目:网上订餐系统数据库设计
院 系:
专 业:
姓 名:
学 号:
指导教师: 欧阳柏成
教师职称: 副教授
填写日期: 2015年 5月 21日 |
1.1现状分析
现如今普遍使用电话订餐,这种方式订餐虽然较为方便,效率也较高,但是由此引发的一些不良现象不得不重视。例如,定餐后,饭店未能够及时将信息记录存档,由于看不到菜品的图片,顾客不能对菜品有一个直观的感受。同时,电话预约中的诚信问题也不得不考虑,订餐过程中顾客对信息的不明确会产生一定的误解并由此造成人力资源及时间的浪费。
这样开发出图文并茂,信息能够及时更新和查看的在线网上订餐系统就具有了重要的意义。
客对菜品的预定及支付方式;
即时可见:对客户预定餐饮信息的处理(包括录入、删除)将立即在主页的对应栏目显示出来,达到“即时发布、即时见效”的功能;
系统运行应该快速、稳定、高效和可靠;
在结构上应具有很好的可扩展性,便于将来的功能扩展和维护。
1.6可行性分析
随着经济的快速发展,网上订餐已经如雨后春笋般的出现在了许多地方。特别在公司,企业内部,团体订餐已经成为了趋势。同时,随着全国人民的精神、物质和文化生活高度的提高,人们已经不在仅仅停留在吃饱的程度,不但要吃饱,还要吃好,而且口味也越来越挑刺,正因为如此网络订餐业务的出现,正迎合了这些人的口味,他们不但省去了自己做饭的麻烦,而且也能寻找和发现新的菜品,品尝不同风格的菜品,网络订餐业务在中国有着极大的发展空间以及良好的背景。
1.7总体设计原则
①.开放性、可扩充性、可靠性原则
二、概念设计
2.1 系统E-R图
2.2数据流图
2.3数据字典
2.3.1 数据项
数据项名/编号 | 含义说明 | 数据类型 | 长度 |
c_id/p1 | 用户唯一性说明 | varchar | 9 |
c_name/p2 | 用户昵称 | varchar | 20 |
c_tel/p3 | 用户联系方式 | varchar | 11 |
c_key/p4 | 用户登陆密码 | varchar | 20 |
d_id/p5 | 菜的唯一性说明 | int | |
d_name/p6 | 菜的名称 | varchar | 30 |
d_remain/p7 | 菜的剩余量 | int | |
d_discount/p8 | 打折 | float | 2 |
d_price/p9 | 菜的单价 | float | 2 |
d_pid/p10 | 提供商编号 | int | |
p_id/p11 | 商店唯一性说明 | varchar | 9 |
p_add/p12 | 商店地址 | varchar | 30 |
p_name/p13 | 商店名称 | varchar | 20 |
p_key/p14 | 商家登陆密码 | varchar | 20 |
p_tel/p15 | 商店联系方式 | varchar | 11 |
p_lev/p16 | 商家信誉 | int | |
p_state/p17 | 商家状态 | varchar | 15 |
m_id/p18 | 管理员唯一性说明 | varchar | 4 |
m_name/p19 | 管理员姓名 | varchar | 20 |
m_key/p20 | 管理员密码 | varchar | 20 |
o_id/p21 | 订单标号 | int | |
o_cid/p22 | 订单中客户标识 | int | |
o_did/p23 | 订单中菜标识 | int | |
o_pid /p24 | 订单中商店标识 | int | |
o_time /p25 | 订餐时间 | smalldatetime | |
o_num/26 | 数量 | int | |
o_cadd/27 | 客户地址 | varchar | 50 |
o_state/28 | 订餐状态 | varchar | 15 |
m_c_mid /p29 | 管理员编号 | int | |
m_c_cid/p30 | 客户编号 | int | |
m_c_time/p31 | 时间 | smalldatetime | |
m_c_operation/p32 | 操作类别 | varchar | 15 |
m_p_mid/p33 | 管理员编号 | int | |
m_p_pid/p34 | 商店编号 | int | |
m_p_time/p35 | 操作类别 | smalldatetime | |
m_c_operation /p36 | 时间 | varchar | 15 |
数据结构名称 | 含义说明 | 组成 |
客户 | 客户信息 | p1-p4 |
菜品 | 菜品信息 | p5-p10 |
商店 | 商店信息 | p11-p17 |
管理员 | 管理员信息 | p18-p20 |
订单 | 订单信息 | p21-p28 |
管理用户 | 管理用户信息 | P29-p32 |
管理商家 | 管理商家信息 | P33-p36 |
处理过程名 | 说明 | 输入 | 输出 | 处理 |
注册 | 所有用户 | 用户详细信息 | 注册结果 | 跳转登陆/重新注册 |
登陆 | 所有用户 | 编号与密码 | 登陆成功/失败 | 登陆首页/重新登陆 |
修改用户信息 | 已登录用户 | 相关修改信息 | 修改成功/失败 | 修改存储信息 |
订餐 | 已登录用户 | 菜品、数量 | 订餐成功/失败 | 加入购物车/重新选择 |
修改订餐 | 已订餐用户 | 菜品、数量的修改 | 修改成功/失败 | 加入购物车/重新选择 |
下订单 | 已订餐用户 | 生成订单 | ||
查询与确认订单 | 已订餐用户 | |||
提交订单 | 已订餐用户 | |||
接受订单 | 商店 | 交付相关工作人员 | ||
送餐 | 送餐员 | 送餐确认 | ||
菜单修改 | 商店 | 新的菜品、菜品价格修改 | 更新菜谱 | |
管理 | 管理员 | 添加或删减用户 | 更新用户信息库 | |
信息更新 | 管理员 | 需要更新的信息 | 信息更新 |
3.1 E—R图向关系的初步转换
客户(编号,昵称,密码,联系方式,状态)
管理员(编号,姓名,密码)
商家(编号,名称,密码,商家地址,联系方式,信誉,状态,剩余量,总量)
菜(编号,名称,价格,折扣,提供商编号,最后修改时间,状态)
订单(客户编号,菜编号,提供商编号,订单时间,数量,客户地址,状态)
管理客户(管理员编号,客户编号,时间,操作类别)
管理商家(管理员编号,商家编号,时间,操作类别)
3.2 E-R具体转换代码
①客户表:
create table client
(c_id varchar(9) primary key not null check(c_id like 'c%'),
c_name varchar(20) not null,
c_key varchar(20) not null,
c_tel varchar(11) not null check(c_tel like '1%') unique
)
②管理员表:
create table manager
(
m_id varchar(4) primary key not null check(m_id like 'm%'),
m_name varchar(20) not null,
m_key varchar(20) not null
)
③商家表:
create table provider
(p_id varchar(9) primary key not null check(p_id like 'p%'),
p_name varchar(20) not null,
p_key varchar(20) not null,
p_tel varchar(11) not null unique check(p_tel like '1%'),
p_add varchar(30) not null unique,
p_lev int,
p_state varchar(15) check (p_state in ('营业中','打烊','歇业'))
)
④菜谱:
create table dish
(d_id int identity(1378001,1) primary key not null,
d_name varchar(30) not null,
d_price float(2) not null,
d_discount float(2),
d_pid varchar(9) not null ,
foreign key (d_pid) references provider(p_id),
d_remain int not null check (d_remain>=0),
d_total int not null,
)
⑤订单:
create table ord
(o_id int identity(10000001,1) primary key not null,
o_cid varchar(9),
foreign key (o_cid) references client (c_id),
o_did int,
foreign key (o_did) references dish (d_id),
o_pid varchar(9),
foreign key (o_pid) references provider (p_id),
o_time smalldatetime,
o_num int not null check (o_num>0),
o_cadd varchar(50) not null,
o_state varchar(15) check (o_state in('正常','取消'))
)
⑥管理客户:
create table manager_client
(m_c_mid varchar(4),
foreign key (m_c_mid) references manager (m_id),
m_c_cid varchar(9),
foreign key (m_c_cid) references client (c_id),
m_c_time smalldatetime,
primary key (m_c_mid,m_c_cid,m_c_time),
m_c_operation varchar(15) check (m_c_operation in('更新','增加','删除'))
)
⑦管理商店:
create table manager_provider
(m_p_mid varchar(4),
foreign key (m_p_mid) references manager (m_id),
m_p_pid varchar(9),
foreign key (m_p_pid) references provider (p_id),
m_p_time smalldatetime,
primary key (m_p_mid,m_p_pid,m_p_time),
m_c_operation varchar(15) check (m_c_operation in('允许注册','注销账户') )
)
四、外围实现部分 --客户端实现
本次数据库的外围采用C++语言实现的,编程环境使用的是visual studio 2010。数据库连接采用的是ADO(ActiveX Data Objects),主要是因为使用起来十分简便(只需掌握三个智能指针即可完成大多数功能),且不需要下载其他文件(windows自带)。而用户交互界面则使用的是dos窗口。
客户端目前提供两个功能,1是订餐功能,1是注册功能。
首先介绍注册功能,每个注册账户对应一个数据库登陆账户以及该账户下的一个拥有客户角色权限的用户,已注册账户的信息由client表存储。注册过程具体如下: 用户选择注册功能后,程序默认以sa身份登录数据库,用户通过dos窗口输入新的id以及密码,程序在client表中检查id是否被使用,若id已被占用则提示用户输入新的id,否则通过sql语句创建登陆账户以及拥有一定权限的数据库用户并提示用户注册成功。(注册实现代码如下:)
然后介绍订餐功能,选择订餐功能后首先提示用户输入账户(id)以及密码,输入后,程序尝试以此账户连接数据库,以30秒为时限,若超过时限没有连接上数据库则提示用户连接失败,否则从数据库中选择状态为”营业中”的饭店信息显示供用户选择,用户选择饭店编号后,从数据库中读取该饭店提供的剩余量大于0的菜品显示供用户选择,待用户作好选择后,将订单插入数据库中ord表(订单编号采用自增长)并修改菜品的剩余值,提示用户接受订单成功,并关闭与数据库的连接。
五、数据库实现
5.1据库的建立
启动服务管理器,打开查询分析器,在调试程序窗口输入下列语句:
Create database database_zbg
On
(name= zbg_data,
' E:\\dbdesign\ zbg_data.mdf',
Size=10mb
Maxsize=500mb,
)
Log on
(name= zbg_log,
' E:\\dbdesign\ zbg_log.ldf',
Size=5mb
Maxsize=100mb,
)
5.2数据载入
1)client表
insert into client values('c20120001','雷政富','leizhenf','');
insert into client values('c20120002','吴婷','wuting12','');
insert into client values('c20120003','李毅','liyi1234','15423122323');
insert into client values('c20120004','郑媛媛','zhengyua','');
insert into client values('c20120005','石磊','shilei12','');
insert into client values('c20120006','吴彦祖','wuyanzu1','');
2)manager
insert into manager values('m001','刘诗诗','liushish');
insert into manager values('m002','郭晶晶','guojingj');
insert into manager values('m003','杨幂','yangmi12');
3)provider
insert into provider values('p20131001','东北酒家','wuqilong','','梧桐路12号',4,'营业中');
insert into provider values('p20131002','学惠园','lichunch','','梧桐路21号',3,'营业中');
insert into provider values('p20131003','东北酒店','yanjiehe','','翟乃路12号',4,'打烊');
insert into provider values('p20131004','四川酒店','yuliang1','','淄博路5号',4,'歇业');
insert into provider values('p20131005','状元酒店','maweidu1','','中原路54号',4,'营业中');
insert into provider values('p20131006','大排档','fengtang','','中原路号',4,'打烊');
insert into provider values('p20131007','老乡鸡','maoyushi','','梧桐路13号',4,'营业中');
4)dish
insert into dish values('大对虾',32.3,0.95,'p20131001',500,500);
insert into dish values('大对虾',31.3,1,'p20131002',300,300);
insert into dish values('大对虾',30,0.98,'p20131007',500,500);
insert into dish values('彩花迎宾',22.3,0.97,'p20131002',500,500);
insert into dish values('彩花迎宾',32.3,0.9,'p20131003',500,500);
insert into dish values('鱿鱼汤',12.3,1,'p20131004',100,100);
insert into dish values('狗全席',22.3,1,'p20131004',500,500);
insert into dish values('狗全席',22.4,1,'p20131005',500,500);
insert into dish values('龙门鱼',32.3,0.99,'p20131005',500,500);
insert into dish values('龙门鱼',33,0.98,'p20131006',500,500);
insert into dish values('叫花鸡',133.2,0.8,'p20131001',50,50);
insert into dish values('叫花鸡',133,0.81,'p20131006',50,50);
insert into dish values('叫花鸡',133.1,0.8,'p20131007',50,50)
5)ord
insert into ord values('c20120001',1378001,'p20131001','2000-05-01 12:35:29.998',1,'梧桐路99号','正常');
insert into ord values('c20120001',1378011,'p20131001','2000-05-02 12:35:29.998',2,'梧桐路99号','正常');
insert into ord values('c20120002',1378006,'p20131004','2000-05-03 12:35:29.998',3,'梧桐路77号','正常');
insert into ord values('c20120002',1378007,'p20131004','2000-05-04 12:35:29.998',4,'梧桐路77号','正常');
insert into ord values('c20120002',1378009,'p20131005','2000-05-05 12:35:29.998',5,'梧桐路77号','正常');
insert into ord values('c20120004',1378004,'p20131002','2000-05-06 12:35:29.998',6,'梧桐路88号','正常');
insert into ord values('c20120005',1378004,'p20131002','2000-05-07 12:35:29.998',7,'梧桐路88号','正常');
insert into ord values('c20120006',1378003,'p20131007','2000-05-08 12:35:29.998',8,'梧桐路66号','正常');
insert into ord values('c20120006',1378004,'p20131002','2000-05-09 12:35:29.998',9,'梧桐路66号','正常');
6)manager_client
insert into manager_client values('m001','c20120001','2013-05-08 12:35:29','增加');
insert into manager_client values('m001','c20120002','2013-05-08 12:37:29','增加');
insert into manager_client values('m003','c20120003','2013-05-08 12:38:29','增加');
insert into manager_client values('m002','c20120004','2013-05-08 12:39:29','增加');
insert into manager_client values('m002','c20120005','2013-05-08 13:35:29','增加');
insert into manager_client values('m003','c20120006','2013-05-08 14:35:29','增加');
7)manager_provider
insert into manager_provider values('m003','p20131001','2013-02-08 14:35:29','允许注册');
insert into manager_provider values('m003','p20131002','2013-02-08 15:35:29','允许注册');
insert into manager_provider values('m003','p20131003','2013-02-08 16:35:29','允许注册');
insert into manager_provider values('m003','p20131004','2013-02-08 17:35:29','允许注册');
insert into manager_provider values('m003','p20131005','2013-02-08 18:35:29','允许注册');
insert into manager_provider values('m003','p20131006','2013-02-08 19:35:29','允许注册');
insert into manager_provider values('m003','p20131007','2013-02-08 19:39:29','允许注册');
六、数据库的运行和维护
作为网管员,无论其管理的网络的规模是大还是小,在日常的管理中除了维护网络平稳运行、及时排除网络故障、保护网络安全等工作以外,备份网络中关键数据也是其中的一个非常非常重要的工作环节。
网络中的各种故障无非就分两种:软件故障和硬件故障。对于“硬件故障”可以通过维修或更换硬件设备得到及时解决;对于“软件故障”则可以通过重新安装或升级软件、重做网络或应用软件系统等方法及时解决,而且用此方法来解决网络故障大多需要一些基础的、关键的数据支持才能得以恢复正常。但是,网络中诸如此类的关键数据(特别是“应用软件系统”中的关键数据)的损坏或丢失,绝大部分是无法恢复和弥补的。
6.1定义并设置备份
6.2启用维护计划任务
6.3运行要求:
操作系统:Windows xp及以上版本,
数据库:SQL server2005,
外围平台:Microsoft Visual studio2010
内存:2G
七、感想及总结:
此次的数据库课程设计中,我通过与小组内的其他两位同学的共同探讨与努力,设计并实现了人生中的第一个数据库,由于刚刚上完数据库的课程,此次的动手实践确实加深了我对数据库这门课程的理解,同时也发现了许多平常忽略的问题。平时看书上的E-R图十分简单,但自己设计的时候却发现需要考虑许多细节,稍有疏忽就会产生许多棘手的问题。E-R图之后还要考虑表,视图,触发器,索引,完整性约束等问题,对于第一次设计数据库的我们来说刚开始的时候确实感觉到无从下手,很难把问题考虑全面,最终我们三人共同讨论并设计出了数据库的雏形,这时的数据库看起来还十分简陋。后来我们的开发方式进行了改变,由我和一个同学分别扮演客户和商家的角色,另一位同学扮演数据库角色。开发过程中,数据库角色的同学主要考虑优化数据库并满足客户角色和商家角色的要求,而客户角色和商家角色在完成自己的应用平台的过程中向数据库提出要求,主要是对权限的申请、对触发器视图等方面的要求。这样我们的数据库就大概成形了,然后我们三人又共同以全面地角度审视了一遍我们的数据库,提出各自的意见,最后提交的数据库则是我们三人共同意志的体现。
八、源码:
// Client.cpp : 定¡§义°?控?制?台¬¡§应®|用®?程¨¬序¨°的Ì?入¨?口¨²点Ì?。¡ê
//
#include "stdafx.h"
#include #include #include #include #include using namespace std; #import "c:\\program files\\common files\\system\\ado\\msado15.dll" no_namespace rename("EOF", "adoEOF") void work1() { _ConnectionPtr m_pConnection; _RecordsetPtr m_pRecordset; char i_user[15],i_pwd[15]; cout<<"*********************请?输º?入¨?用®?户¡ì名?及¡ã密¨¹码?登Ì?录?*********************************"< CoInitialize(NULL); try{ m_pConnection.CreateInstance("ADODB.Connection"); cout<<"...1"< m_pConnection->Open((_bstr_t)"Provider=SQLOLEDB;Server=(local);Database=database_zbg;uid="+i_user+";pwd="+i_pwd+";","","",adModeUnknown); cout<<"...2"< catch(_com_error e) { cout<<"Cannot connect to Database "< } cout<<"已°?成¨¦功|登Ì?录?"< m_pRecordset->Open("select * from provider where p_state='营®a业°¦Ì中D'",m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText); cout<<"*****************************目?前¡ã营®a业°¦Ì中D的Ì?商¦¨¬家¨°**************************"< cout< while(!m_pRecordset->adoEOF) { vpid=m_pRecordset->GetCollect("p_id"); ame=m_pRecordset->GetCollect("p_name"); vpadd=m_pRecordset->GetCollect("p_add"); vptel=m_pRecordset->GetCollect("p_tel"); vplev=m_pRecordset->GetCollect("p_lev"); cout< } m_pRecordset->Close(); cout<<"请?输º?入¨?所¨´选?商¦¨¬家¨°的Ì?编À¨¤号?"< cin>>pid; m_pRecordset->Open((_variant_t)((_bstr_t)"select * from dish where d_pid='"+pid+"'and d_remain>0"),m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText); cout<<"******************************请?选?择?菜?品¡¤************************"< int cnt=1; while(!m_pRecordset->adoEOF) { vdid[cnt]=m_pRecordset->GetCollect("d_id"); vdpid[cnt]=m_pRecordset->GetCollect("d_pid"); vdname=m_pRecordset->GetCollect("d_name"); vdprice=m_pRecordset->GetCollect("d_price"); vdremain=m_pRecordset->GetCollect("d_remain"); cout< m_pRecordset->MoveNext(); } char caddr[200],num[15]; int did; cout<<"请?输º?入¨?送¨ª菜?地Ì?址¡¤"< cout<<"请?输º?入¨?选?择?的Ì?菜?品¡¤的Ì?编À¨¤号?以°?及¡ã数ºy量¢?"< { if(did==0) break; cin>>num; m_pConnection->Execute((_bstr_t)"insert into ord (o_cid,o_did,o_pid,o_num,o_cadd) values ('"+i_user+"','"+(char*)(_bstr_t)vdid[did]+"','"+(char*)(_bstr_t)vdpid[did]+"','"+num+"','"+caddr+"')",NULL, 1); // m_pConnection->Execute((_bstr_t)"update dish set d_remain=d_remain-"+num,NULL,1); } cout<<"************************已°?接¨®受º¨¹您¨²的Ì?订?单Ì£¤,ê?感D谢?您¨²的Ì?支¡ì持?**************************"< m_pConnection->Close(); CoUninitialize(); } void work2() { _ConnectionPtr m_pConnection; _RecordsetPtr m_pRecordset; CoInitialize(NULL); m_pConnection.CreateInstance("ADODB.Connection"); m_pConnection->ConnectionTimeout=30; m_pConnection->Open("Provider=SQLOLEDB;Server=(local);Database=database_zbg;uid=sa;pwd=sa;","","",adModeUnknown); m_pRecordset.CreateInstance("ADODB.Recordset"); cout<<"*************************************请?输º?入¨?注Á¡é册¨¢id以°?及¡ã密¨¹码?**************************************"< do{ cin>>w2_id>>w2_pwd; m_pRecordset->Open((_bstr_t)"select * from client where c_id='"+w2_id+"'",m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText); if(!m_pRecordset->adoEOF) { cout<<"该?id已°?被À?使º1用®?,ê?请?重?新?输º?入¨?"< else { cout<<"该?id可¨¦以°?使º1用®?"< cin>>name>>tel; m_pConnection->Execute((_bstr_t)"insert into client(c_id,c_name,c_key,c_tel) values ('"+w2_id+"','"+name+"','"+w2_pwd+"','"+tel+"')",NULL,1); m_pConnection->Execute((_bstr_t)"create login "+w2_id+" with password='"+w2_pwd+"'",NULL,1); m_pConnection->Execute((_bstr_t)"create user "+name+"for login "+w2_id,NULL,1); m_pConnection->Execute((_bstr_t)"grant connect to "+name,NULL,1); _CommandPtr m_pCommand; m_pCommand.CreateInstance("ADODB.Connection"); _ParameterPtr param; char role[5]="c"; param=m_pCommand->CreateParameter("",adVarChar,adParamInput,sizeof(role),role); m_pCommand->Parameters->Append(param); param=m_pCommand->CreateParameter("",adVarChar,adParamInput,sizeof(name),name); m_pCommand->Parameters->Append(param); m_pCommand->CommandText=_bstr_t("sp_addrolemember"); m_pCommand->ActiveConnection=m_pConnection; m_pCommand->CommandType=adCmdStoredProc; m_pCommand->Execute(NULL,NULL,adCmdStoredProc); m_pCommand.Detach(); m_pRecordset->Close(); cout<<"***********************************************已°?成¨¦功|注Á¡é册¨¢!!!*********************************************"< } m_pRecordset->Close(); }while(1); m_pConnection->Close(); CoUninitialize(); } int _tmain(int argc, _TCHAR* argv[]) { cout<<"***********************欢?迎®-使º1用®?合?工¡è大䨮网ª?上¦?订?餐¨ª系¦Ì统ª3客¨ª户¡ì端?**************************"< char cc; while(1) { cin>>choice; switch(choice){ case 1: work1();break; case 2: work2();break; // case 3: work3();break; default: break; } cout<<"是º?否¤?继¨¬续?进?行D操¨´作Á¡Â?ê?(ê¡§Y/N)ê?"< if(cc=='N') break; else cout<<"请?输º?入¨?选?择?"< cout<<"****************************感D谢?使º1用®?合?工¡è大䨮订?餐¨ª系¦Ì统ª3!ê?!ê?!ê?*****************************"< }