电影票务系统的数据库设计和核心逻辑

以下是电影票务系统的数据库设计和核心逻辑建议:

一、数据库表设计(MySQL示例)

  1. 电影表(movies)
CREATE TABLE movies (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(255) NOT NULL,       -- 电影名称
    duration INT,                      -- 片长(分钟)
    genre VARCHAR(50),                 -- 影片类型
    release_date DATE                  -- 上映日期
);
  1. 影院表(cinemas)
CREATE TABLE cinemas (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,        -- 影院名称
    location VARCHAR(255)              -- 地理位置
);
  1. 影厅表(halls)
CREATE TABLE halls (
    id INT PRIMARY KEY AUTO_INCREMENT,
    cinema_id INT NOT NULL,            -- 所属影院
    name VARCHAR(50),                  -- 影厅名称
    seat_layout VARCHAR(20),           -- 座位布局(如:10x20)
    FOREIGN KEY (cinema_id) REFERENCES cinemas(id)
);
  1. 场次表(screenings)
CREATE TABLE screenings (
    id INT PRIMARY KEY AUTO_INCREMENT,
    movie_id INT NOT NULL,             -- 电影ID
    hall_id INT NOT NULL,              -- 影厅ID
    start_time DATETIME NOT NULL,      -- 放映时间
    price DECIMAL(8,2) NOT NULL,       -- 票价
    FOREIGN KEY (movie_id) REFERENCES movies(id),
    FOREIGN KEY (hall_id) REFERENCES halls(id)
);
  1. 座位表(seats)
CREATE TABLE seats (
    id INT PRIMARY KEY AUTO_INCREMENT,
    hall_id INT NOT NULL,              -- 所属影厅
    row_num INT NOT NULL,              -- 行号
    col_num INT NOT NULL,              -- 列号
    seat_type ENUM('普通','VIP')       -- 座位类型
    FOREIGN KEY (hall_id) REFERENCES halls(id)
);
  1. 座位状态表(seat_status)
CREATE TABLE seat_status (
    screening_id INT NOT NULL,         -- 场次ID
    seat_id INT NOT NULL,              -- 座位ID
    status ENUM('可选','已售','锁定'), -- 状态
    lock_expire TIMESTAMP,             -- 锁定过期时间
    PRIMARY KEY (screening_id, seat_id),
    FOREIGN KEY (screening_id) REFERENCES screenings(id),
    FOREIGN KEY (seat_id) REFERENCES seats(id)
);
  1. 订单表(orders)
CREATE TABLE orders (
    id VARCHAR(32) PRIMARY KEY,        -- 订单号(建议用UUID)
    user_id INT,                       -- 用户ID(如果有会员系统)
    screening_id INT NOT NULL,         -- 场次ID
    total_amount DECIMAL(10,2),        -- 总金额
    status ENUM('待支付','已支付','已取消'),
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (screening_id) REFERENCES screenings(id)
);

二、核心业务逻辑

  1. 余票查询逻辑
// 查询某场次可用座位数
public int getAvailableSeatsCount(int screeningId) {
    String sql = "SELECT COUNT(*) FROM seat_status " +
                 "WHERE screening_id = ? AND status = '可选'";
    // 执行查询并返回结果
}

// 获取详细座位状态
public List<SeatStatus> getSeatStatus(int screeningId) {
    String sql = "SELECT seat_id, status FROM seat_status " +
                 "WHERE screening_id = ?";
    // 返回座位状态列表
}
  1. 选座锁定逻辑(伪代码)
@Transactional
public boolean lockSeats(int screeningId, List<Integer> seatIds, int userId) {
    // 1. 检查座位是否可用
    String checkSql = "SELECT COUNT(*) FROM seat_status " +
                     "WHERE screening_id = ? AND seat_id IN (?) " +
                     "AND status != '可选'";
    
    // 2. 设置临时锁定(15分钟有效期)
    String updateSql = "UPDATE seat_status " +
                      "SET status = '锁定', lock_expire = NOW() + INTERVAL 15 MINUTE " +
                      "WHERE screening_id = ? AND seat_id IN (?)";
    
    // 3. 记录锁定日志
    // ...
}
  1. 支付成功处理
@Transactional
public void confirmPayment(String orderId) {
    // 1. 更新订单状态为已支付
    updateOrderStatus(orderId, "已支付");
    
    // 2. 永久标记座位为已售
    String sql = "UPDATE seat_status SET status = '已售' " +
                "WHERE screening_id = ? AND seat_id IN " +
                "(SELECT seat_id FROM order_seats WHERE order_id = ?)";
}

三、关键设计要点

  1. 并发控制
  • 使用数据库事务 + 行级锁(SELECT FOR UPDATE)
  • 考虑使用Redis分布式锁控制高并发请求
  • 采用乐观锁机制处理库存变更
  1. 性能优化
  • 对高频查询(如余票查询)使用Redis缓存
  • 将座位状态表按场次分表(sharding)
  • 使用消息队列异步处理订单状态变更
  1. 容错机制
  • 定时任务释放过期锁定座位
  • 订单支付超时自动回滚机制
  • 数据库读写分离架构设计
  1. 数据一致性
  • 通过事务保证座位状态与订单状态一致
  • 使用补偿事务处理异常场景
  • 定期对账校验库存与实际销售数据

建议根据实际业务规模调整设计方案,初期可先实现核心功能,后续逐步扩展会员系统、优惠券系统等模块。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值