【Java+JSP+MySql】12306购票系统(二)数据库

  1. 用户表

用户表的创建:

CREATE TABLE user_info(
id CHAR(18) NOT NULL,
username VARCHAR(10) NOT NULL,
telephone CHAR(11) NOT NULL,
upassword VARCHAR(20) NOT NULL,
PRIMARY KEY(id),
CONSTRAINT CU1 CHECK(telephone LIKE '1%')
)ENGINE=INNODB DEFAULT CHARSET=utf8mb4;

插入数据:

INSERT INTO `user_info` VALUES
('110108200001011111','赵倩','18310710700','password'),
('110108200002022222','张三','18310710711','123456'),
('110108200003033333','李四','18310710722','654321');
  1. 车次表

车次表的创建:

CREATE TABLE train(
trainnum CHAR(5) NOT NULL,
origin VARCHAR(10) NOT NULL,
destination VARCHAR(10) NOT NULL,
stime CHAR(5),
prize00 INT,
prize01 INT,
prize02 INT,
PRIMARY KEY(trainnum),
CONSTRAINT CU2 CHECK(stime LIKE '__:__')
);

插入数据:

INSERT INTO `train` VALUES
('G1101','北京','天津','09:00',89,59,39),
('G1323','北京','天津','13:30',89,59,39),
('G1434','北京','天津','17:05',89,59,39),
('G2141','天津','北京','09:40',89,59,39),
('G2363','天津','北京','18:00',89,59,39),
('C3444','北京','上海','10:50',319,289,259),
('C3555','北京','上海','16:30',319,289,259),
('C3666','北京','上海','19:50',319,289,259),
('C4566','上海','北京','11:05',319,289,259),
('C4788','上海','北京','18:05',319,289,259),
('C5077','上海','天津','15:25',319,289,259),
('C6098','天津','上海','16:30',319,289,259);
  1. 余票表

余票表的创建:

CREATE TABLE `left_tickets`(
`sdate` DATE,
`trainnum` CHAR(5),
`leftnum00` INT,
`leftnum01` INT,
`leftnum02` INT,
PRIMARY KEY(`sdate`,`trainnum`),
FOREIGN KEY(`trainnum`) REFERENCES train(`trainnum`),
CONSTRAINT CU3 CHECK(`leftnum00`>=0 AND `leftnum01`>=0 AND `leftnum02`>=0)
);

插入数据:

INSERT INTO `left_tickets` VALUES
('2021-12-31','G1101',12,20,36),
('2021-12-31','G1323',12,20,36),
('2021-12-31','G1434',12,20,36),
('2021-12-31','G2141',12,20,36),
('2021-12-31','G2363',12,20,36),
('2021-12-31','C3444',12,20,34),
('2021-12-31','C3555',12,20,36),
('2021-12-31','C3666',12,20,36),
('2021-12-31','C4566',12,20,36),
('2021-12-31','C4788',12,20,36),
('2021-12-31','C5077',12,20,36),
('2021-12-31','C6098',12,20,36),
('2022-01-01','G1101',12,19,36),
('2022-01-01','G1323',12,20,36),
('2022-01-01','G1434',12,20,36),
('2022-01-01','G2141',12,20,36),
('2022-01-01','G2363',12,20,36),
('2022-01-01','C3444',12,20,36),
('2022-01-01','C3555',12,20,36),
('2022-01-01','C3666',12,20,36),
('2022-01-01','C4566',12,20,36),
('2022-01-01','C4788',12,20,36),
('2022-01-01','C5077',12,20,36),
('2022-01-01','C6098',12,20,36),
('2022-01-02','G1101',12,20,36),
('2022-01-02','G1323',12,20,36),
('2022-01-02','G1434',12,20,36),
('2022-01-02','G2141',11,20,36),
('2022-01-02','G2363',12,20,36),
('2022-01-02','C3444',12,20,36),
('2022-01-02','C3555',12,20,36),
('2022-01-02','C3666',12,20,36),
('2022-01-02','C4566',12,20,36),
('2022-01-02','C4788',12,20,36),
('2022-01-02','C5077',12,20,36),
('2022-01-02','C6098',12,20,36),
('2022-01-03','G1101',12,20,36),
('2022-01-03','G1323',12,20,36),
('2022-01-03','G1434',12,20,36),
('2022-01-03','G2141',12,20,36),
('2022-01-03','G2363',12,20,36),
('2022-01-03','C3444',12,20,36),
('2022-01-03','C3555',12,20,36),
('2022-01-03','C3666',12,20,36),
('2022-01-03','C4566',12,20,36),
('2022-01-03','C4788',12,20,34),
('2022-01-03','C5077',12,20,36),
('2022-01-03','C6098',12,20,36);
  1. 已售车票表

已售车票表的创建

CREATE TABLE `sold_tickets`(
`sdate` DATE,
`trainnum` CHAR(5),
`seat` VARCHAR(20),
`userid` CHAR(18) NOT NULL,
PRIMARY KEY(`sdate`,`trainnum`,`seat`),
FOREIGN KEY(`sdate`,`trainnum`) REFERENCES `left_tickets`(`sdate`,`trainnum`),
FOREIGN KEY(`userid`) REFERENCES `user_info`(`id`)
);

插入数据:

INSERT INTO `sold_tickets` VALUES
('2021-12-31','C3444','02-1A','110108200001011111'),
('2022-01-03','C4788','02-4D','110108200001011111'),
('2022-01-01','G1101','01-5C','110108200002022222'),
('2022-01-02','G2141','00-2B','110108200002022222'),
('2021-12-31','C3444','02-8C','110108200003033333'),
('2022-01-03','C4788','02-9A','110108200003033333');

视图

前面3个视图是几种常见的分类,后面2个视图是系统中所需要的。

  1. 出发城市
#行列子视图
CREATE VIEW 出发城市 AS
SELECT DISTINCT origin
FROM train;
  1. 学生车票
#带表达式视图
CREATE VIEW 学生车票(出发城市,到达城市,二等座价格) AS
SELECT origin,destination,`prize02`*0.5
FROM train;
  1. 乘车量
#分组视图
CREATE VIEW 乘车量(日期,车次号,乘客数) AS
SELECT sdate,trainnum,COUNT(*)
FROM sold_tickets
GROUP BY sdate,trainnum;
  1. 车票余量及用户完整信息
#完整系统需要的视图
#车票余量完整信息视图
CREATE VIEW train_info(start_date,origin,destination,trainnum,stime,num00,num01,num02) AS
SELECT left_tickets.`sdate`,train.`origin`,train.`destination`,left_tickets.`trainnum`,
train.`stime`,left_tickets.`leftnum00`,left_tickets.`leftnum01`,left_tickets.`leftnum02`
FROM train,left_tickets
WHERE train.`trainnum`=left_tickets.`trainnum`;
  1. 已购车票及用户完整信息
#用户购买车票完整信息视图
CREATE VIEW user_tickets_info(userid,origin,destination,sdate,stime,trainnum,seat) AS
SELECT sold_tickets.`userid`,train.`origin`,train.`destination`,sold_tickets.`sdate`,
train.`stime`,sold_tickets.`trainnum`,sold_tickets.`seat`
FROM train,sold_tickets
WHERE train.`trainnum`=sold_tickets.`trainnum`;

所有视图的截图在这个专栏的第一个文章里包含了,可以看到。这里也放出链接:
12306购票系统(一)项目介绍

存储过程

  1. 登录
DELIMITER $
CREATE PROCEDURE login(IN telenum CHAR(11),IN pwd VARCHAR(20))
BEGIN
	DECLARE result INT DEFAULT 0;
	SELECT COUNT(*) INTO result
	FROM `user_info`
	WHERE `user_info`.`telephone`=telenum
	AND `user_info`.`upassword`=pwd;
	SELECT result;
END $
  1. 注册
DELIMITER $
CREATE PROCEDURE sign_in(IN id CHAR(18),IN nm VARCHAR(10),IN telenum CHAR(11),IN pwd VARCHAR(20))
BEGIN
	INSERT INTO `user_info` VALUES(id,nm,telenum,pwd);
	SELECT ('注册成功');
END $
  1. 取消订票
DELIMITER $
CREATE PROCEDURE cancel_ticket(IN stdate DATE, IN trainnum CHAR(5),IN userid CHAR(18))
BEGIN
	DELETE FROM `sold_tickets`
	WHERE `sold_tickets`.`sdate`=stdate AND
	`sold_tickets`.`trainnum`=trainnum AND
	`sold_tickets`.`userid`=userid;
END $
  1. 更新购票信息
DELIMITER $
CREATE PROCEDURE buy_update(IN stdate DATE,IN trainnum CHAR(5),IN sw_newnum INT,IN yd_newnum INT,IN ed_newnum INT)
BEGIN
	UPDATE `left_tickets` SET `left_tickets`.`leftnum00`=sw_newnum,
	`left_tickets`.`leftnum01`=yd_newnum,`left_tickets`.`leftnum02`=ed_newnum
	WHERE `left_tickets`.`sdate`=stdate AND `left_tickets`.`trainnum`=trainnum;
END $

以上存储过程中,只有1. 登录2.注册在购票系统中有应用。但是这四个触发器把增删改查都应用到了。

触发器

  1. 购票
    根据所购车票等级,余票量减一
DELIMITER $
CREATE TRIGGER buy_tickets BEFORE INSERT ON sold_tickets FOR EACH ROW
BEGIN
	IF new.`seat` LIKE '02%' THEN
	UPDATE `left_tickets` SET `leftnum02` =`leftnum02`-1
	WHERE `sdate`=new.`sdate` AND `trainnum`=new.`trainnum`;
	ELSEIF new.`seat` LIKE '01%' THEN
	UPDATE `left_tickets` SET `leftnum01` =`leftnum01`-1
	WHERE `sdate`=new.`sdate` AND `trainnum`=new.`trainnum`;
	ELSE
	UPDATE `left_tickets` SET `leftnum00` =`leftnum00`-1
	WHERE `sdate`=new.`sdate` AND `trainnum`=new.`trainnum`;
	END IF;
END $
  1. 取消订票
    根据取消的车票等级,相应余票加一
DELIMITER $
CREATE TRIGGER cancel_t AFTER DELETE ON sold_tickets FOR EACH ROW
BEGIN
	IF old.`seat` LIKE '02%' THEN
	UPDATE `left_tickets` SET `leftnum02` =`leftnum02`+1
	WHERE `sdate`=old.`sdate` AND `trainnum`=old.`trainnum`;
	ELSEIF old.`seat` LIKE '01%' THEN
	UPDATE `left_tickets` SET `leftnum01` =`leftnum01`+1
	WHERE `sdate`=old.`sdate` AND `trainnum`=old.`trainnum`;
	ELSE
	UPDATE `left_tickets` SET `leftnum00` =`leftnum00`+1
	WHERE `sdate`=old.`sdate` AND `trainnum`=old.`trainnum`;
	END IF;
END $
  1. 修改座位等级
DELIMITER $
CREATE TRIGGER update_seat AFTER UPDATE ON sold_tickets FOR EACH ROW
BEGIN
	IF new.`seat` LIKE '02%' THEN
	UPDATE `left_tickets` SET `leftnum02` =`leftnum02`-1
	WHERE `sdate`=new.`sdate` AND `trainnum`=new.`trainnum`;
	ELSEIF new.`seat` LIKE '01%' THEN
	UPDATE `left_tickets` SET `leftnum01` =`leftnum01`-1
	WHERE `sdate`=new.`sdate` AND `trainnum`=new.`trainnum`;
	ELSE
	UPDATE `left_tickets` SET `leftnum00` =`leftnum00`-1
	WHERE `sdate`=new.`sdate` AND `trainnum`=new.`trainnum`;
	END IF;
	
	IF old.`seat` LIKE '02%' THEN
	UPDATE `left_tickets` SET `leftnum02` =`leftnum02`+1
	WHERE `sdate`=old.`sdate` AND `trainnum`=old.`trainnum`;
	ELSEIF old.`seat` LIKE '01%' THEN
	UPDATE `left_tickets` SET `leftnum01` =`leftnum01`+1
	WHERE `sdate`=old.`sdate` AND `trainnum`=old.`trainnum`;
	ELSE
	UPDATE `left_tickets` SET `leftnum00` =`leftnum00`+1
	WHERE `sdate`=old.`sdate` AND `trainnum`=old.`trainnum`;
	END IF;
END $

触发器前两个1. 购票2.取消订票在系统中有应用,但三个合起来将增删改都实现了。

系列更新结束后会把源代码和相关的文档打包上传成资源。
如果你觉得这篇文章对你有用的话,麻烦点赞,收藏,关注一下。
感谢您的阅读,您的支持是对我最大的鼓励~
  • 6
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
12306的数据库设计 原⽂地址:http://blog.csdn.net/hnkontecna/article/details/61672983 标签 标签 PostgreSQL , 12306 , 春节 , ⼀票难求 , 门禁⼴告 , 数组 , 范围类型 , 抢购 , 排他约束 , ⼤盘分析 , ⼴告查询 , ⽕车票 背景 背景 马上春节了,⼜到了⽕车票的销售旺季,⼀票难求的问题依旧存在吗? 还记得10年前春节前买⽕车票得在放票前1天搬个⼩板凳去排队,对于热门路线,排⼀个晚上都有可能买不到票。 随着互联⽹的发展,⼏年前建设了12306⽹上购票系统,可以从电脑上买票,但是不要以为在电脑上就能买到票。 我记得12306刚推出时,经常发⽣12306⽹站打不开,⽆法付款的问题。 为什么呢? 原因很简单,春节期间⽹上购票的⼈可能达到⼏亿的级别,⽽且放票⽇期是同⼀天同⼀个时间点,也就是说同⼀时刻12306要接受⼏亿⽤ 户的访问。 处理能⼒和实际的访问需求更不上,带来的结果就是⽹站打不开,系统不稳定的现象。 后来12306想了分线路分时段开启的办法,想办法把不同线路的⽤户错开时间来访问12306的⽹站,但是这个⽅法起初的效果不明显,并 不是所有⽤户都知道的(就好像你临时通知今天不上班,但还是有⽤户会来单位的),所以⼤多数⽤户还是集中在⼀个点去访问12306的 ⽹站。 随着硬件的发展,技术的演进,12306的系统越来越趋于成熟,稳定性和响应速度也越来越好。 据说现在很多商家还开通了云抢票业务,本质上是让你不要冲击12306系统了,把需求提前收集,在放票时,这些系统会进⾏排队与合并 购买,这种⼿段可以减少12306的访问并发。 抢⽕车票是很有意思的⼀个课题,对IT⼈的智商以及IT系统的健壮性,尤其是数据库的功能和性能都是⼀种挑战。 接下来我们⼀起来缕⼀缕有哪些难点,⼜有怎样的解决⼿段。 ⼀、铁路售票系统 ⼀、铁路售票系统 - 西天取经之路开始啦 西天取经之路开始啦 铁路售票系统最基本的功能包括 查询余票、余票统计、购票、车次变化、退票、改签、中转乘车规划 等。 每个需求都有各⾃的特点,例如 1. 查询余票,⽤户在购票前通常会查⼀下到达⽬的地有哪些余票,它属于⼀个⾼并发的操作,同时需要统计余票张数,需要很强的CPU来 ⽀撑实时的查询。 2. 购票购票和查询不⼀样,购票是会改变库存的,所以对数据库来说是更新的操作。 ⽽且购票很可能发⽣冲突,例如很多⼈要买同⼀趟车的票,那就出现冲突了,到底卖给谁呢? 需要考虑锁冲突,尽量的让不同的⼈购买时可并⾏,或者可以合并多⼈的购票请求,来减少数据库的更新操作。 3. 中转乘车,当⽤户需要购买的起点和到达站⽆票时,需要计算中转的搭乘⽅案。 ⽐如从北京到上海,如果没有直达车,是不是该转车呢?转哪趟,在哪⾥转就成了问题,简单⼀点就是买票的⼈⾃⼰想。 ⾼级⼀点的话,可以让12306给你推荐路线,这个涉及的是数据库的路径规划功能。 我们来逐⼀分析⼀下这些需求的特点。 1 查询余票 查询余票 1. 普通的余票查询需求 你如果要买从北京到上海的⽕车票,通常会查⼀下哪些车次还有余票。 查询的过滤条件可能很多,⽐如 1.1. 上车站、下车站、中转站 1.2. 车次类型(⾼铁、动车、直达、快速、普客、...) 1.3. 出发⽇期、时段 1.4. 到达⽇期、时段 1.5. 席别(硬座、硬卧、...站票) 1.6. 过滤掉没有余票的车次 展⽰给⽤时还要考虑到怎么排序(是按始发时间排呢,还是按票价,或者按余票数量排?),怎么分页。 眼见不⼀定为实 查询余票通常不是实时的、或者说不⼀定是准确的,有可能是后台异步统计的结果。 即使是实时统计的结果,在⾼并发的抢票期间,你看到的信息对你来说也许很快就会失效。 ⽐如你看到某趟车还有100张票,很可能等你付款的时候,已经卖光了。 所以在⾼峰期,余票信息的参考价值并不⼤,不要被迷惑了。 2. 查询余票的另⼀个更⾼级的需求是路径规划, ⾃动适配(根据⽤户输⼊的中转站点s) 这个功能以前可能没有,但是总有⼀天会暴露出来,特别是车票很紧张的情况下。 就⽐如从北京到上海,直达的没有了,系统可以帮你看看转⼀趟车的,转2趟车的,转N趟车的。(当然,转的越多越复杂)。 从中转这个⾓度来讲,实际上已经扯上路径规划的技术了。 怎么中转是时间最短的、价格最低的、中转次数最少的等等。(⾥⾯还涉及转车的输⼊要求(⽐如⽤户要求在⼀线城市转车,或者必须要转 ⾼铁))。 关于路径规划,可以参考⼀下PostgreSQL pgrouting,已⽀持多种路径规划算法,⽀持算法的⾃定义扩展。 简直是居家旅⾏,杀⼈灭⼝的必备良药。 师⽗⼩⼼,有妖怪。。。 师⽗⼩⼼,有妖怪。。。 1. ⼤多数⽤户是有选择综合症的,通常来说,⽤户可能会查

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值