【数据库实践】基于OpenGauss的餐厅后台管理系统
1 需求分析
1.1 背景分析
在中国文化中,饮食文化一直扮演着很重要的角色,餐饮业是一个历史悠久的行业。随着社会的不断发展、科技的不断进步、人民的经济水平提高带动了消费水平的发展,大家对吃的形式要求越来越多样,对餐饮服务的需求也从单独的食物质量扩展到服务的便利性、高效性。随着互联网的不断发展,越来越多的人习惯于手机支付而非传统的现金支付,期望实现自助点单、自助结算的一体化服务。
随着餐厅运营规模的不断扩充,顾客流量的不断增长,年轻的消费群体变得越来越多,更现代、快捷、时尚的消费观在慢慢形成,普通的基于服务员点餐的运转模式越来越不能够满足当代人需求。
随着餐厅业务的发展与客流量的增多,服务员在面对客户点单时遇到越来越多无法解决的问题,比如人流量太多无法及时为每一位顾客点单,客户需要提前预约下单或者点本店外卖。
而计算机辅助点餐管理能够使管理者的收集和处理信息的能力得到大大地提高,使管理者能及时做出相应的决策。计算机系统可以根据管理过程的变化,对原始数据及时进行数据处理、存储。管理人员可以解决的具体问题是,在需要信息的时候,随时检索查询。要了解整个餐饮管理系统的动态情况,需对其进行动态管理,从而有效地处理餐饮的管理,实现餐饮管理信息的自动化管理。利用计算机来管理,使前台服务和后台服务的一次性结账得以实现。随着餐饮服务业的日益发展,对餐饮企业进行计算机辅助管理,是现代餐饮管理模式的一个明智选择。
1.2 系统功能需求
1.2.1 用户信息管理模块
本模块实现对进行用户信息增添、查找、修改等操作,分别对应于用户的注册、登录、修改密码功能。
- 用户注册
用户使用用户名和密码进行注册,在注册过程中,检验用户填写的用户名是否已经被注册过,要求注册的用户名不能和已注册的用户名重复。用户需要两次输入密码,检验两次的密码是否相同,不相同需要重新输入。
- 用户登录
用户使用注册的用户名和密码进行登录,检验所输入的用户名在系统中是否存在、密码是否正确,随后提示是否登录成功,若登录失败,给出具体失败原因。登录成功后根据该用户的用户信息自动跳转到系统页面中。
- 修改密码
用户可以通过该功能修改密码。
1.2.2 菜品管理模块
本模块实现对菜品进行管理,具体功能为查找、上新、下架菜品。
- 菜品查询
管理员可以通过该功能查看餐厅中已上架的菜品。
- 菜品上新
管理员可以通过该功能在系统内上架新菜品。
- 菜品下架
管理员可以通过该功能在系统内下架菜品。
- 菜品修改
管理员可以通过该功能在系统内修改菜品。
1.2.3 餐桌信息管理模块
本模块可以实现对餐桌用餐情况的总览以及增加或减少用餐位置。
- 餐桌信息查询
管理员可以通过该功能查询各餐桌状态,以便为顾客找寻空位置就餐。
- 餐桌信息增加
管理员可以增加新的用餐位置。
- 餐桌信息删除
管理员可以删除用餐位置。
- 餐桌信息修改
管理员可以修改用餐位置相关信息。
1.2.4 订单管理模块
本模块实现订单管理的功能。
- 查看订单
服务员可以通过该功能查看已有的订单。
- 修改订单状态
服务员可以在顾客结束用餐后将订单状态设置为已完成或者也可以选择在接受到订单时退回订单。
- 修改订单
在顾客提交订单后,如果因某些原因(顾客手滑点错了菜)需要修改订单,管理员有权限通过此功能修改订单。
- 删除订单
在顾客提交订单后,如果因某些原因(顾客身份的特殊性、隐私需求)需要删除订单,管理员有权限通过此功能删除订单。
1.3 其他性能需求
- 需要数据库支持万级数据量,相应时间不超过2s。
- 用户界面设计友好,有足够的交互。
1.4 技术路线
开发语言:C++ SQL
开发环境:Windows 10 + QT Creator 10.0.1
数据库:OpenGuass
2. 概念结构设计
2.1 实体关系分析
- 用户实体,包括属性:用户名、密码、注册时间、用户类型。
图2-1 用户实体图
- 订单实体,包括属性:订单号、用餐人数、点单时间、订单状态。
图2-2 订单实体图
- 餐桌实体,包括属性:餐桌号、餐桌人数、餐桌状态。
图2-3 餐桌实体图
- 菜品实体,包括属性:菜品序号、菜名、定价、类别、简介。
图2-4 菜品实体图
实体间具有如下联系:
- 一个用户可以点多个订单,一个订单只能由一个用户点单,因此用户和订单之间具有一对多关系。
- 一个订单只能在一个餐桌中产生,一个餐桌可能产生不同的订单,因此餐桌和订单之间具有一对多关系。
- 一个用户可能在多个餐桌就餐,一个餐桌可供多个用户就餐,因此餐桌和用户之间具有多对多关系。
- 一个订单中可能包含多个菜品,一个菜品可能在多个订单中被包含,因此订单和菜品之间具有多对多关系。
- 一个管理员用户可以管理多个订单、餐桌和菜品,一个订单、餐桌和菜品可被多个管理员用户管理,因此管理员用户与订单、餐桌和菜品都有多对多关系。
综上所述,可以画出实体联系图:
图2-5实体联系
综合上图,可画出完整E-R图:
图2-6 E-R图
3. 逻辑结构设计
3.1 关系模式设计
将E-R图转换为如下关系模式(其中加粗为主键,斜体为外键):
用户(用户名,密码,用户类型,注册时间)
订单(订单号,用户名,餐桌号,用餐人数,点餐时间,订单状态)
餐桌(餐桌号,餐桌人数,餐桌状态)
菜品(菜品序号,菜名,定价,类别,简介)
订单菜品(订单号,菜品序号,数量)
3.2 数据类型定义
- 用户表
表1 用户表
数据项名 |
数据类型 |
长度 |
完整性约束 |
备注 |
UserName |
varchar |
64 |
主键,非空 |
用户名 |
UserPassword |
varchar |
64 |
非空 |
密码 |
UserType |
int2 |
16 |
非空,为0或1 |
类型(0表示商家,1表示用户) |
CreateTime |
timestamp |
6 |
非空 |
创建时间 |
- 订单表
表2 订单表
数据项名 |
数据类型 |
长度 |
完整性约束 |
备注 |
OrderID |
int8 |
64 |
主键,非空,递增 |
订单号 |
TbaleID |
int4 |
32 |
外键,非空 |
桌号 |
UserName |
varchar |
64 |
外键,非空 |
用户名 |
PeopleNum |
int4 |
32 |
非空,大于0 |
用餐人数 |
OrderTime |
timestamp |
6 |
非空 |
点餐时间 |
OrderState |
int2 |
16 |
非空,为0或1或2 |
订单状态(0表示进行中,1表示已完成,2表示已退回) |
- 餐桌表
表3 餐桌表
数据项名 |
数据类型 |
长度 |
完整性约束 |
备注 |
TableID |
int4 |
32 |
主键,非空,递增 |
餐桌号 |
PeopleNum |
int4 |
32 |
非空,大于0 |
餐桌人数 |
TableState |
int2 |
16 |
非空,为0或1 |
餐桌状态(0表示空闲,1表示使用中) |
- 菜品表
表4 菜品表
数据项名 |
数据类型 |
长度 |
完整性约束 |
备注 |
DishID |
int4 |
32 |
主键,非空,递增 |
菜品序号 |
DishName |
varchar |
128 |
非空 |
菜名 |
DishPrice |
float8 |
53 |
非空,大于等于0 |
定价 |
DishType |
varchar |
128 |
非空 |
类别 |
DishIntro |
varchar |
512 |
|
简介 |
- 订单菜品表
表5 订单菜品表
数据项名 |
数据类型 |
长度 |
完整性约束 |
备注 |
OrderID |
int8 |
64 |
主键,外键,非空,递增 |
订单号 |
DishID |
int4 |
32 |
主键,外键,非空,递增 |
菜品序号 |
DishNum |
int4 |
32 |
非空,大于0 |
菜品数量 |
4. 创建数据库
4.1 连接数据库
首先租用华为云弹性云服务器ECS,按教程安装OpenGuass,配置OpenGuass,将加密方式改为md5加密,监听本机ip地址,在华为云安全组配置中开放26000端口,最后使用Navicat 15连接数据库。
图4-1 Navicat连接数据库
4.2 建立数据库
首先建立一个与本用户同名的模式:CREATE SCHEMA jxm AUTHORIZATION jxm;,在这个模式下建立本程序需要的表。
- 建立用户表(sysuser)
CREATE TABLE sysuser
(
UserName VARCHAR(64) PRIMARY KEY,
UserPassword VARCHAR (64) NOT NULL,
UserType int2 NOT NULL CHECK (UserType = 0 OR UserType = 1),
CreateTime timestamp NOT NULL
);
- 建立餐桌表(table)
CREATE TABLE table
(
TableID int4 PRIMARY KEY,
PeopleNum int4 NOT NULL CHECK (PeopleNum > 0),
TableState int2 NOT NULL CHECK (TableState = 0 OR TableState = 1)
);
- 建立订单表(order)
CREATE TABLE order
(
OrderID int8 PRIMARY KEY,
TableID int4 NOT NULL,
UserName varchar(64) NOT NULL,
PeopleNum int4 NOT NULL CHECK (PeopleNum > 0),
OrderTime timestamp NOT NULL,
OrderState int2 NOT NULL CHECK (OrderState = 0 OR OrderState = 1 OR OrderState = 2)
FOREIGN KEY (TableID) REFERENCES table. TableID,
FOREIGN KEY (UserName) REFERENCES sysuser. UserName
);
- 建立菜品表(dish)
CREATE TABLE dish
(
DishID int4 PRIMARY KEY,
DishName varchar(128) NOT NULL,
DishPrice float8 NOT NULL CHECK (DishPrice >= 0),
DishType varchar(128) NOT NULL,
DishIntro varchar(512)
);
- 建立订单菜品(dishinorder)
CREATE TABLE dishinorder
(
OrderID int8,
DishID int4,
DishNum int4 NOT NULL CHECK (DishNum > 0),
PRIMARY KEY(OrderID,DishID),
FOREIGN KEY (OrderID) REFERENCES order. OrderID,
FOREIGN KEY(DishNum) REFERENCES dish.DishID
);
5.系统结构设计
5.1 c++利用ODBC连接数据库
首先按照教程安装ODBC Windows版本并连接数据库:
图5-1 ODBC连接数据库
之后在QT Creater中使用QT的库函数利用ODBC连接数据库:
- void Widget::SetSQLConnection()
- {
- db = QSqlDatabase::addDatabase("QODBC");
- QString dsn = QString::fromLocal8Bit("OpenGauss");
- qDebug()<<"ODBC connect?"<<db.isValid();
- db.setHostName("70.90.125");//IP地址
- db.setDatabaseName(dsn);
- db.setUserName("jxm"); //用户名
- db.setPassword("openGauss@1234");//密码
- db.setPort(26000); //端口号为26000
- if(!db.open())
- {
- qDebug()<<db.lastError().text();
- QMessageBox::critical(0, QObject::tr("Database error"), db.lastError().text());
- return;
- }
- else
- qDebug()<<"database open success!";
- }
5.2 程序整体架构
主界面由两部分组成,分别是左边的logo、控件、提示窗口和右边的主窗口,控件实现右边主窗口各功能界面的切换,提示窗口实现相关系统提示的显示。
图5-2 主界面整体框架
右边主窗口利用一个堆栈窗口部件stackedWidget来控制各个功能界面的切换,主要包括注册、登录、订单管理、菜品管理、餐桌管理、账号管理6个功能界面,程序刚进入时显示登录界面,各功能界面需要实现相应对数据的增删改查等功能,具体实现在第六章详细解释。
6.具体设计
6.1 注册功能设计
图6-1 注册界面
注册逻辑:
- 用户输入用户名、密码和重复密码,点击注册按钮。
- 判断用户两次输入密码是否一致,不一致时报错,并提示用户重新输入。
- 根据用户输入的用户名去数据库查找用户名是否已存在,存在时报错,并提示用户重新输入。
- 注册成功,将注册数据插入数据库sysuser表,返回登录界面。
6.2 登录功能设计
图6-2 登录界面
注册逻辑:
- 用户输入用户名、密码,点击登录按钮。
- 在数据库查找相应记录,若用户名不存在或密码错误则报错,并提示用户重新输入。
- 登录成功,进入订单管理界面
6.3 订单管理功能设计
图6-3 订单管理界面
订单管理界面中实现了订单的筛选,修改和删除功能。
订单筛选:
可以筛选订单状态,订单状态分为进行中,已完成,已退回三种,用户可以依照自己的需求选择对应的筛选条件进行筛选。该功能主要服务后厨选择进行中的订单进行制作。
订单筛选主要是利用了数据库的查找功能,根据不同的查找条件查找相应的记录并显示在屏幕上。
订单删除:
为满足某些用户特殊需求(如隐私需求),需要删除订单记录时,管理员可以使用此功能删除特定的订单记录。
订单删除主要利用了数据库的删除记录指令,用户在表格中选中一行并点击删除按钮,确定后可删除数据库中保存的相应订单记录。
订单修改:
由于可能存在用户点错单等问题,需要配合商家对订单进行修改,因此设计了订单修改功能。订单修改的逻辑是用户双击对应订单行时进入子窗口,在子窗口中可以进行订单对应数据的修改,修改完毕由用户提交后返回主窗口处理,将修改数据写入数据库。
由于子窗口需要保存主窗口传递过来的记录数据,并将用户修改过后的数据返回主窗口,因此需要自己重写一个继承自QDialog的类Dialog_Order,设计相应控件。类中有公有变量struct order用于存储记录信息,主窗口在调出子窗口前需要将所选中记录数据写入子窗口控件中。用户在子窗口中修改数据并提交后,通过变量order传回主窗口,主窗口使用数据库的update功能更新记录数据。
同时由于订单内显示菜品需要进行dish表和dishinorder表的连接,为了方便查询我建立了视图order_dish。
CREATE VIEW order_dish
AS
SELECT
dish."DishName",
"order"."OrderID",
dishinorder."DishNum",
"order"."UserName",
dish."DishPrice"
FROM
(
( dish JOIN dishinorder ON ( ( dish."DishID" = dishinorder."DishID" ) ) )
JOIN "order" ON ( ( dishinorder."OrderID" = "order"."OrderID" ) )
);
图6-4 修改订单界面
6.4 菜品管理功能设计
图6-5 菜品管理界面
菜品管理界面中实现了菜品的查询、新增、修改和删除功能,其中查询、修改和删除功能和订单的相应功能逻辑相似,故不赘述。
新增菜品:
图6-6 新增菜品界面
新增菜品功能复用了修改菜品的子窗口,在主窗口调用子窗口时向子窗口传入一个flag用于标记是修改还是新增,主窗口将子窗口内的输入控件内容初始设置为空,子窗口将用户输入和标记返回给主窗口,主窗口根据返回的标记选择处理逻辑。当需要新增时使用数据库的insert命令将用户新输入的数据插入至表dish。
6.5 餐桌管理功能设计
餐桌管理页面中实现了餐桌的筛选、修改、新增、删除功能。在展示餐桌时为了便于查看和交互使用了图6-5所示圆角矩形的方式展示一个餐桌,背景为蓝色的矩形代表餐桌正在使用中,背景为白色则代表餐桌空闲。
在用户交互方面,在保留双击修改餐桌的功能的同时,设计了用户单击切换餐桌状态的功能,方便服务员快速为顾客安排餐桌。
图6-7 餐桌管理界面
6.6 账号管理功能设计
账号管理界面中实现了修改密码和退出登录功能,修改密码需要用户两次输入密码,确认后将密码的更新写入数据库,然后返回登录界面。
用户点击退出登录后会返回登录界面。
图6-8 账号管理界面
图6-9修改密码界面
7. 界面适配和交互设计
7.1 界面控件动态适配大小
界面控件布局随窗口大小动态变化,保证良好的视觉体验。界面采用框架布局,具有层次感,控件样式适配程序主要美术风格,风格统一。
图7-1默认最小大小
图7-2 全屏大小
7.2 flowlayout流式布局
使用QT所给的系统例子中的flowlayout来实现餐桌按钮的流式布局,使按钮布局随窗口大小变化自动调整。
图7-3 不同宽度下餐桌管理页面
8. 规范检测
8.1 数据库完整性约束条件
在创建表时使用CHECK规定了某些列的取值,如OrderState等有特定取值,DishPrice等需要限制范围(>=0)的。
图8-1 完整性约束条件
8.2 界面规范检测
对某些需要限定范围的值使用validator验证器进行了输入限制,关键代码:
- //验证器
- QIntValidator *validator = new QIntValidator(this);
- validator->setBottom(0);
- table_value->setValidator(validator);
- num_value->setValidator(validator);
对某些不能为空的值进行了输入检测,关键代码:
- if(num_value->text() == "")
- {
- QMessageBox msgBox(this);
- msgBox.setWindowTitle("提示");
- msgBox.setText("人数不可以为空,请重试");
- msgBox.exec();
- return;
- }
9. 百万条数据支持
sysuser表生成100万条记录:
对登录、注册几乎没有影响。
order表生成100万条记录,在显示时全部同时显示100万条记录时间不可接收,因此选择每次显示1000条记录,用户点击下一页时显示下1000条记录,相应时间在1s以内。
- 点赞
- 收藏
- 关注作者
评论(0)