餐饮点餐系统

news2024/10/6 21:46:50

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

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_price
    WHERE 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 THEN
        SIGNAL 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, totalItems
    FROM carts c
    JOIN cart_items ci ON c.id = ci.cart_id
    WHERE c.user_id = userId AND c.restaurant_id = restaurantId
    GROUP 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.-- 查询用户“小鱼儿”在“江湖酒楼”餐厅中购买的菜品名称和总价
SELECT
    d.name AS dish_name,
    SUM(oi.quantity * oi.price_per_item) AS total_price_for_dish
FROM
    dishes d
JOIN
    order_items oi ON d.id = oi.dish_id
JOIN
    orders o ON oi.order_id = o.id
JOIN
    users u ON o.user_id = u.id
WHERE
    u.username = '小鱼儿'
    AND o.restaurant_id = (SELECT id FROM restaurants WHERE name = '江湖酒楼')
GROUP BY
    d.id, d.name;

-- 注释:
-- 这个查询首先连接了dishes、order_items、orders和users表,

-- 通过用户名和餐厅名称筛选出“小鱼儿”在“江湖酒楼”购买的菜品,

-- 然后使用GROUP BY按菜品名称分组,    -- 并计算每个菜品的总价(数量乘以单价)。

 

2.-- 查询每个餐厅的菜品分类数量,并按数量降序排列
SELECT
    r.name AS restaurant_name,
    COUNT(DISTINCT dc.id) AS number_of_categories
FROM
    restaurants r
JOIN
    dish_categories dc ON r.id = dc.restaurant_id
GROUP BY
    r.id, r.name
ORDER BY
    number_of_categories DESC;


-- 注释:

-- 这个查询连接了restaurants和dish_categories表,

-- 通过餐厅ID关联它们,

-- 然后使用COUNT(DISTINCT ...)计算每个餐厅的不同菜品分类数量,

-- 最后使用ORDER BY按数量降序排列结果。

 

3.-- 查询每个用户的订单数量和总金额,只显示有订单的用户
SELECT
    u.username,
    COUNT(o.id) AS order_count,
    SUM(o.total_price) AS total_spent
FROM
    users u
LEFT JOIN
    orders o ON u.id = o.user_id
GROUP BY
    u.id, u.username
HAVING
    COUNT(o.id) > 0;

-- 注释:

-- 这个查询首先通过LEFT JOIN连接了users和orders表,

-- 然后使用GROUP BY按用户ID和用户名分组,

-- 使用COUNT计算每个用户的订单数量,

-- 使用SUM计算每个用户的订单总金额,
-- 最后使用HAVING子句筛选出有订单的用户(即订单数量大于0的用户)。

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

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

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

相关文章

http服务网络请求如何确保数据安全(含python示例源码)

深度学习类文章回顾 【YOLO深度学习系列】图像分类、物体检测、实例分割、物体追踪、姿态估计、定向边框检测演示系统【含源码】 【深度学习】物体检测/实例分割/物体追踪/姿态估计/定向边框/图像分类检测演示系统【含源码】 【深度学习】YOLOV8数据标注及模型训练方法整体流程…

命令行中关于windows hash md5 , mac hash md5 , linux hash md5 文件校验方式

md5, sha-1 ,sha256. windows certutil -hashfile filename md5certutil -hashfile filename sha1certutil -hashfile filename sha256macos 平台 md5 filenameshasum -a 1 filenameshasum -a 256 filenamelinux 平台 md5sum filenameshasum -a 1 fil…

菜籽桌面4.5.0~4.5.1常见问题解答

目录 如何刷机? 刷机失败? 无法方控? 无法画中画? 原车音乐跟我安装的音乐一起播放? 原车音乐停了,我安装的软件也跟着没声音了? 调节声音时忽大忽小? 怎么安装软件? 软件…

spring boot (shiro)+ websocket测试连接不上的简单检测处理

1、用前端连接测试的demo一切正常,但是到了项目中连接不上了 一开始以为是地址错,但是换了apifox测试也是不可以。 2、考虑是shiro进行了拦截了,所以就访问不到了地址,那么就放行。 3、再次用apifox测试,成功了。 当然…

Halcon 如何让图像自适应窗口

一 如何让图像自适应窗口 read_image(Image,1)get_image_size(Image,Width, Height)dev_close_window()dev_open_window(0,0,Width/2,Height/2,black,WindowHandle)dev_set_part(0,0,Height-800,Width-800)dev_display(Image)二 如何实现彩色图像转化为灰色图像 read_image(I…

Java nio 的线程通信机制线程通信Pipe

Java的Pipe是一种新的线程通信机制,传统的线程通信可以是通过共享内存的方式,socket等方式,而Pipe是通过Java NIO 通信的方式实现共享内存,优点类似于go语言的管道 先上代码 public static void main(String[] args) throws IOEx…

国外的Claude3.5 Sonnet Artifacts和国内的CodeFlying孰强孰弱?

在Claude 3.5 Sonnet发布后,最受大家关注的问题应该就是它在编写代码能力上的变化。 要知道在Claude3.0发布以来的这几个月就因为它的编写代码能力而一直受到人们的诟病。 那Anthropic这次终于是不负众望,在Claude 3.5 Sonnet中更新了一个叫做Artifact…

.net core 的 winform 的 浏览器控件 WebView2

在.NET Core WinForms应用程序中,没有直接的“浏览器控件”,因为WinForms不支持像WebBrowser控件那样的功能。但是,你可以使用WebView2控件,它是一个基于Chromium的浏览器内核,可以在WinForms应用程序中嵌入Web内容。 …

用英文介绍芝加哥(1):Making Modern Chicago Part 1 Building a Boomtown

Making Modern Chicago | Part 1: Building a Boomtown Link: https://www.youtube.com/watch?vpNdX0Dm-J8Y&listPLmSQiOQJmbZ7TU39cyx7gizM9i8nOuZXy&index4 Summary Summary of Chicago’s History and Development Urban Planning and Growth Chicago, often r…

新手入门爬虫:从零开始,轻松掌握网络数据采集技术(有实战)

在互联网高速发展的今天,数据已经成为了各行各业的重要资源。而爬虫作为一种特殊的程序,可以帮助我们快速地获取到大量的数据。本文将从零开始,带领大家了解爬虫的基本概念、原理以及实践操作,帮助新手轻松掌握网络数据采集技术。…

浅谈逻辑控制器之Switch控制器

浅谈逻辑控制器之Switch控制器 Switch Controller是Apache JMeter中一个强大的逻辑控制器,它允许用户基于特定的变量值或参数来控制哪些子采样器被执行。与简单地按照配置顺序执行的控制器不同,Switch Controller根据提供的“switch value”来决定执行哪…

行业推荐!IG5216量产工具下载,IG5216开卡软件分享

国内固态硬盘常用,且有量产工具流传出来的主控厂商包括慧荣、群联、点序、英韧、得一微、瑞昱、联芸、迈威、国科、华澜微等等。 每个主控需要用各自对应的量产工具,不同的量产工具支持的闪存颗粒也有差异,因此要根据固态硬盘实际的主控型号…

Charles抓包工具系列文章(三)-- 接口映射工具(Map Remote和Map Local)

一、背景 前文的http请求都是静态的,像compose a new request,仅适用于接口的自测。 回放repeat 一个 http 请求,也无法做到动态调试。 这里的动态还是静态,是站在客户端的角度,数据是实时的,可调试的。 …

【R语言】plot输出窗口大小的控制

如果需要输出png格式的图片并设置dpi,可采用以下代码 png("A1.png",width 10.09, height 10.35, units "in",res 300) 为了匹配对应的窗口大小,在输出的时候保持宽度和高度一致即可,步骤如下: 如上的“10…

Verilog进行结构描述(四):Verilog逻辑强度(strength)模型

目录 1.Verilog提供多级逻辑强度。2.基本单元强度说明语法3.信号强度值系统4.Verilog多种强度决断 微信公众号获取更多FPGA相关源码: 1.Verilog提供多级逻辑强度。 逻辑强度模型决定信号组合值是可知还是未知的,以更精确的描述硬件的行为。下面这些情…

【ONLYOFFICE深度探索】:ONLYOFFICE桌面编辑器8.1震撼发布,打造高效办公新境界

文章目录 一、功能完善的PDF编辑器:解锁文档处理新维度二、幻灯片版式设计:释放创意,打造专业演示三、改进从右至左显示:尊重多元文化,优化阅读体验四、新增本地化选项:连接全球用户,跨越语言障…

Redis--18--Redis Desktop Manage下载与安装

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 Redis Desktop Manage1.官网下载https://redis.io/insight/ 2.安装方法3.使用方法3.1.进入RedisDesktopManager的主界面3.2 新建连接3.3 支持操作 Redis Desktop Ma…

面试-JMM的内存可见性

1.JAVA内存模型 分析: 由于JVM运行程序的实体是线程,而每个线程创建时,JVM都会 为其创建一个工作内存(栈空间),用于存储线程私有的数据。而java内存模型中规定所有变量都存储在主内存中。主内存是共享内存区域,所有线程都可以访问…

标准版回收站的商品怎么删除?

管理后台/维护/数据维护/清除数据 里面就可以清空回收站的商品

ElasticSearch-Windows系统ElasticSearch(ES)的下载及安装

前言 下载ElasticSearch 可以进入ElasticSearch官方下载地址,选择与电脑系统相对应的版本;博主已经上传资源,或者点此直接免费下载,本次演示版本为8.14.1。 注意: Elasticsearch 5 需要 Java 8 以上版本;…