一个表设计问题

2020-04-20 09:44:13 +08:00
 mawerss1

业务场景是保存物流动态信息 物流动态目前看一般情况下只会进行 append,不会修改和删除中间的行

问题: 两种建表方式那种更好一点

1. 具体的物流动态用单独的表保存。 比如:
表 A 保存订单 id 和状态
id tid  status

表 B 保存具体物流动态信息
aid content time 

2.物流信息保存在上面的表 a 中和订单状态放在一起,用字符分割,在程序中解析字符串,插入时使用 concat 链接字符串

表 A 中的数据单表大概有 500w 条,如果按第一种方式,假设每个订单平均 5 个动态,就要 2500w 行,按第二种设计方法是否会有问题?
4935 次点击
所在节点    MySQL
30 条回复
privatetan
2020-04-20 09:50:50 +08:00
哈哈哈哈哈 我昨晚上睡觉前想了一个类似问题 没想到今天就有人来问了
Vegetable
2020-04-20 09:57:30 +08:00
我来设计会选择第一个。
数据量不算问题,毕竟查询简单。
yongjing
2020-04-20 09:59:27 +08:00
第一个
mawerss1
2020-04-20 10:01:13 +08:00
@Vegetable 其实第一种设计我认为是有些浪费的,查询只会按照订单来查,不会查询单个动态详情,这样物流动态的索引其实是用不到的?
Egfly
2020-04-20 10:01:20 +08:00
选第一个。 第二个方案可以改进一下,把物流动态信息用 json 格式存起来。这样一个订单就一条数据
linxb
2020-04-20 10:09:01 +08:00
选第一个,简单便捷清晰
littleylv
2020-04-20 10:11:02 +08:00
我个人毫不犹豫选 1
xuanbg
2020-04-20 10:14:36 +08:00
第一个简单,开销也低,因为只管 insert 就行。第二种就要先读出来,然后拼接,然后 update 。不说数据库操作 select +update(delete+insert)比 insert 开销大得多,业务逻辑也复杂了很多。省那么点存储空间,脑子瓦特了……
Vegetable
2020-04-20 10:15:44 +08:00
@mawerss1 第一个对于开发者来说,需要做的事情更少。浪费点资源可能大家不太在乎
lancelock
2020-04-20 10:23:03 +08:00
用 pg,json 存
index90
2020-04-20 10:28:23 +08:00
要看是读多写少还是写多读少啊。
读多写少用第二种,写多读少用第一种。用列存储的话用第一种,如果是 B 树存储结构的用第二种,B+的可以考虑第一种。

如果第一种,aid 不能使用自增 id,需要自己生成和 tid 有关的 id,否则 B 表横向扩展会有问题。
mawerss1
2020-04-20 10:41:38 +08:00
@index90 横向扩展能详细讲讲吗,现在只做了分库没做分表,分库是按用户 id 分的
x66
2020-04-20 10:50:15 +08:00
感觉很适合使用时间序列数据库
ISSSSSSS
2020-04-20 10:52:15 +08:00
看情况,如果是专业的物流公司,必然选择第一种。如果是普通电商小公司,我会选择第二种。
首先第一种设计的很严谨,但是带来的数据行数过大。一个订单平均有 10 个左右的物流行数,不划算。而且设计的这么严谨其实没有用处。
第二种设计方式虽然看着简陋但很实用。能有效减少行数,适合小项目。至于有人说 update 复杂,其实数据处理完全可以放在应用中。
个人建议:
1 按状态分表。//因为物流信息一般是在订单未完成之前才关注,订单完成后几乎就是死数据,所以不妨在订单完成后,将此类数据迁移到另一个表。
2 增加缓存。//缓存按照 30 分钟进行刷新,避免用户着急刷新物流而导致的查询数据库过多。
3 换一个数据库 比如 mongo 或 ES 。
arthas2234
2020-04-20 11:02:50 +08:00
订单表的数据量多少和物流信息查询快慢没有必然关系
一般来说订单列表中不会返回物流信息的,只有在订单详情里面返回,这种查询效率很快的

按照第二种方法,特定的查询会很麻烦,如果用 json 来储存的话,如果物流信息的 json 结构改变的话,也很麻烦
mawerss1
2020-04-20 11:05:04 +08:00
@arthas2234 商家应用列表里要返回物流信息
tabris17
2020-04-20 11:07:47 +08:00
选用 postgresql,然后物流动态用数组类型字段保存
DoUSeeMe
2020-04-20 11:10:48 +08:00
@index90 就针对 mysql 来说,这位仁兄的想法我深表赞同
encro
2020-04-20 11:13:20 +08:00
当然选择第一种,
虽然数据量大了数倍,但是因为订单 id 比较分散,那么性能是很高的;
第二种你也防止程序源 select * 返回一堆信息;
而且你自己需要的时候需要 select 再 append 。
第一种就好办了,直接 append,每次都不需要查以前的。只在需要的时候再 append 。


从软件工程角度来说,
第一种物流和订单也更解耦了,物流依赖订单,订单不依赖物流。
比如你可以先实现订单功能,有时间再实现物流追踪。

甚至我以前做的一个海淘系统,订单和物流采用了不同的子系统,只能通过类似微服务的接口调用,这样保证重构系统的时候,接口不变就可以了。
xieshaohu
2020-04-20 11:52:53 +08:00
选第一种,页面上加载订单信息和物流信息调用两个接口。原因 :功能解耦了,后台数据库负载低,应用接口也变得简单。

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

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

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

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

© 2021 V2EX