餐饮点餐系统

餐饮点餐系统是一款为餐厅和顾客提供便捷点餐服务的在线平台。

1.DDL


CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户ID',username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名',password VARCHAR(255) NOT NULL COMMENT '密码',email VARCHAR(100) UNIQUE COMMENT '邮箱地址',gender ENUM('男', '女') NOT NULL COMMENT '性别',phone VARCHAR(20) COMMENT '电话号码'
) COMMENT='用户表';CREATE TABLE restaurants (id INT AUTO_INCREMENT PRIMARY KEY COMMENT '餐厅ID',name VARCHAR(100) NOT NULL COMMENT '餐厅名称',address VARCHAR(255) NOT NULL COMMENT '餐厅地址',opening_hours VARCHAR(50) COMMENT '营业时间',contact_number VARCHAR(20) COMMENT '联系电话'
) COMMENT='餐厅表';CREATE TABLE dish_categories (id INT AUTO_INCREMENT PRIMARY KEY COMMENT '菜品分类ID',name VARCHAR(50) NOT NULL COMMENT '分类名称',restaurant_id INT NOT NULL COMMENT '所属餐厅ID',FOREIGN KEY (restaurant_id) REFERENCES restaurants(id) ON DELETE CASCADE
) COMMENT='菜品分类表';CREATE TABLE dishes (id INT AUTO_INCREMENT PRIMARY KEY COMMENT '菜品ID',name VARCHAR(100) NOT NULL COMMENT '菜品名称',description TEXT COMMENT '菜品描述',price DECIMAL(10, 2) NOT NULL COMMENT '菜品价格',category_id INT NOT NULL COMMENT '所属分类ID',restaurant_id INT NOT NULL COMMENT '所属餐厅ID',FOREIGN KEY (category_id) REFERENCES dish_categories(id) ON DELETE CASCADE,FOREIGN KEY (restaurant_id) REFERENCES restaurants(id) ON DELETE CASCADE
) COMMENT='菜品表';CREATE TABLE carts (id INT AUTO_INCREMENT PRIMARY KEY COMMENT '购物车ID',user_id INT NOT NULL COMMENT '用户ID',restaurant_id INT NOT NULL COMMENT '餐厅ID',FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,FOREIGN KEY (restaurant_id) REFERENCES restaurants(id) ON DELETE CASCADE
) COMMENT='购物车表';CREATE TABLE cart_items (id INT AUTO_INCREMENT PRIMARY KEY COMMENT '购物车项ID',cart_id INT NOT NULL COMMENT '购物车ID',dish_id INT NOT NULL COMMENT '菜品ID',quantity INT NOT NULL COMMENT '数量',FOREIGN KEY (cart_id) REFERENCES carts(id) ON DELETE CASCADE,FOREIGN KEY (dish_id) REFERENCES dishes(id) ON DELETE CASCADE
) COMMENT='购物车项表';CREATE TABLE orders (id INT AUTO_INCREMENT PRIMARY KEY COMMENT '订单ID',user_id INT NOT NULL COMMENT '用户ID',restaurant_id INT NOT NULL COMMENT '餐厅ID',order_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '订单日期',total_price DECIMAL(10, 2) NOT NULL COMMENT '订单总价',status ENUM('待支付', '已支付', '已取消', '已完成') NOT NULL DEFAULT '待支付' COMMENT '订单状态',FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,FOREIGN KEY (restaurant_id) REFERENCES restaurants(id) ON DELETE CASCADE
) COMMENT='订单表';CREATE TABLE order_items (id INT AUTO_INCREMENT PRIMARY KEY COMMENT '订单项ID',order_id INT NOT NULL COMMENT '订单ID',dish_id INT NOT NULL COMMENT '菜品ID',quantity INT NOT NULL COMMENT '数量',price_per_item DECIMAL(10, 2) NOT NULL COMMENT '单价',FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE,FOREIGN KEY (dish_id) REFERENCES dishes(id) ON DELETE CASCADE
) COMMENT='订单项表';

2.DML

-- 插入用户数据
INSERT INTO users (username, password, email, gender, phone) VALUES
('小鱼儿', 'xiaoyu_pass', 'xiaoyu@example.com', '男', '1234567890'),
('花无缺', 'huawu_pass', 'huawu@example.com', '男', '0987654321'),
('苏樱', 'suying_pass', 'suying@example.com', '女', '5555555555');-- 插入餐厅数据
INSERT INTO restaurants (name, address, opening_hours, contact_number) VALUES
('江湖酒楼', '京城大街1号', '09:00-22:00', '12345678'),
('美味轩', '长安路88号', '10:00-21:30', '87654321'),
('清风阁', '西湖路123号', '11:00-23:00', '98765432');-- 插入菜品分类数据
INSERT INTO dish_categories (name, restaurant_id) VALUES
('川菜', 1),
('粤菜', 2),
('湘菜', 3),
('鲁菜', 1),
('苏菜', 2),
('浙菜', 3);-- 插入菜品数据
INSERT INTO dishes (name, description, price, category_id, restaurant_id) VALUES
('水煮鱼', '麻辣鲜香,回味无穷', 58.00, 1, 1),
('宫保鸡丁', '色泽红亮,口感鲜美', 48.00, 1, 1),
('麻婆豆腐', '麻辣可口,下饭佳品', 38.00, 1, 1),
('白切鸡', '皮爽肉滑,鲜美无比', 68.00, 2, 2),
('清蒸鲈鱼', '鲜嫩可口,营养丰富', 78.00, 2, 2),
('菠萝咕噜肉', '酸甜可口,色泽诱人', 52.00, 2, 2),
('剁椒鱼头', '香辣可口,回味无穷', 62.00, 3, 3),
('辣椒炒肉', '香辣可口,下饭佳品', 42.00, 3, 3),
('红烧肉', '肥而不腻,入口即化', 55.00, 3, 3);- 插入购物车数据(假设小鱼儿在江湖酒楼和美味轩有购物车)
INSERT INTO carts (user_id, restaurant_id) VALUES
(1, 1), -- 小鱼儿在江湖酒楼
(1, 2); -- 小鱼儿在美味轩-- 获取购物车id
SET @cartId1 = (SELECT id FROM carts WHERE user_id = 1 AND restaurant_id = 1);
SET @cartId2 = (SELECT id FROM carts WHERE user_id = 1 AND restaurant_id = 2);-- 插入购物车项数据(假设小鱼儿在江湖酒楼选择了前两个菜品,在美味轩选择了后两个菜品)
INSERT INTO cart_items (cart_id, dish_id, quantity) VALUES
(@cartId1, 1, 2), -- 水煮鱼
(@cartId1, 2, 1), -- 宫保鸡丁
(@cartId2, 4, 1), -- 白切鸡
(@cartId2, 5, 3); -- 清蒸鲈鱼-- 插入订单数据(假设小鱼儿在江湖酒楼下了一个订单)
INSERT INTO orders (user_id, restaurant_id) VALUES
(1, 1); -- 小鱼儿在江湖酒楼下订单-- 获取订单id
SET @orderId = LAST_INSERT_ID();-- 插入订单项数据(假设小鱼儿购买了购物车中的水煮鱼和宫保鸡丁)
INSERT INTO order_items (order_id, dish_id, quantity, price_per_item) VALUES
(@orderId, 1, 2, 58.00), -- 菜品:水煮鱼
(@orderId, 2, 1, 48.00); -- 菜品:宫保鸡丁

3.er图以及模型图 

 

4.触发器和测试语句 

1.DELIMITER //
CREATE TRIGGER trg_calculate_order_total_before_insert
BEFORE INSERT ON order_items
FOR EACH ROW
BEGIN-- 计算订单项总价,并更新到订单表中DECLARE total_price DECIMAL(10, 2) DEFAULT 0.00;-- 假设这是单个订单项插入,所以直接计算这个订单项的总价SET total_price = NEW.quantity * NEW.price_per_item;-- 更新订单的总价(这里假设一个订单只有一个订单项插入,实际中可能需要累加)UPDATE orders SET total_price = total_priceWHERE id = (SELECT order_id FROM (SELECT order_id FROM order_items WHERE id = NEW.id) AS subquery);
END;
//
DELIMITER ;-- 注意:这个触发器假设每次只插入一个订单项,并且订单表中total_price字段在插入订单项之前为空或需要更新。-- 在实际情况中,您可能需要修改这个触发器以处理一个订单中多个订单项的插入,并正确累加总价。
-- 测试语句:插入一个新的订单项,并检查订单表中的总价是否已自动更新 INSERT INTO order_items (order_id, dish_id, quantity, price_per_item) VALUES (@orderId, 3, 1, 38.00); -- 假设我们为同一个订单添加了另一个菜品 SELECT * FROM orders WHERE id = @orderId; -- 检查总价是否已更新 
2.DELIMITER //
CREATE TRIGGER trg_log_price_change_after_update
AFTER UPDATE ON dishes
FOR EACH ROW
BEGIN-- 假设我们有一个价格变动日志表CREATE TEMPORARY TABLE IF NOT EXISTS price_change_log (id INT AUTO_INCREMENT PRIMARY KEY,dish_id INT NOT NULL,old_price DECIMAL(10, 2) NOT NULL,new_price DECIMAL(10, 2) NOT NULL,change_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP);-- 插入价格变动记录INSERT INTO price_change_log (dish_id, old_price, new_price)VALUES (OLD.id, OLD.price, NEW.price);
END;
//
DELIMITER ;
-- 测试语句:更新一个菜品的价格,然后查询价格变动日志 UPDATE dishes SET price = 60.00 WHERE id = 1; SELECT * FROM price_change_log; -- 你会看到价格变动的记录 
3.DELIMITER //
CREATE TRIGGER trg_check_dish_price_before_insert
BEFORE INSERT ON dishes
FOR EACH ROW
BEGIN-- 假设每个餐厅都有一个最大菜品价格字段,这里为了简化,我们直接在触发器中设定一个值DECLARE max_price DECIMAL(10, 2) DEFAULT 100.00; -- 示例值,实际情况应从餐厅表中获取-- 检查插入的菜品价格是否超过餐厅设定的最大价格IF NEW.price > max_price THENSIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Dish price exceeds the maximum allowed price for the restaurant.';END IF;
END;
//
DELIMITER ;
-- 测试语句:尝试插入一个价格超过100的菜品,应该会触发错误 INSERT INTO dishes (name, description, price, category_id, restaurant_id) VALUES ('昂贵菜品', '非常昂贵', 150.00, 1, 1); -- 这应该会导致错误

5.存储过程 

DELIMITER //
CREATE PROCEDURE GetCartDetailsForUserAndRestaurant(IN userId INT, IN restaurantId INT, OUT cartId INT, OUT totalItems INT)
BEGIN-- 初始化输出变量SET cartId = NULL;SET totalItems = 0;-- 查询购物车ID和菜品数量SELECT c.id, COUNT(ci.id)INTO cartId, totalItemsFROM carts cJOIN cart_items ci ON c.id = ci.cart_idWHERE c.user_id = userId AND c.restaurant_id = restaurantIdGROUP BY c.id;-- 如果没有找到购物车,cartId 保持为 NULL
END //
DELIMITER ;

测试存储过程


-- 假设我们知道小鱼儿在江湖酒楼有购物车
SET @userId = 1;
SET @restaurantId = 1;
SET @cartId = NULL;
SET @totalItems = 0;CALL GetCartDetailsForUserAndRestaurant(@userId, @restaurantId, @cartId, @totalItems);SELECT @cartId AS CartID, @totalItems AS TotalItems;

 

6.简单查询 

1.-- 查询所有用户的用户名和性别
SELECT username, gender FROM users;-- 注释:
-- 使用SELECT语句从users表中检索username(用户名)和gender(性别)字段的所有数据。

 

2.-- 查询在江湖酒楼餐厅的所有菜品名称和价格
SELECT dishes.name AS dish_name, dishes.price 
FROM dishes 
JOIN restaurants ON dishes.restaurant_id = restaurants.id 
WHERE restaurants.name = '江湖酒楼';-- 注释:-- 使用SELECT语句从dishes和restaurants表中检索数据。-- 通过JOIN操作将dishes表与restaurants表连接起来,基于餐厅ID进行匹配。-- 使用WHERE子句来过滤出在江湖酒楼餐厅的菜品。-- 将dishes表中的name字段重命名为dish_name,以便结果集更清晰。

 

3.
-- 查询小鱼儿的购物车中所有菜品的名称和数量
SELECT dishes.name AS dish_name, cart_items.quantity 
FROM cart_items 
JOIN dishes ON cart_items.dish_id = dishes.id 
JOIN carts ON cart_items.cart_id = carts.id 
WHERE carts.user_id = 1;-- 注释:-- 使用SELECT语句从cart_items、dishes和carts表中检索数据。-- 通过JOIN操作将cart_items表与dishes表和carts表连接起来,基于相应的ID进行匹配。-- 使用WHERE子句来过滤出用户ID为1(即小鱼儿)的购物车中的菜品。-- 将dishes表中的name字段重命名为dish_name,以便结果集更清晰。

7.复杂查询

1.-- 查询用户“小鱼儿”在“江湖酒楼”餐厅中购买的菜品名称和总价
SELECTd.name AS dish_name,SUM(oi.quantity * oi.price_per_item) AS total_price_for_dish
FROMdishes d
JOINorder_items oi ON d.id = oi.dish_id
JOINorders o ON oi.order_id = o.id
JOINusers u ON o.user_id = u.id
WHEREu.username = '小鱼儿'AND o.restaurant_id = (SELECT id FROM restaurants WHERE name = '江湖酒楼')
GROUP BYd.id, d.name;-- 注释:
-- 这个查询首先连接了dishes、order_items、orders和users表,-- 通过用户名和餐厅名称筛选出“小鱼儿”在“江湖酒楼”购买的菜品,-- 然后使用GROUP BY按菜品名称分组,    -- 并计算每个菜品的总价(数量乘以单价)。

 

2.-- 查询每个餐厅的菜品分类数量,并按数量降序排列
SELECTr.name AS restaurant_name,COUNT(DISTINCT dc.id) AS number_of_categories
FROMrestaurants r
JOINdish_categories dc ON r.id = dc.restaurant_id
GROUP BYr.id, r.name
ORDER BYnumber_of_categories DESC;-- 注释:-- 这个查询连接了restaurants和dish_categories表,-- 通过餐厅ID关联它们,-- 然后使用COUNT(DISTINCT ...)计算每个餐厅的不同菜品分类数量,-- 最后使用ORDER BY按数量降序排列结果。

 

3.-- 查询每个用户的订单数量和总金额,只显示有订单的用户
SELECTu.username,COUNT(o.id) AS order_count,SUM(o.total_price) AS total_spent
FROMusers u
LEFT JOINorders o ON u.id = o.user_id
GROUP BYu.id, u.username
HAVINGCOUNT(o.id) > 0;-- 注释:-- 这个查询首先通过LEFT JOIN连接了users和orders表,-- 然后使用GROUP BY按用户ID和用户名分组,-- 使用COUNT计算每个用户的订单数量,-- 使用SUM计算每个用户的订单总金额,
-- 最后使用HAVING子句筛选出有订单的用户(即订单数量大于0的用户)。

总结:通过该系统,餐厅能够展示其菜单,顾客可以浏览菜品,并将其加入购物车或直接下单。系统还提供了订单管理功能,方便餐厅跟踪和处理顾客的订单。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/37103.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++代码行统计程序

前言: 应该每一个学编程的人都很希望知道自己打了多少行代码,而网上又没有好用的统计软件(至少我没找到)。于是我做了一个代码行统计程序。 原理: 由于是上课时打的,只能统计.cpp文件,其它文…

python爬虫之scrapy框架基本使用

python爬虫之scrapy框架基本使用 1、环境安装:pip install scrapy 2、创建一个工程:scrapy startproject xxxPro 3、cd xxxPro 4、在spiders子目录中创建一个爬虫文件:scrapy genspider spiderName www.xxx.com 5、执行工程:scra…

kotlin 携程 withTimeoutOrNull

withTimeoutOrNull 是 Kotlin 协程库中的一个函数&#xff0c;它用于在指定的时间内执行一个协程&#xff0c;如果协程在超时时间内完成&#xff0c;则返回协程的结果&#xff0c;否则返回 null。 函数签名: fun <T> withTimeoutOrNull(timeMillis: Long, block: suspe…

3DEXPERIENCE平台正在推动仿真技术的创新,旨在创造仿真设计的新境界

随着企业数字化转型的不断推进&#xff0c;3DEXPERIENCE 平台正以其前瞻性的技术和服务重塑仿真设计领域的新高度&#xff0c;助力企业实现仿真技术的再次飞跃。该平台不仅整合了先进的仿真工具与设计流程&#xff0c;还促进了跨部门的协作&#xff0c;降低分析仿真对硬件的要求…

QSPI四线SPI:D0、D1、D2、D3

在SPI&#xff08;串行外设接口&#xff09;通信中&#xff0c;D0、D1、D2、D3通常指的是数据线&#xff0c;也叫做数据引脚或通道。这些引脚的使用可能会根据具体设备或配置的不同而有所变化。 标准的SPI通信接口通常包含以下四个主要引脚&#xff1a; MOSI&#xff08;Master…

【第7章】MyBatis-Plus持久层接口之Chain

文章目录 前言一、使用步骤1. query2. update 二、使用提示总结 前言 Chain 是 Mybatis-Plus 提供的一种链式编程风格&#xff0c;它允许开发者以更加简洁和直观的方式编写数据库操作代码。Chain 分为 query 和 update 两大类&#xff0c;分别用于查询和更新操作。每类又分为普…

iptables(10)target(REJECT、LOG)

简介 前面文章介绍iptables的匹配条件,并且已经用到了一些常用动作,比如ACCEPT、DROP、REJECT等。 以下是 iptables 中常用的一些目标(target)及其原理和时机:ACCEPT 原理:允许数据包通过,并停止对后续规则的匹配。 时机:当你想允许特定的数据包通过防火墙时。DROP 原…

远程桌面无法复制粘贴文件到本地怎么办?

远程桌面不能复制粘贴问题 Windows远程桌面为我们提供了随时随地访问文件和数据的便捷途径&#xff0c;大大提升了工作和生活的效率。然而&#xff0c;在使用过程中&#xff0c;我们也可能遇到一些问题。例如&#xff0c;在通过远程桌面传输文件时&#xff0c;常常会出现无法复…

devc++跑酷小游戏4.1.5

导航&#xff1a; Dev-c跑酷小游戏 1.0.0 devc跑酷小游戏1.2.5 devc跑酷游戏1.2.6 devc跑酷游戏2.0.0 devc跑酷游戏2.0.1 devc跑酷游戏2.4.0 devc跑酷小游戏3.5.0 devc小游戏3.8.5 devc跑酷小游戏4.0.0 更新内容: 也没更新多少&#xff0c;改了界面颜色和按钮&#…

突破SaaS产品运营困境:多渠道运营如何集中管理?

随着数字化时代的到来&#xff0c;SaaS&#xff08;软件即服务&#xff09;产品已成为企业日常运营不可或缺的工具。然而&#xff0c;在竞争激烈的市场环境下&#xff0c;SaaS产品运营越来越重视多渠道、多平台布局&#xff0c;以更广泛地触及潜在用户&#xff0c;然而&#xf…

Android Native 客户端属性配置系统使用说明

Android Native 客户端属性配置系统使用说明 背景和问题现代 android 开发基本都基于 gradle 属性设置来进行定制化编译,随着项目的迭代,工程结构越发复杂,配置属性越来越多,越来越多的配置使得上手难度越来越大。 解决方案设计一般而言,在 android 开发中,Gradle 属性系…

新国都:昙花一现or未来可期?

从波动起伏到强势爆发&#xff0c;这份业绩能否持续&#xff1f; 今天我们抽取一名铁杆粉丝想要咨询的公司来说一说——新国都。 一句话总结这家以第三方支付为主营业务的公司业绩&#xff1a;盈利能力突然爆发&#xff0c;23年净利润暴增近16倍&#xff0c;24年Q1净利润大增6…

继承WebMvcConfigurationSupport后居然出现了Bug?

前言 今天在编写文件上传代码时对静态资源进行映射时遇到了一个Bug与各位看官进行分享&#xff0c;首先先复现一下Bug。 复现过程 文件上传类 /*** 文件的上传与下载*/ Slf4j RestController RequestMapping("/common") public class CommonController {Value(&q…

mysql解压版本安装5.7

1. 官网下载好解压版本 我这边5.7版本 https://dev.mysql.com/downloads/file/?id523570 mysql官网 创建 my.ini文件 内容如下 [client] #客户端设置&#xff0c;即客户端默认的连接参数# socket /data/mysqldata/3306/mysql.sock #用于本地连接的socket套接字 # 默…

ASP.NET MVC-简单例子-配置日志文件-log4net

环境&#xff1a; win10&#xff0c;SQL Server 2008 R2 安装 使用NuGet 安装时发现报错并无法安装&#xff1a; 现有 packages.config 文件中检测到一个或多个未解析包依赖项约束。必须解析所有依赖项约束以添加或更新包。如果正在更新这些包&#xff0c;则可忽略此消息&am…

5G EPS fallback

5G EPS Fallback语音方案流程总结-电子发烧友网 (elecfans.com) 5g信令流程详解_5G语音信令流程-CSDN博客 可以参考的文件&#xff1a; 【漫画】图解5G信令流程&#xff1a;08 EPSFallback.docx - 人人文库 (renrendoc.com)

Linux命令 wc(word count)-l(lines)用于统计文件中的行数。

文章目录 1、wc -l2、实战3、wc --help 1、wc -l 在命令 wc -l 中&#xff0c;-l 的英文全称是 lines。这个选项用于指定 wc&#xff08;word count&#xff0c;单词计数&#xff09;命令来统计文件的行数。 例如&#xff0c;当你运行 wc -l load_user_100w_sort.sql 时&…

如何在Android应用中最佳实现“Edge to Edge“特性?

Edge to Edge"特性 要在Android应用中最佳实现"Edge to Edge"特性,可以按照以下步骤进行操作: 1. 设置目标版本:将应用的目标版本设置为Android Q或更高版本。在build.gradle文件中,将targetSdkVersion设置为Q。 2. 设置主题样式:在styles.xml文件中,创…

操作系统之《PV操作》【知识点+详细解题过程】

1、并发进程 &#xff1a; 并发的实质是一个处理器在几个进程之间的多路复用&#xff0c;并发是对有限的物理资源强制行使多用户共享&#xff0c;消除计算机部件之间的互等现象&#xff0c;以提高系统资源利用率。 &#xff08;1&#xff09;并发进程——互斥性&#xff1a; 进…

【pytorch10】统计属性

常见统计属性 norm&#xff08;范数&#xff09;mean,sumprodmax&#xff0c;min&#xff0c;argmin&#xff0c;argmaxkthvalue&#xff0c;topk kthvalue求第几个的位置和第几个的值 topk求top几的这样的一个数值 norm范数 这里的norm表达的是范数的意思&#xff0c;norma…