MYSQL实训--------------餐饮点餐系统

1、E-R图

2、数据模型图

3、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 user_wallet (
    wallet_id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    balance DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

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='订单项表';

4、DML

-- 插入用户数据
INSERT INTO users (username, password, email, gender, phone) VALUES
('小鱼儿', 'xiaoyu_pass', 'xiaoyu@example.com', '男', '1234567890'),
('花无缺', 'huawu_pass', 'huawu@example.com', '男', '0987654321'),
('小香', 'xiaoxiang_pass', 'xiaoxiang@example.com', '男', '15603102023'),
('小玖', 'xiaojiu_pass', 'xiaojiu@example.com', '女', '15530063071'),
('苏樱', 'suying_pass', 'suying@example.com', '女', '5555555555');
 
-- 插入钱包数据
INSERT INTO `user_wallet` VALUES ('1', '1', '422.00', '2024-06-08 22:07:42');
INSERT INTO `user_wallet` VALUES ('2', '2', '600.00', '2024-06-04 22:07:42');
INSERT INTO `user_wallet` VALUES ('3', '3', '150.00', '2024-06-03 22:07:42');
INSERT INTO `user_wallet` VALUES ('4', '4', '489.00', '2024-06-07 22:07:42');
INSERT INTO `user_wallet` VALUES ('5', '5', '319.00', '2024-06-06 22:07:42');
 
-- 插入餐厅数据
INSERT INTO restaurants (name, address, opening_hours, contact_number) VALUES
('江湖酒楼', '京城大街1号', '09:00-22:00', '12345678'),
('美味轩', '长安路88号', '10:00-21:30', '87654321'),
('蟹堡王', '海洋大街3号', '8:00-23:30', '987456123'),
('美味坊', '京津路666号', '12:00-4:00', '963852741'),
('清风阁', '西湖路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,total_price) VALUES
(1, 1,50.00); -- 小鱼儿在江湖酒楼下订单
 
 
-- 获取订单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); -- 菜品:宫保鸡丁




-- 插入购物车数据(假设小香在江湖酒楼和清风阁有购物车)
INSERT INTO carts (user_id, restaurant_id) VALUES
(3, 1), -- 小香在江湖酒楼
(3, 3); -- 小香在清风阁

-- 获取购物车id
SET @cartId1 = (SELECT id FROM carts WHERE user_id = 3 AND restaurant_id = 1);
SET @cartId2 = (SELECT id FROM carts WHERE user_id = 3 AND restaurant_id = 3);


-- 插入购物车项数据(假设小香在江湖酒楼选择了前两个菜品,在清风阁选择了后两个菜品)
INSERT INTO cart_items (cart_id, dish_id, quantity) VALUES
(@cartId1, 3, 2), -- 麻婆豆腐
(@cartId1, 2, 1), -- 宫保鸡丁
(@cartId2, 8, 1), -- 辣椒炒肉
(@cartId2, 9, 3); -- 红烧肉

-- 插入订单数据(假设小香在清风阁下了一个订单)
INSERT INTO orders (user_id, restaurant_id,total_price) VALUES
(3, 3,100.00); -- 小香在清风阁下订单

-- 获取订单id
SET @orderId1 = LAST_INSERT_ID();

-- 插入订单项数据(假设小香购买了购物车中的辣椒炒肉和红烧肉)
INSERT INTO order_items (order_id, dish_id, quantity, price_per_item) VALUES
(@orderId1, 8, 1, 42.00), -- 菜品:辣椒炒肉
(@orderId1, 9, 3, 55.00); -- 菜品:红烧肉

-- 插入购物车数据(假设小玖在蟹堡王和美味坊有购物车)
INSERT INTO carts (user_id, restaurant_id) VALUES
(4, 4), -- 小玖在蟹堡王
(4, 5); -- 小玖在美味坊

-- 获取购物车id
SET @cartId3 = (SELECT id FROM carts WHERE user_id = 4 AND restaurant_id = 4);
SET @cartId4 = (SELECT id FROM carts WHERE user_id = 4 AND restaurant_id = 5);


-- 插入购物车项数据(假设小玖在美味坊选择了前两个菜品,在蟹堡王选择了后两个菜品)
INSERT INTO cart_items (cart_id, dish_id, quantity) VALUES
(@cartId3,4,2), -- 白切鸡
(@cartId3,5,1), -- 清蒸鲈鱼
(@cartId4,	7,1), -- 剁椒鱼头
(@cartId4,9,3); -- 红烧肉

-- 插入订单数据(假设小玖在蟹堡王下了一个订单)
INSERT INTO orders (user_id, restaurant_id,total_price) VALUE
(4,4,150.00);-- 小玖在蟹堡王下订单

-- 获取订单id
SET @orderId2= LAST_INSERT_ID();

-- 插入订单项数据(假设小玖购买了购物车中的清蒸鲈鱼和剁椒鱼头)
INSERT INTO order_items (order_id, dish_id, quantity, price_per_item) VALUES
(@orderId2, 5,1,78.00),-- 菜品:清蒸鲈鱼
(@orderId2 ,7,1,62.00); -- 菜品:剁椒鱼头

-- 插入购物车数据(假设花无缺在美味坊和美味轩有购物车)
INSERT INTO carts (user_id, restaurant_id) VALUES
(2, 4), -- 花无缺在美味坊
(2,2 ); -- 花无缺在美味轩

-- 获取购物车id
SET @cartId3 = (SELECT id FROM carts WHERE user_id = 2 AND restaurant_id = 4);
SET @cartId4 = (SELECT id FROM carts WHERE user_id = 2 AND restaurant_id = 2);

-- 插入购物车项数据(假设花无缺在美味坊选择了前两个菜品,在美味轩选择了后两个菜品)
INSERT INTO cart_items (cart_id, dish_id, quantity) VALUES
(@cartId3,3,2), -- 麻婆豆腐
(@cartId3,5,1), -- 清蒸鲈鱼
(@cartId4,	7,1), -- 剁椒鱼头
(@cartId4,6,3); -- 菠萝咕噜肉

-- 插入订单数据(假设花无缺在美味轩下了一个订单)
INSERT INTO orders (user_id, restaurant_id,total_price) VALUE
(2,2,250.00);-- 花无缺在美味轩下订单

-- 获取订单id
SET @orderId3= LAST_INSERT_ID();

-- 插入订单项数据(假设花无缺购买了购物车中的清蒸鲈鱼和菠萝咕噜肉)
INSERT INTO order_items (order_id, dish_id, quantity, price_per_item) VALUES
(@orderId3, 5,1,78.00),-- 菜品:清蒸鲈鱼
(@orderId3 ,6,3,52.00); -- 菜品:菠萝咕噜肉

-- 插入购物车数据(假设苏樱在江湖酒楼和美味坊有购物车)
INSERT INTO carts (user_id, restaurant_id) VALUES
(5, 1), -- 苏樱在江湖酒楼
(5, 4); -- 苏樱在美味坊

-- 获取购物车id5
SET @cartId5 = (SELECT id FROM carts WHERE user_id = 5 AND restaurant_id = 1);
SET @cartId6 = (SELECT id FROM carts WHERE user_id =5  AND restaurant_id = 4);

-- 插入购物车项数据(假设苏樱在美味坊选择了前两个菜品,在江湖酒楼选择了后两个菜品)
INSERT INTO cart_items (cart_id, dish_id, quantity) VALUES
(@cartId5,1,2), -- 水煮鱼
(@cartId5,5,1), -- 清蒸鲈鱼
(@cartId6,	8,2), -- 辣椒炒肉
(@cartId6,6,3); -- 菠萝咕噜肉

-- 插入订单数据(假设苏樱在美味坊下了一个订单)
INSERT INTO orders (user_id, restaurant_id,total_price) VALUE
(5,4,350.00);-- 苏樱在美味坊下订单

-- 获取订单id
SET @orderId4= LAST_INSERT_ID();

-- 插入订单项数据(假设苏樱购买了购物车中的水煮鱼和辣椒炒肉)
INSERT INTO order_items (order_id, dish_id, quantity, price_per_item) VALUES
(@orderId4, 1,2,58.00),-- 菜品:水煮鱼
(@orderId4 ,8,2,42.00); -- 菜品:辣椒炒肉

5、简单查询

1、查询用户信息,仅显示用户的姓名与手机号,用中文显示列名。中文显示姓名列与手机号列

select username as '姓名',phone as '手机号' from users ;

2、模糊查询

create index idx_name on dishes(`name`);
explain select *from dishes where `name` like '香%';

3、统计用户订单信息,查询所有用户的下单数量,并进行倒序排列

select order_id,count(order_id)as '订单数量'
from order_items
group by order_id
order by `订单数量` desc;

6、多表联合查询

1、查询用户的基本信息,订单信息。

SELECT 
    u.id, -- 选择用户的用户ID
    u.username, -- 选择用户名
    u.email, -- 选择邮箱
    u.phone, -- 选择电话
    uw.wallet_id, -- 选择钱包ID
    uw.balance -- 选择钱包余额
FROM 
    users u -- 从用户表中选择数据
JOIN 
    user_wallet uw ON u.id = uw.user_id; -- 使用JOIN连接用户表和钱包表,连接条件是两个表中的user_id相同

2、查看订单中下单最多的菜品对应的类别。

select
	p.name as '下单最多的菜品种类'
from 
	dish_categories p
inner join 
	dishes d on p.id = d.category_id
inner join 
	order_items oi on d.id = oi.dish_id
where
	oi.order_id in (
	select 
	o.id
	from
	orders o
	where 
	o.user_id=(
	select 
	user_id
	from	
	orders
	group by
	user_id	
	order by
	count(*) desc
	limit 1
		)
)
group by
	p.name
order by
	sum(oi.quantity) desc
limit 1;

3、查询下单总金额最多的用户,并查询用户的全部信息

set @topUserId =(
	select	user_id
	from orders
	group by  user_id
	order by
	sum(total_price) desc
	limit 1
);
select 
	u.*,
	uw.balance as wallet_balance
	from users u
join	
	user_wallet uw on u.id = uw.user_id
where
	u.id = @topUserId ;

7、触发器---插入---修改---删除

1、用户表添加语句添加触发器,要求在添加用户信息时同时初始化用户钱包表数据,初始金额为0。

delimiter $$
create trigger after_user_insert
after insert on users
for each row
begin
	insert into user_wallet (user_id,balance) values(NEW.id,0.00);
end ;
$$
delimiter ;

测试语句 

insert into users values(0,'小刘','xiaoliu_password','xiaoliu@emplain','男','7418529630');

2、菜品表修改语句添加触发器,要求在修改商品售价时不允许上下浮动超过10%。 

delimiter $$
create trigger check_dish_price_chage
before update on dishes
for each row
begin
	declare original_price decimal(10,2);
	declare new_price decimal(10,2);
	declare price_difference decimal(10,2);

	set original_price = OLD.price;
	set new_price = NEW.price;

	set price_difference =(new_price - original_price) / original_price * 100;

	if new_price > original_price and price_difference > 10 then 
		signal sqlstate '45000'
		set message_text = '价格超出';
	end if ;
	if new_price < original_price and abs(price_difference) > 10 then
		signal sqlstate '45000'
		set message_text = '价格超出';
	end if ; 
end ;
$$
delimiter ;

测试语句  

update dishes set price = 100.00 where `name` = '麻婆豆腐';

 手动测试

3、订单表删除语句添加触发器,要求在删除订单信息时先删除订单详情表中的订单信息。 

delimiter $$
create trigger before_delete_order
before delete on orders 
for each row  
begin 
		delete from order_items where order_id = OLD.id;
end;
$$
delimiter ;

测试语句 

delete from  order_items where order_id =@orderId1;
select *  from order_items where order_id =@orderId1;

 8、存储过程创建

1.计算某个用户的总订单金额

delimiter $$
create procedure orderAmount (in userID int)
begin
	declare total_amount decimal (10,2) default 0.00;
	
	select sum(oi.quantity * oi.price_per_item) into total_amount
	from order_items oi
	join orders o on oi.order_id = o.id
	where o.user_id = userID;

	select total_amount as total_order_amount;
end;
$$
delimiter ;

call orderAmount (1);

2.在数据库中创建一个新的订单,并更新相关的用户钱包余额和订单详情。 

DELIMITER //

CREATE PROCEDURE UpdateUserWalletBalanceAfterPayment(IN p_orderId INT)
BEGIN
    -- 声明变量
    DECLARE v_userId INT;
    DECLARE v_totalPrice DECIMAL(10, 2);
    DECLARE v_walletBalance DECIMAL(10, 2);

    -- 从订单表中获取用户ID和订单总价
    SELECT user_id, total_price
    INTO v_userId, v_totalPrice
    FROM orders
    WHERE id = p_orderId;

    -- 从用户钱包表中获取当前余额
    SELECT balance
    INTO v_walletBalance
    FROM user_wallet
    WHERE user_id = v_userId;

    -- 检查余额是否足够支付
    IF v_walletBalance >= v_totalPrice THEN
        -- 更新用户钱包余额
        UPDATE user_wallet
        SET balance = v_walletBalance - v_totalPrice
        WHERE user_id = v_userId;

        -- 更新订单状态为已支付(可选,取决于您的业务逻辑)
        UPDATE orders
        SET status = '已支付'
        WHERE id = p_orderId;

        -- 输出成功信息(可选)
        SELECT '支付成功,余额已更新。';
    ELSE
        -- 余额不足,输出错误信息(可选)
        SELECT '余额不足,支付失败。';
    END IF;
END //

DELIMITER ;

CALL UpdateUserWalletBalanceAfterPayment(1); -- 假设订单ID为1的订单已被支付

买的起效果: 

买不起效果: 

### 餐厅点餐管理系统 MySQL 数据库设计 #### 表结构设计 为了实现一个高效的餐厅点餐管理系统,数据库的设计至关重要。以下是几个核心表及其字段说明: - **用户表 (users)** 存储系统用户的个人信息。 | 字段名 | 类型 | 描述 | |------------|-------------|-------------------| | user_id | INT(11) | 用户唯一标识 | | username | VARCHAR(50) | 登录用户名 | | password | CHAR(32) | MD5 加密后的密码 | | email | VARCHAR(100)| 用户邮箱 | ```sql CREATE TABLE users ( user_id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50), password CHAR(32), email VARCHAR(100) ); ``` - **菜单项表 (menu_items)** 记录所有可供选择的食物条目。 | 字段名 | 类型 | 描述 | |---------------|-------------|--------------------| | item_id | INT(11) | 菜单项唯一标识 | | name | VARCHAR(100)| 名字 | | description | TEXT | 简介 | | price | DECIMAL(8,2)| 单价 | | category_id | INT(11) | 所属分类 ID | ```sql CREATE TABLE menu_items ( item_id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), description TEXT, price DECIMAL(8,2), category_id INT ); ``` - **订单表 (orders)** 维护顾客提交的每一个订单的信息。 | 字段名 | 类型 | 描述 | |--|---------------------| | order_id | INT(11) | 订单编号 | | user_id | INT(11) | 下单者 ID | | total_price | DECIMAL(8,2)| 总金额 | | status | ENUM('pending', 'completed') | 订单状态 | | created_at | TIMESTAMP | 创建时间戳 | ```sql CREATE TABLE orders ( order_id INT AUTO_INCREMENT PRIMARY KEY, user_id INT, total_price DECIMAL(8,2), status ENUM('pending', 'completed'), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ``` - **订单详情表 (order_details)** 关联具体订单中的各个菜品以及数量。 | 字段名 | 类型 | 描述 | |---------------|-------------|-------------------------| | detail_id | INT(11) | 明细记录唯一标识 | | order_id | INT(11) | 对应订单 ID | | item_id | INT(11) | 商品 ID | | quantity | SMALLINT | 数量 | | sub_total | DECIMAL(8,2)| 小计 | ```sql CREATE TABLE order_details ( detail_id INT AUTO_INCREMENT PRIMARY KEY, order_id INT, item_id INT, quantity SMALLINT, sub_total DECIMAL(8,2) ); ``` 这些表格共同构成了基本的数据模型,支持了从浏览菜单到完成支付整个流程的功能需求[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值