注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Oracle、MySQL资料及经验

.

 
 
 

日志

 
 

会员优惠券表数据库设计  

2016-10-24 16:26:27|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

 

这里的优惠券,有的地方叫代金券、红包,都是相似的功能,下面统称为优惠券

为方便理解,以下只写了最简单的表结构和操作。

 

 

一、表结构设计

1. 会员表(可直接使用公司已有的会员表)

create table member(mem_id number, name varchar2(50), mobile number);  --列分别是会员ID、姓名、手机号

mem_id列做主键,mobile列建索引。

 

2. 优惠券表

create table coupon(coupon_id number, money number, begin_date date, end_date date);  --列分别是优惠券ID、金额、优惠券的开始日期、优惠券的结束日期

coupon_id列做主键,依据end_date列做分区表。

 

3. 会员与优惠券关系表

create table member_coupon(mem_id number, coupon_id number, end_date date, status number default 0);  --列分别是会员ID、优惠券ID、优惠券的结束日期、是否已用(0未用)

mem_id列建索引,coupon_id列建索引,end_date值为对应优惠券的结束时间,该列冗余的目的是利用该列在member_coupon表上做分区,方便做历史数据清理。

 

4. 过期的优惠券表,即coupon的历史表

create table coupon_his(coupon_id number, money number, begin_date date, end_date date);

coupon_id列做主键

 

5. 会员与过期的优惠券关系表,即member_coupon的历史表

create table member_coupon_his(mem_id number, coupon_id number, end_date date, status number);

mem_id列建索引,coupon_id列建索引。

 

 

二、定期把过期的优惠券移到历史表

建立定时任务,通过分区表的分区转移功能,把couponmember_coupon中的过期数据,自动定期转移到历史表coupon_hismember_coupon_his,以保证couponmember_coupon表不会过大,从而确保查询相关的sql执行效率。

 

 

三、涉及到的主要sql操作

1. 新增会员

insert into member (mem_id, name, mobile) values (1001, '', 13520660360);

 

2. 新增优惠券

insert into coupon (coupon_id, money, begin_date, end_date) values (20001, 10, trunc(sysdate), to_date('2016-10-31', 'yyyy-mm-dd'));

insert into coupon (coupon_id, money, begin_date, end_date) values (20002, 50, trunc(sysdate-30), trunc(sysdate-1));  --测试一张已过期的优惠券

 

3. 给某会员增加优惠券

insert into member_coupon (mem_id, coupon_id, end_date) values (1001, 20001, to_date('2016-10-31', 'yyyy-mm-dd')); --或为:

insert into member_coupon (mem_id, coupon_id, end_date) values (1001, 20001, (select end_date from coupon where coupon_id=20001));

insert into member_coupon (mem_id, coupon_id, end_date) values (1001, 20002, trunc(sysdate-1));  --测试已过期的优惠券

 

4. 查询某会员有哪些未使用且没过期的优惠券

select t3.*

  from member t1, member_coupon t2, coupon t3

 where t1.mem_id = t2.mem_id

   and t2.coupon_id = t3.coupon_id

   and t1.mem_id = 1001  --需要传入用户ID,手机号也可以

   and t2.status = 0

   and t3.end_date >= trunc(sysdate);

 

5. 查询某会员有哪些未使用但已过期的优惠券

因为可能有已过期的优惠券尚未转移到历史表,所以需要用到union all把两部分数据合并,如果分区表是按天分区的,同时凌晨0点做分区转移,则已过期的优惠券全部在历史表中。

select t3.*

  from member t1, member_coupon t2, coupon t3

 where t1.mem_id = t2.mem_id

   and t2.coupon_id = t3.coupon_id

   and t1.mem_id = 1001

   and t2.status = 0

   and t3.end_date < trunc(sysdate)

union all

select t3.*

  from member t1, member_coupon_his t2, coupon_his t3

 where t1.mem_id = t2.mem_id

   and t2.coupon_id = t3.coupon_id

   and t1.mem_id = 1001

   and t2.status = 0;

 

6. 查询某会员所有的优惠券

用到union all把两部分数据合并

select t3.*

  from member t1, member_coupon t2, coupon t3

 where t1.mem_id = t2.mem_id

   and t2.coupon_id = t3.coupon_id

   and t1.mem_id = 1001

union all

select t3.*

  from member t1, member_coupon_his t2, coupon_his t3

 where t1.mem_id = t2.mem_id

   and t2.coupon_id = t3.coupon_id

   and t1.mem_id = 1001;

 

7. 某会员使用了一张优惠券后,更新该会员的这张代金券为已使用

update member_coupon set status = 1 where mem_id = 1001 and coupon_id = 20001;

 

 

 

另一种设计思路

对于会员与优惠券关系表,刚开始我想的是既然每个会员有多张优惠券,于是可以会员ID后跟着该会员所有的优惠券ID,如下表结构:

会员ID

优惠券1

优惠券2

优惠券3

优惠券4

优惠券5

优惠券6

这种设计是某会员有多少优惠券就有多少列(前面的方式是某会员有多少优惠券就有多少行),这种设计可确保每个会员在member_coupon表中只有一行数据,也就能控制member_coupon表不会很大。

但发现这种设计相关操作的sql很难写,且效率低下,例如:

①给某会员增加一张优惠券的sql,需要先在该行中找到哪一列为空,才能对找到的那一列做update

②给某会员删除过期优惠券的sql,也是先找到过期的列名,才能update该列为空。

③查询会员有哪些没过期的优惠券,需要涉及到行转列,sql执行效率比较低;

总之,这种设计会导致常用操作的sql很复杂,甚至需要借助存储过程才能实现,这其实是以时间换空间(前面的方式是以空间换时间),所以这种设计思路予以放弃。

  评论这张
 
阅读(328)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017