关于数据库范式和性能优化的一个疑问

2019-12-30 14:16:37 +08:00
 CrisTao

要记录一个用户的会员开通记录:按照范式的话,应该是将用户表和会员记录表分离出来,但是这样的话,每次查会员是否有效是不是都得去关联一次会员记录表了?如果直接在用户表页加一个截止时间的字段,那这样在查询的时候是不是会少一次关联,但这样岂不是违反了范式?

用户表:

id (用户 id )

expired_at (当前会员截止时间,是否需要这个字段?)

会员记录表:

id (记录 id )

uid (用户 id )

paid_at (支付时间)

expired_at (截止时间)

status (订单状态)

对于数据库设计有点迷糊,求各位指点迷津

5116 次点击
所在节点    MySQL
11 条回复
feigle
2019-12-30 14:32:01 +08:00
下次来了个 vvip 的需求,你是不是得在用户表中再加一个字段 vvip_expired_at (当前 vvip 截止时间)?
lhx2008
2019-12-30 14:37:01 +08:00
从范式来说,用户表不需要任何 vip 有关的内容,vip 表也不需要任何订单相关的内容,想要快的话做个 vip 用户缓存就行了。
不过你在用户表插个过期时间也不是不行,只是你 vip 到时候还有别的信息要存的
encro
2019-12-30 14:43:57 +08:00
应该分成:

用户表(可以加截止时间,当前 vip 类型),
会员购买记录表(每次购买是一条记录),
这样就没有冲突了。
还可以避免没有过期重复购买的问题。

设计数据库的一个重要思考原则就是参考财务账单,任何操作都是一个单据(数据库记录),这个单据负责追溯发生了什么事,其他是否该冗余完全根据数据库性能来,去 TM 范式。
CrisTao
2019-12-30 14:54:12 +08:00
@lhx2008 总的来说,就是存储还是按照范式走,要性能的话就走缓存
2379920898
2019-12-30 15:11:53 +08:00
看完 高性能 四五六章 =没苦恼
wangyzj
2019-12-30 15:41:35 +08:00
理论上订单表里面不应该有结束时间把
应该是一个 sku id
会员表里面是过期时间,这样性能会好一些
yrj
2019-12-30 16:32:01 +08:00
其实吧,多一次关联,也慢不到哪去
kyuuseiryuu
2019-12-30 16:37:35 +08:00
你给数据库省事儿,就是给自己未来找事儿。
mahogany
2019-12-30 17:45:36 +08:00
为了性能可以部分违背范式,不过你要保证用户表上的会员截止日期恩能被正确地更新,缓存要同步。
yb3712590
2019-12-30 23:07:18 +08:00
当用户数和开通记录都上亿,且用户表用于生产需要频繁查询时,你可以单独新建用户快查表,加入需要高频检索的属性,每日凌晨计算并更新这个表。
否则没理由违反范式。
daozhihun
2019-12-31 09:32:36 +08:00
范式不是分解到越高越好,要根据实际情况取舍。
比如订单明细表可以算出总金额,但是通常情况还是会在订单表里搞一个 total 字段,即使这个字段是冗余的而且可能导致不一致的情况。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/633546

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX