影院票务管理系统oracle

用户表 :编号,用户名,密码,邮箱,角色,用户头像;
影片表 :编号,影片名称,国外名称,演职人员,导演,电影详情,电影时长,电影类型,电影评分,票房,电影参评人数,上映时间,制片地区,电影海报地址,电影状态;
影院表 :编号,影院名称,影院地址;
放映厅表 :编号,放映厅名称,放映厅容量,所属影院编号;
订单表 :编号,所属用户编号,所属场次编号,电影票座位信息,订单状态,订单价格,订单支付时间,所属用户对象;
订单详情表 :编号,所属放映厅,放映的电影编号,电影放映时间,售价,剩余座位数,场次状态,所属放映厅对象,放映的电影;
评论表:编号,所属用户编号,评论内容,所属电影编号,评论时间,所属用户,评分;

1 需求分析

1.1 用户管理模块

用户管理模块提供完整的账户生命周期管理,支持新用户通过邮箱验证进行注册登录,允许用户维护个人信息(包括头像修改和密码更新),实施基于角色的权限控制(区分普通用户、影院管理员和系统管理员),并记录用户活动历史(如登录时间、购票记录等),确保账户安全性和操作可追溯性。

1.2 影片管理模块

影片管理模块负责维护电影全生命周期数据,包括影片基本信息(名称、导演、时长、类型等)的增删改查,管理影片上映状态(即将上映/热映/已下架),提供多维度搜索筛选功能(按类型、评分、地区等),自动生成票房统计报表,并支持电影海报的上传与展示。

1.3 影院管理模块

影院管理模块实现影院资源的数字化管理,维护影院基础信息(名称、地址等),配置放映厅参数(名称、座位容量),通过地图API展示影院地理分布,并统计各影院场次安排数据(如每日排片量、上座率等),为影院资源调度提供数据支持。

1.4 场次管理模块

场次管理模块提供放映计划的全流程管理,支持创建/修改影厅放映计划(时间、影厅),设置动态票价策略(分时段差异化定价),实现可视化座位图展示,自动监控并更新场次状态(可预订/即将售罄/已售罄),并通过冲突检测机制防止同一影厅时间重叠排片。

1.5 订单管理模块

订单管理模块实现票务交易闭环,支持在线选座购票流程,集成模拟支付系统(支持支付宝/微信等支付方式),管理订单全生命周期状态(待支付/已支付/已取消),提供用户订单历史查询功能,并处理退票业务(含退款规则计算)。

1.6 评论管理模块

评论管理模块构建影片评价体系,允许用户发表评分和文字评论,实施先审后发的审核机制,支持评论互动功能(点赞/回复),自动生成评论分析报告(包含评分分布、热词分析等),并实时更新影片综合评分数据。

2 系统设计

2.1 系统结构功能图

根据需求分析,确定系统结构功能如图2-1所示:

图2-1 系统功能结构图

2.2 功能流程图

系统最主要的功能就是管理员登录之后对各种功能的使用。管理员功能如图4-2所示。

图2-2 管理员登录管理流程

图2-3普通用户登录流程

2.3 数据库设计

整体功能的E-R图如图2-4所示。

图2-4 系统E-R图

本系统包含的数据表如下:

1书架类型表 (shelf_types)

列名 数据类型 字段类型 长度 是否为空 默认值 备注
shelf_type_id NUMBER 主键 - - 书架类型ID
shelf_type_name VARCHAR2 非空 50 - 书架类型名称

2读者类型表 (reader_types)

列名 数据类型 字段类型 长度 是否为空 默认值 备注
reader_type_id NUMBER 主键 - - 读者类型ID
reader_type_name VARCHAR2 非空 50 - 读者类型名称

3书架表 (shelves)

列名 数据类型 字段类型 长度 是否为空 默认值 备注
shelf_id NUMBER 主键 - - 书架ID
shelf_number VARCHAR2 非空 20 - 书架编号
shelf_type_id NUMBER 外键且非空 - - 书架类型ID

4工作人员表 (staff)

列名 数据类型 字段类型 长度 是否为空 默认值 备注
staff_id NUMBER 主键 - - 工作人员ID
staff_name VARCHAR2 非空 100 - 工作人员姓名
staff_position VARCHAR2 非空 50 - 工作人员职位

5图书表 (books)

列名 数据类型 字段类型 长度 是否为空 默认值 备注
book_id NUMBER 主键 - - 图书ID
title VARCHAR2 非空 200 - 图书标题
author VARCHAR2 非空 100 - 图书作者
isbn VARCHAR2 唯一且非空 20 - 图书国际标准书号
publication_year NUMBER 可空 - - 出版年份
shelf_id NUMBER 外键且非空 - - 书架ID

6读者表 (readers)

列名 数据类型 字段类型 长度 是否为空 默认值 备注
reader_id NUMBER 主键 - - 读者ID
reader_name VARCHAR2 非空 100 - 读者姓名
reader_type_id NUMBER 外键且非空 - - 读者类型ID
contact_phone VARCHAR2 可空 15 - 联系电话

7正借阅表 (loans)

列名 数据类型 字段类型 长度 是否为空 默认值 备注
loan_id NUMBER 主键 - - 借阅记录ID
book_id NUMBER 外键且非空 - - 图书ID
reader_id NUMBER 外键且非空 - - 读者ID
loan_date DATE 非空 - - 借书日期
due_date DATE 非空 - - 应还日期

8已还书籍表 (returns)

列名 数据类型 字段类型 长度 是否为空 默认值 备注
return_id NUMBER 主键 - - 还书记录ID
loan_id NUMBER 外键 - - 借阅记录ID
return_date DATE 非空 - - 还书日期

9****通知记录表(overdue_notifications

列名 数据类型 字段类型 长度 是否为空 默认值 备注
notification_id NUMBER 主键 - - 通知记录
loan_id NUMBER 外键 - - 借阅记录 ID
reader_id NUMBER 外键 - - 读者 ID
notification_date DATE 日期 - SYSDATE 通知日期
message VARCHAR2 字符串 500 - 通知内容

10****历史记录表(book_location_history

列名 数据类型 字段类型 长度 是否为空 默认值 备注
history_id NUMBER 主键 - - 历史记录
book_id NUMBER 外键 - - 图书 ID
old_shelf_id NUMBER 外键 - - 旧书架 ID
new_shelf_id NUMBER 外键 - - 新书架 ID
change_date DATE 日期 - SYSDATE 变更日期
changed_by NUMBER 外键 - - 操作人 ID

3 SQL实现

sql 复制代码
-- 创建用户表
CREATE TABLE 用户表 (
    编号 NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    用户名 VARCHAR2(100) NOT NULL,
    密码 VARCHAR2(100) NOT NULL,
    邮箱 VARCHAR2(100) UNIQUE NOT NULL,
    角色 VARCHAR2(50) NOT NULL,
    用户头像 VARCHAR2(255)
);

-- 创建影片表
CREATE TABLE 影片表 (
    编号 NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    影片名称 VARCHAR2(200) NOT NULL,
    国外名称 VARCHAR2(200),
    演职人员 VARCHAR2(500),
    导演 VARCHAR2(100),
    电影详情 VARCHAR2(1000),
    电影时长 NUMBER, -- 电影时长(以分钟为单位)
    电影类型 VARCHAR2(100),
    电影评分 NUMBER CHECK (电影评分 BETWEEN 0 AND 10),
    票房 NUMBER,
    电影参评人数 NUMBER,
    上映时间 DATE,
    制片地区 VARCHAR2(100),
    电影海报地址 VARCHAR2(255),
    电影状态 VARCHAR2(50) -- 电影状态,例如正在上映或已下架
);

-- 创建影院表
CREATE TABLE 影院表 (
    编号 NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    影院名称 VARCHAR2(100) NOT NULL,
    影院地址 VARCHAR2(255) NOT NULL
);

-- 创建放映厅表
CREATE TABLE 放映厅表 (
    编号 NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    放映厅名称 VARCHAR2(100) NOT NULL,
    放映厅容量 NUMBER NOT NULL,
    所属影院编号 NUMBER,
    FOREIGN KEY (所属影院编号) REFERENCES 影院表(编号)
);

-- 创建订单详情表
CREATE TABLE 订单详情表 (
    编号 NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    所属放映厅 NUMBER,
    放映的电影编号 NUMBER,
    电影放映时间 DATE,
    售价 NUMBER NOT NULL,
    剩余座位数 NUMBER NOT NULL,
    场次状态 VARCHAR2(50), -- 可预订、已售罄等状态
    FOREIGN KEY (所属放映厅) REFERENCES 放映厅表(编号),
    FOREIGN KEY (放映的电影编号) REFERENCES 影片表(编号)
);

-- 创建订单表
CREATE TABLE 订单表 (
    编号 NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    所属用户编号 NUMBER,
    所属场次编号 NUMBER,
    电影票座位信息 VARCHAR2(500), -- 存储座位信息
    订单状态 VARCHAR2(50),
    订单价格 NUMBER NOT NULL,
    订单支付时间 DATE,
    FOREIGN KEY (所属用户编号) REFERENCES 用户表(编号),
    FOREIGN KEY (所属场次编号) REFERENCES 订单详情表(编号)
);

-- 创建评论表
CREATE TABLE 评论表 (
    编号 NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    所属用户编号 NUMBER,
    评论内容 VARCHAR2(1000),
    所属电影编号 NUMBER,
    评论时间 DATE DEFAULT SYSDATE,
    所属用户 VARCHAR2(100),
    评分 NUMBER CHECK (评分 BETWEEN 0 AND 10),
    FOREIGN KEY (所属用户编号) REFERENCES 用户表(编号),
    FOREIGN KEY (所属电影编号) REFERENCES 影片表(编号)
);
sql 复制代码
-- 用户表索引
CREATE INDEX idx_username ON 用户表 (用户名);
CREATE INDEX idx_email ON 用户表 (邮箱);

-- 影片表索引
CREATE INDEX idx_movie_name ON 影片表 (影片名称);
CREATE INDEX idx_director ON 影片表 (导演);
CREATE INDEX idx_movie_rating ON 影片表 (电影评分);

-- 影院表索引
CREATE INDEX idx_cinema_name ON 影院表 (影院名称);

-- 放映厅表索引
CREATE INDEX idx_screening_room_name ON 放映厅表 (放映厅名称);

-- 订单表索引
CREATE INDEX idx_user_id ON 订单表 (所属用户编号);
CREATE INDEX idx_showtime_id ON 订单表 (所属场次编号);

-- 订单详情表索引
CREATE INDEX idx_hall_id ON 订单详情表 (所属放映厅);
CREATE INDEX idx_movie_id ON 订单详情表 (放映的电影编号);

-- 评论表索引
CREATE INDEX idx_user_id_comment ON 评论表 (所属用户编号);
CREATE INDEX idx_movie_id_comment ON 评论表 (所属电影编号);
sql 复制代码
-- 创建用户信息视图
CREATE VIEW 用户信息视图 AS
SELECT 编号 AS 用户编号, 用户名, 邮箱, 角色
FROM 用户表;

-- 创建正在上映电影视图
CREATE VIEW 正在上映电影视图 AS
SELECT 编号 AS 电影编号, 影片名称, 上映时间, 票房, 电影状态
FROM 影片表
WHERE 电影状态 = '正在上映';

-- 创建影院放映厅信息视图
CREATE VIEW 影院放映厅信息视图 AS
SELECT c.编号 AS 影院编号, c.影院名称, c.影院地址, 
       r.编号 AS 放映厅编号, r.放映厅名称, r.放映厅容量
FROM 影院表 c
JOIN 放映厅表 r ON c.编号 = r.所属影院编号;

-- 创建用户订单详情视图
CREATE VIEW 用户订单详情视图 AS
SELECT o.编号 AS 订单编号, u.用户名, 
      m.影片名称, d.电影放映时间,
      o.电影票座位信息, o.订单状态
FROM 订单表 o
JOIN 用户表 u ON o.所属用户编号 = u.编号
JOIN 订单详情表 d ON o.所属场次编号 = d.编号
JOIN 影片表 m ON d.放映的电影编号 = m.编号;

-- 创建用户电影评论视图
CREATE VIEW 用户电影评论视图 AS
SELECT c.编号 AS 评论编号, u.用户名, 
      m.影片名称, c.评论内容, c.评分, c.评论时间
FROM 评论表 c
JOIN 用户表 u ON c.所属用户编号 = u.编号
JOIN 影片表 m ON c.所属电影编号 = m.编号;
sql 复制代码
-- 创建用户注册存储过程
CREATE OR REPLACE PROCEDURE 用户注册 (
    p_username IN VARCHAR2,
    p_password IN VARCHAR2,
    p_email IN VARCHAR2,
    p_role IN VARCHAR2
) AS
BEGIN
    INSERT INTO 用户表 (用户名, 密码, 邮箱, 角色)
    VALUES (p_username, p_password, p_email, p_role);
END 用户注册;
/

-- 创建更新订单状态存储过程
CREATE OR REPLACE PROCEDURE 更新订单状态 (
    p_order_id IN NUMBER,
    p_new_status IN VARCHAR2
) AS
BEGIN
    UPDATE 订单表
    SET 订单状态 = p_new_status
    WHERE 编号 = p_order_id;

    COMMIT; -- 提交事务
END 更新订单状态;
/

-- 创建计算电影平均评分函数
CREATE OR REPLACE FUNCTION 计算电影平均评分 (
    p_movie_id IN NUMBER
) RETURN NUMBER AS
    v_average_rating NUMBER;
BEGIN
    SELECT AVG(评分)
    INTO v_average_rating
    FROM 评论表
    WHERE 所属电影编号 = p_movie_id;

    RETURN NVL(v_average_rating, 0); -- 如果没有评分,则返回0
END 计算电影平均评分;
/

-- 创建查询用户订单总数函数
CREATE OR REPLACE FUNCTION 查询用户订单总数 (
    p_user_id IN NUMBER
) RETURN NUMBER AS
    v_order_count NUMBER;
BEGIN
    SELECT COUNT(*)
    INTO v_order_count
    FROM 订单表
    WHERE 所属用户编号 = p_user_id;

    RETURN v_order_count;
END 查询用户订单总数;
/
sql 复制代码
-- 自动更新影片评分和参评人数
CREATE OR REPLACE TRIGGER 更新影片评分
AFTER INSERT OR UPDATE OR DELETE ON 评论表
FOR EACH ROW
DECLARE
    v_电影编号 影片表.编号%TYPE;
BEGIN
    IF INSERTING THEN
        v_电影编号 := :NEW.所属电影编号;
        UPDATE 影片表 SET
            电影评分 = (SELECT AVG(评分) FROM 评论表 WHERE 所属电影编号 = v_电影编号),
            电影参评人数 = (SELECT COUNT(*) FROM 评论表 WHERE 所属电影编号 = v_电影编号)
        WHERE 编号 = v_电影编号;
    ELSIF DELETING THEN
        v_电影编号 := :OLD.所属电影编号;
        UPDATE 影片表 SET
            电影评分 = (SELECT AVG(评分) FROM 评论表 WHERE 所属电影编号 = v_电影编号),
            电影参评人数 = (SELECT COUNT(*) FROM 评论表 WHERE 所属电影编号 = v_电影编号)
        WHERE 编号 = v_电影编号;
    ELSE
        -- 处理电影变更的情况
        IF :NEW.所属电影编号 != :OLD.所属电影编号 THEN
            -- 更新原电影
            UPDATE 影片表 SET
                电影评分 = (SELECT AVG(评分) FROM 评论表 WHERE 所属电影编号 = :OLD.所属电影编号),
                电影参评人数 = (SELECT COUNT(*) FROM 评论表 WHERE 所属电影编号 = :OLD.所属电影编号)
            WHERE 编号 = :OLD.所属电影编号;
            
            -- 更新新电影
            UPDATE 影片表 SET
                电影评分 = (SELECT AVG(评分) FROM 评论表 WHERE 所属电影编号 = :NEW.所属电影编号),
                电影参评人数 = (SELECT COUNT(*) FROM 评论表 WHERE 所属电影编号 = :NEW.所属电影编号)
            WHERE 编号 = :NEW.所属电影编号;
        ELSE
            -- 只更新当前电影
            UPDATE 影片表 SET
                电影评分 = (SELECT AVG(评分) FROM 评论表 WHERE 所属电影编号 = :NEW.所属电影编号),
                电影参评人数 = (SELECT COUNT(*) FROM 评论表 WHERE 所属电影编号 = :NEW.所属电影编号)
            WHERE 编号 = :NEW.所属电影编号;
        END IF;
    END IF;
END;
/

-- 订单支付后更新场次座位
CREATE OR REPLACE TRIGGER 更新场次座位
AFTER UPDATE OF 订单状态 ON 订单表
FOR EACH ROW
WHEN (NEW.订单状态 = '已支付' AND OLD.订单状态 != '已支付')
DECLARE
    v_座位数 NUMBER;
BEGIN
    -- 计算订单中的座位数量(以逗号分隔)
    v_座位数 := REGEXP_COUNT(:NEW.电影票座位信息, ',') + 1;
    
    UPDATE 订单详情表
    SET 剩余座位数 = 剩余座位数 - v_座位数
    WHERE 编号 = :NEW.所属场次编号;
END;
/

-- 自动更新场次状态
CREATE OR REPLACE TRIGGER 更新场次状态
AFTER UPDATE OF 剩余座位数 ON 订单详情表
FOR EACH ROW
BEGIN
    IF :NEW.剩余座位数 <= 0 THEN
        UPDATE 订单详情表
        SET 场次状态 = '已售罄'
        WHERE 编号 = :NEW.编号;
    ELSIF :NEW.剩余座位数 < (:NEW.剩余座位数 + :NEW.剩余座位数 * 0.2) THEN  -- 示例:少于20%座位时
        UPDATE 订单详情表
        SET 场次状态 = '即将售罄'
        WHERE 编号 = :NEW.编号;
    ELSE
        UPDATE 订单详情表
        SET 场次状态 = '可预订'
        WHERE 编号 = :NEW.编号;
    END IF;
END;
/

-- 新评论自动关联用户名
CREATE OR REPLACE TRIGGER 填充评论用户名
BEFORE INSERT ON 评论表
FOR EACH ROW
BEGIN
    SELECT 用户名 INTO :NEW.所属用户
    FROM 用户表
    WHERE 编号 = :NEW.所属用户编号;
END;
/

-- 票房自动累加
CREATE OR REPLACE TRIGGER 更新影片票房
AFTER UPDATE OF 订单状态 ON 订单表
FOR EACH ROW
WHEN (NEW.订单状态 = '已支付' AND OLD.订单状态 != '已支付')
DECLARE
    v_电影编号 影片表.编号%TYPE;
BEGIN
    -- 获取关联的电影编号
    SELECT 放映的电影编号 INTO v_电影编号
    FROM 订单详情表
    WHERE 编号 = :NEW.所属场次编号;
    
    -- 更新票房
    UPDATE 影片表
    SET 票房 = 票房 + :NEW.订单价格
    WHERE 编号 = v_电影编号;
END;
/

-- 场次时间冲突检查
CREATE OR REPLACE TRIGGER 检查场次冲突
BEFORE INSERT OR UPDATE ON 订单详情表
FOR EACH ROW
DECLARE
    v_conflict_count NUMBER;
BEGIN
    SELECT COUNT(*) INTO v_conflict_count
    FROM 订单详情表
    WHERE 所属放映厅 = :NEW.所属放映厅
    AND 编号 != :NEW.编号  -- 排除自身
    AND 电影放映时间 BETWEEN :NEW.电影放映时间 - INTERVAL '2' HOUR
                     AND :NEW.电影放映时间 + INTERVAL '2' HOUR;
    
    IF v_conflict_count > 0 THEN
        RAISE_APPLICATION_ERROR(-20001, '该放映厅在此时间段已有其他场次安排');
    END IF;
END;
/

1. 用户管理操作

sql 复制代码
-- 用户注册
INSERT INTO 用户表 (用户名, 密码, 邮箱, 角色) 
VALUES ('张三', 'zhangsan123', 'zhangsan@example.com', '普通用户');

-- 用户信息更新
UPDATE 用户表 
SET 用户头像 = 'avatars/zhangsan.jpg', 密码 = 'newpassword123' 
WHERE 用户名 = '张三';

-- 用户删除
DELETE FROM 用户表 WHERE 用户名 = '张三';

-- 用户登录验证
SELECT 编号, 用户名, 角色 FROM 用户表 
WHERE 邮箱 = 'zhangsan@example.com' AND 密码 = 'zhangsan123';

2. 影片管理操作

sql 复制代码
-- 添加新影片
INSERT INTO 影片表 (
    影片名称, 国外名称, 导演, 电影详情, 电影时长, 
    电影类型, 上映时间, 制片地区, 电影海报地址, 电影状态
) VALUES (
    '流浪地球', 'The Wandering Earth', '郭帆', 
    '太阳即将毁灭,人类在地球表面建造巨大推进器...',
    125, '科幻/灾难', DATE '2019-02-05', '中国', 
    'posters/wandering_earth.jpg', '已下架'
);

-- 更新影片信息
UPDATE 影片表 
SET 电影评分 = 7.9, 电影参评人数 = 1250000 
WHERE 影片名称 = '流浪地球';

-- 影片查询 (按类型和评分)
SELECT * FROM 影片表 
WHERE 电影类型 LIKE '%科幻%' AND 电影评分 > 7.0 
ORDER BY 上映时间 DESC;

-- 票房排行榜
SELECT 影片名称, 票房 FROM 影片表 
WHERE 票房 IS NOT NULL 
ORDER BY 票房 DESC 
FETCH FIRST 10 ROWS ONLY;

3. 影院管理操作

sql 复制代码
-- 新增影院
INSERT INTO 影院表 (影院名称, 影院地址) 
VALUES ('万达影城(北京CBD店)', '北京市朝阳区建国路93号万达广场');

-- 新增放映厅
INSERT INTO 放映厅表 (放映厅名称, 放映厅容量, 所属影院编号) 
VALUES ('IMAX厅', 250, (SELECT 编号 FROM 影院表 WHERE 影院名称 = '万达影城(北京CBD店)'));

4. 场次管理操作

sql 复制代码
-- 创建新场次
INSERT INTO 订单详情表 (
    所属放映厅, 放映的电影编号, 电影放映时间, 售价, 剩余座位数, 场次状态
) VALUES (
    (SELECT 编号 FROM 放映厅表 WHERE 放映厅名称 = 'IMAX厅'),
    (SELECT 编号 FROM 影片表 WHERE 影片名称 = '流浪地球'),
    TIMESTAMP '2023-05-20 19:30:00',
    65.00,
    (SELECT 放映厅容量 FROM 放映厅表 WHERE 放映厅名称 = 'IMAX厅'),
    '可预订'
);

-- 查询可用场次
SELECT 
    m.影片名称, 
    c.影院名称, 
    h.放映厅名称, 
    s.电影放映时间, 
    s.售价, 
    s.剩余座位数
FROM 订单详情表 s
JOIN 影片表 m ON s.放映的电影编号 = m.编号
JOIN 放映厅表 h ON s.所属放映厅 = h.编号
JOIN 影院表 c ON h.所属影院编号 = c.编号
WHERE m.影片名称 = '流浪地球'
AND s.电影放映时间 > SYSDATE
AND s.剩余座位数 > 0;

5. 订单管理操作

sql 复制代码
-- 创建新订单
INSERT INTO 订单表 (
    所属用户编号, 所属场次编号, 电影票座位信息, 订单状态, 订单价格
) VALUES (
    (SELECT 编号 FROM 用户表 WHERE 邮箱 = 'zhangsan@example.com'),
    (SELECT 编号 FROM 订单详情表 WHERE 电影放映时间 = TIMESTAMP '2023-05-20 19:30:00'),
    'A5,A6,A7',
    '待支付',
    195.00
);

-- 支付订单
UPDATE 订单表 
SET 订单状态 = '已支付', 订单支付时间 = SYSDATE 
WHERE 编号 = (SELECT MAX(编号) FROM 订单表);

-- 查询用户历史订单
SELECT 
    o.订单支付时间,
    m.影片名称,
    c.影院名称,
    h.放映厅名称,
    s.电影放映时间,
    o.电影票座位信息,
    o.订单价格
FROM 订单表 o
JOIN 订单详情表 s ON o.所属场次编号 = s.编号
JOIN 影片表 m ON s.放映的电影编号 = m.编号
JOIN 放映厅表 h ON s.所属放映厅 = h.编号
JOIN 影院表 c ON h.所属影院编号 = c.编号
WHERE o.所属用户编号 = (SELECT 编号 FROM 用户表 WHERE 邮箱 = 'zhangsan@example.com');

6. 评论管理操作

sql 复制代码
-- 添加评论
INSERT INTO 评论表 (所属用户编号, 评论内容, 所属电影编号, 评分)
VALUES (
    (SELECT 编号 FROM 用户表 WHERE 邮箱 = 'zhangsan@example.com'),
    '特效震撼,中国科幻的里程碑作品',
    (SELECT 编号 FROM 影片表 WHERE 影片名称 = '流浪地球'),
    9.0
);

-- 查询影片评论
SELECT 
    u.用户名,
    c.评论内容,
    c.评分,
    c.评论时间
FROM 评论表 c
JOIN 用户表 u ON c.所属用户编号 = u.编号
WHERE c.所属电影编号 = (SELECT 编号 FROM 影片表 WHERE 影片名称 = '流浪地球')
ORDER BY c.评论时间 DESC;

7. 事务处理示例 (购票全流程)

sql 复制代码
DECLARE
    v_user_id 用户表.编号%TYPE;
    v_session_id 订单详情表.编号%TYPE;
    v_seats VARCHAR2(100) := 'B10,B11';
    v_seat_count NUMBER := 2;
    v_price NUMBER;
BEGIN
    -- 获取用户ID
    SELECT 编号 INTO v_user_id 
    FROM 用户表 WHERE 邮箱 = 'zhangsan@example.com';
    
    -- 获取场次信息和价格
    SELECT 编号, 售价 INTO v_session_id, v_price 
    FROM 订单详情表 
    WHERE 编号 = 101; -- 假设场次ID为101
    
    -- 验证座位可用性
    IF (SELECT 剩余座位数 FROM 订单详情表 WHERE 编号 = v_session_id) < v_seat_count THEN
        RAISE_APPLICATION_ERROR(-20001, '座位不足');
    END IF;
    
    -- 开始事务
    SAVEPOINT start_transaction;
    
    -- 创建订单
    INSERT INTO 订单表 (所属用户编号, 所属场次编号, 电影票座位信息, 订单状态, 订单价格)
    VALUES (v_user_id, v_session_id, v_seats, '待支付', v_price * v_seat_count);
    
    -- 锁定座位 (通过更新场次)
    UPDATE 订单详情表 
    SET 剩余座位数 = 剩余座位数 - v_seat_count 
    WHERE 编号 = v_session_id;
    
    -- 模拟支付成功
    UPDATE 订单表 
    SET 订单状态 = '已支付', 订单支付时间 = SYSDATE 
    WHERE 所属用户编号 = v_user_id 
    AND 所属场次编号 = v_session_id;
    
    COMMIT;
EXCEPTION
    WHEN OTHERS THEN
        ROLLBACK TO start_transaction;
        RAISE;
END;
/

8. 复杂查询示例

sql 复制代码
-- 查询各类型影片平均评分
SELECT 
    电影类型,
    ROUND(AVG(电影评分), 2) AS 平均评分,
    COUNT(*) AS 影片数量
FROM 影片表
GROUP BY 电影类型
HAVING AVG(电影评分) > 6.0
ORDER BY 平均评分 DESC;

-- 查询热门影片(评分高且评论多)
SELECT 
    m.影片名称,
    m.电影评分,
    COUNT(c.编号) AS 评论数量,
    SUM(o.订单价格) AS 总票房
FROM 影片表 m
LEFT JOIN 评论表 c ON m.编号 = c.所属电影编号
LEFT JOIN 订单详情表 s ON m.编号 = s.放映的电影编号
LEFT JOIN 订单表 o ON s.编号 = o.所属场次编号
GROUP BY m.影片名称, m.电影评分
HAVING COUNT(c.编号) > 1000
ORDER BY m.电影评分 DESC, 评论数量 DESC;

-- 查询用户观影偏好
SELECT 
    u.用户名,
    m.电影类型,
    COUNT(*) AS 观影次数,
    SUM(o.订单价格) AS 总消费
FROM 订单表 o
JOIN 用户表 u ON o.所属用户编号 = u.编号
JOIN 订单详情表 s ON o.所属场次编号 = s.编号
JOIN 影片表 m ON s.放映的电影编号 = m.编号
GROUP BY u.用户名, m.电影类型
ORDER BY 观影次数 DESC;
相关推荐
小陈工2 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
科技小花6 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸6 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain6 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希7 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神7 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员7 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java7 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿7 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴7 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存