高并发秒杀系统--秒杀业务分析与数据库表设计

视频地址:http://www.imooc.com/learn/587

1.分析秒杀系统的业务流程
商家&库存&用户之间的关系
2.用户对库存的业务分析
用户执行秒杀->减库存+记录购买明细
3.对购买行为的分析(表数据字段的依据)
购买的对象
购买的时间/付款有效期
付款信息/发货信息
4.如果用户的购买行为没有事物控制
减库存,没有购买记录 --> 少卖 --> 客户无法看到秒杀结果
库存没减,产生购买记录 --> 超卖 --> 商家没有足够的库存发货
5.数据落地问题MYSQL VS NOSQL
什么是NOSQL:所有的非关系型数据库的存储方案
常见的NOSQL:redis hbase Cassandra ElasticSearch
NOSQL的优势:性能 高可用 分布式
NOSQL的劣势:对于事务的支持不太友好
结论:事务机制机制依然是最可靠的数据落地方案
6.秒杀系统的业务难点
分析高并发导致的性能问题:
start transaction -- 开启事务
update 减库存 -- 减库存操作
insert 购买记录 -- 插入购买记录
commit -- 事务提交
在秒杀开启的时候由于同时产生减库存请求(高并发入库),在事务开启中由于mysql行级锁机制
导致每次减库存操作都应该在上一次事务结束之后才能操作否则会一直等待,由此产生高并发的性能问题
7.秒杀系统的主要功能
秒杀接口的暴露 -- 避免插件实现重复秒杀
执行秒杀
数据相关查询
8.秒杀系统的主要开发流程
DAO设计编码 -- 数据库表的设计、DAO接口的设计、使用Mybatis实现DAO接口
Service设计编码 -- Service的接口设计、Service的接口实现、使用Spring管理Service、通过Spring声明式事务管理事务方法
Web设计编码 -- Restful接口的设计、前端交互的编码

-- 数据库初始化脚本

-- 创建数据库
CREATE DATABASE seckill;
-- 使用数据库
USE seckill;
-- 创建表秒杀库存表
CREATE TABLE seckill(
  `seckill_id` bigint NOT NULL AUTO_INCREMENT COMMENT '商品库存id',
  `name` varchar(120) NOT NULL COMMENT '商品名称',
  `number` int NOT NULL COMMENT '商品库存',
  `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '秒杀开始时间',
  `end_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '秒杀结束时间',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '秒杀创建时间',
  PRIMARY KEY (seckill_id),
  key idx_start_time(start_time),
  key idx_end_time(end_time),
  key idx_create_time(create_time)
)ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8 COMMENT '秒杀库存表';
/*
  注意mysql5.7创建seckill表时会报 ERROR 1067 (42000): Invalid default value for 'end_time'
  解决方式1: set sql_mode = '';
  查询sql_mode:  show variables like 'sql_mode';
  解决方式2:为timestamp类型的字段添加默认值
*/
-- 初始化数据
insert into seckill(name,number,start_time,end_time)
values
  ('1000元秒杀iphone7s',100,'2017-04-14 00:00:00','2017-04-15 00:00:00'),
  ('800元秒杀ipadAir',150,'2017-04-14 00:00:00','2017-04-15 00:00:00'),
  ('500元秒杀华为P9',200,'2017-04-14 00:00:00','2017-04-15 00:00:00'),
  ('200元秒杀红米NOTE',300,'2017-04-14 00:00:00','2017-04-15 00:00:00');
-- 秒杀成功明细表
-- 用户登陆验证相关的信息,验证用户身份
CREATE TABLE success_killed(
  `seckill_id` bigint NOT NULL COMMENT '秒杀商品id',
  `user_phone` bigint NOT NULL COMMENT '用户手机号',
  `state` tinyint NOT NULL DEFAULT -1 COMMENT '状态标识:-1:无效 0:成功 1:已付款',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '秒杀成功时间',
  PRIMARY KEY (seckill_id,user_phone) /*联合主键,保证同一个用户对同一商品不会多次秒杀*/,
  key idx_create_time(create_time)
)ENGINE InnoDB DEFAULT CHARSET=utf8 COMMENT '秒杀成功明细表';
-- 连接数据库控制台
-- 导入初始化数据
-- 查询表结构: show create table [table_name]\G

-- 建表模板
CREATE TABLE XXX(
  `pid` bigint NOT NULL AUTO_INCREMENT COMMENT '逻辑主键',
  PRIMARY KEY (pid),  /*主键设置*/
  KEY idx_pid (pid)   /*创建索引*/
)ENGINE InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT '表信息';

-- 为什么要手写DDL
-- 1.方便其他同时/DBA查看数据库的改变
ALTER TABLE seckill
DROP INDEX idx_create_time,
ADD INDEX idx_s_c(start_time,create_time);
-- 2.数据库的版本控制

 

mysql在windows本地zip安装方式
1.配置环境变量
2.修改my-default.ini,添加
#安装目录
basedir=C:\Program1\mysql-5.7.16-winx64
#数据库存放目录
datadir=C:\Program1\mysql-5.7.16-winx64\data
#端口
port=3306
#字符集
character_set_server=utf8
#最大连接数
max_connections=200
3.管理员身份运行CMD
输入:mysqld --initialize-insecure
4.安装服务
输入:mysqld -install
5.启动服务
输入:net start mysql
6.进入mysql修改密码
输入:set password = password('新密码');
7.重启mysql并登陆
net stop mysql

 

posted @ 2017-04-13 21:50  AZcode  阅读(3435)  评论(0编辑  收藏  举报