用户购买商品表应该怎么设计?

2017-10-01 10:09:52 +08:00
 aliehuhu
需求:判断用户是否购买过该商品。
表 1 是一个用户买一个商品就加一条记录。

表 2 是一个用户购买的商品都放在一条记录里,用,号隔开,查询的时候读取出这个字段分割成数组再判断。

表 1 的话,如果有一万个用户,一百件商品,最多就会产生 100 万记录了,感觉好多。
该用哪种方法呢?或者有更好的实现方式?
7391 次点击
所在节点    MySQL
32 条回复
silencefent
2017-10-01 10:14:57 +08:00
第一种表可以根据时间将记录作废
或者归纳到分表,2015 2016 2017 订单
第二种表简直是灾难
zjsxwc
2017-10-01 10:26:54 +08:00
查询下用户订单表不就可以判断用户是否购买过商品了吗?

select * from order where user_id=123 and item_id=456 limit 1

同时给个 user_id 与 item_id 组合 index 就好了
Vogan
2017-10-01 10:27:34 +08:00
第二种是反模式,不推荐。数据如果脏了,那么爆炸。
bxb100
2017-10-01 10:38:30 +08:00
还有第二种这样的操作啊
aliehuhu
2017-10-01 10:41:38 +08:00
@bxb100 初学,见笑了
gouchaoer
2017-10-01 11:01:25 +08:00
用 json 字段,如果是 5.7 的话
rootx
2017-10-01 11:06:42 +08:00
100 万…很少…
codingadog
2017-10-01 11:47:19 +08:00
请看数据库设计一二三范式
codingadog
2017-10-01 11:47:54 +08:00
顺便 100w 数据完全不多啊
loveCoding
2017-10-01 12:15:59 +08:00
100 万....很少的 , 目前公司一个库单表 800 万没啥问题 . 主要是索引设计好
evlos
2017-10-01 12:22:37 +08:00
第二种设计太可怕了
loveyu
2017-10-01 14:16:36 +08:00
正被要求第二种设计的路过,都是累
rainex
2017-10-01 15:55:49 +08:00
看了下,楼上还没人说到点子上,我说两句。

第一种方法是初学者就会用的方式,后续数据库维护也简单。

第二种其实思路是对的,因为接下来你还要根据需要作为查询条件去取那些商品数据的,你需要快速一步到位的得到 id 逗号分隔这种数据,但因为逗号分隔的数据内容可能很大,有可能空也可能买的太多导致 varchar(3000)都不够用,就不能用定长字段,所以数据量大了查询会慢,而且后续维护起来麻烦。

所以,如果不想找太多麻烦就用第一种,如果想优化设计,可以用第二种的思路,只拿第一种做原始数据,但查询的 id 逗号分隔数据用 nosql 或文件目录结构来存放“缓存”,需要更新维护时先修改原始数据,然后更新“缓存”,也称不上楼上有人说的灾难,想运行快就要付出代价。

有个设计原则,就是别什么烂活都交给关系型数据库,这种数据库是种代价高昂的数据存储方案,相对而言速度也不是很快。

另外每一部分用什么方案,跟服务器的假设和配置方案也有关系,比如 cpu 和内存还有磁盘的方案等等,不过现在因为硬件越来越强,人工成本反而高,所以。。。现在搞技术的其实越来越幸福越来越容易了
rainex
2017-10-01 16:05:38 +08:00
补充下,要根据业务情况做好模拟测试,别拿着书上的东西生搬硬套,比如说一些数据还被别的业务所使用(查询、修改),这就可能会影响到查询、更新两者的负载比例关系(因为 mysql 查询虽快但更新很慢而且并发多了容易锁死),影响到哪种缓存方案合算,我说这些就是说没有绝对的办法,各因素要通盘考虑,但大原则都是要稳妥的设计原始数据存放方案,尽量确保业务需求的修改变动只需要修改缓存方案即可解决。
wemore
2017-10-01 16:45:06 +08:00
json 字符串存商品 id list,但是商品没了就不能删除只能标记下架。
zjqzxc
2017-10-01 17:25:15 +08:00
表 1 是 sql 的思路
表 2 是 nosql 的思路( json 存储,不建议逗号)

表 1 可以查某个用户购买过什么,也可以查某个商品被哪些用户买过
表 2 的思路可以作为在 redis 中的存储格式

另外,楼上说商品没了就不能删除只能下架。。我想说,sku 一旦进入数据库,还能有删除这一说?
学校的数据库课程中,有很多说法真的不适合互联网环境下的应用,包括但不限于各种断言触发器以及很多完整性约束。。。
konakona
2017-10-01 18:15:47 +08:00
多用第一种方式。
第二种方式是灾难 - -
gamexg
2017-10-01 19:45:42 +08:00
尽量第一种,另外第二种可以放 kv 缓存数据库,不需要放到 mysql。
leeg810312
2017-10-01 19:45:52 +08:00
第二种叫灾难?哪有这么严重!订单可以用 NoSQL 或 PGSQL/MySQL 的 json 来存,比直接逗号存储要好,查询一样很方便。
leekafai
2017-10-01 20:07:08 +08:00
op 现在做的就到点子上了。
和上面说的一样,数据结构不需要二选一,你需要方便统计的,第一种,你需要快取的,第二种。

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

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

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

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

© 2021 V2EX