业务场景是保存物流动态信息 物流动态目前看一般情况下只会进行 append,不会修改和删除中间的行
问题: 两种建表方式那种更好一点
1. 具体的物流动态用单独的表保存。 比如:
表 A 保存订单 id 和状态
id tid status
表 B 保存具体物流动态信息
aid content time
2.物流信息保存在上面的表 a 中和订单状态放在一起,用字符分割,在程序中解析字符串,插入时使用 concat 链接字符串
表 A 中的数据单表大概有 500w 条,如果按第一种方式,假设每个订单平均 5 个动态,就要 2500w 行,按第二种设计方法是否会有问题?
1
privatetan 2020-04-20 09:50:50 +08:00 via iPhone
哈哈哈哈哈 我昨晚上睡觉前想了一个类似问题 没想到今天就有人来问了
|
2
Vegetable 2020-04-20 09:57:30 +08:00
我来设计会选择第一个。
数据量不算问题,毕竟查询简单。 |
3
yongjing 2020-04-20 09:59:27 +08:00 via Android
第一个
|
4
mawerss1 OP @Vegetable 其实第一种设计我认为是有些浪费的,查询只会按照订单来查,不会查询单个动态详情,这样物流动态的索引其实是用不到的?
|
5
Egfly 2020-04-20 10:01:20 +08:00
选第一个。 第二个方案可以改进一下,把物流动态信息用 json 格式存起来。这样一个订单就一条数据
|
6
linxb 2020-04-20 10:09:01 +08:00
选第一个,简单便捷清晰
|
7
littleylv 2020-04-20 10:11:02 +08:00
我个人毫不犹豫选 1
|
8
xuanbg 2020-04-20 10:14:36 +08:00 1
第一个简单,开销也低,因为只管 insert 就行。第二种就要先读出来,然后拼接,然后 update 。不说数据库操作 select +update(delete+insert)比 insert 开销大得多,业务逻辑也复杂了很多。省那么点存储空间,脑子瓦特了……
|
10
lancelock 2020-04-20 10:23:03 +08:00
用 pg,json 存
|
11
index90 2020-04-20 10:28:23 +08:00
要看是读多写少还是写多读少啊。
读多写少用第二种,写多读少用第一种。用列存储的话用第一种,如果是 B 树存储结构的用第二种,B+的可以考虑第一种。 如果第一种,aid 不能使用自增 id,需要自己生成和 tid 有关的 id,否则 B 表横向扩展会有问题。 |
13
x66 2020-04-20 10:50:15 +08:00
感觉很适合使用时间序列数据库
|
14
ISSSSSSS 2020-04-20 10:52:15 +08:00
看情况,如果是专业的物流公司,必然选择第一种。如果是普通电商小公司,我会选择第二种。
首先第一种设计的很严谨,但是带来的数据行数过大。一个订单平均有 10 个左右的物流行数,不划算。而且设计的这么严谨其实没有用处。 第二种设计方式虽然看着简陋但很实用。能有效减少行数,适合小项目。至于有人说 update 复杂,其实数据处理完全可以放在应用中。 个人建议: 1 按状态分表。//因为物流信息一般是在订单未完成之前才关注,订单完成后几乎就是死数据,所以不妨在订单完成后,将此类数据迁移到另一个表。 2 增加缓存。//缓存按照 30 分钟进行刷新,避免用户着急刷新物流而导致的查询数据库过多。 3 换一个数据库 比如 mongo 或 ES 。 |
15
arthas2234 2020-04-20 11:02:50 +08:00
订单表的数据量多少和物流信息查询快慢没有必然关系
一般来说订单列表中不会返回物流信息的,只有在订单详情里面返回,这种查询效率很快的 按照第二种方法,特定的查询会很麻烦,如果用 json 来储存的话,如果物流信息的 json 结构改变的话,也很麻烦 |
16
mawerss1 OP @arthas2234 商家应用列表里要返回物流信息
|
17
tabris17 2020-04-20 11:07:47 +08:00
选用 postgresql,然后物流动态用数组类型字段保存
|
19
encro 2020-04-20 11:13:20 +08:00
当然选择第一种,
虽然数据量大了数倍,但是因为订单 id 比较分散,那么性能是很高的; 第二种你也防止程序源 select * 返回一堆信息; 而且你自己需要的时候需要 select 再 append 。 第一种就好办了,直接 append,每次都不需要查以前的。只在需要的时候再 append 。 从软件工程角度来说, 第一种物流和订单也更解耦了,物流依赖订单,订单不依赖物流。 比如你可以先实现订单功能,有时间再实现物流追踪。 甚至我以前做的一个海淘系统,订单和物流采用了不同的子系统,只能通过类似微服务的接口调用,这样保证重构系统的时候,接口不变就可以了。 |
20
xieshaohu 2020-04-20 11:52:53 +08:00
选第一种,页面上加载订单信息和物流信息调用两个接口。原因 :功能解耦了,后台数据库负载低,应用接口也变得简单。
|
21
index90 2020-04-20 12:37:15 +08:00
@mawerss1 横向扩展是指你需要考虑当一台机器已经无法满足你的容量需求时,在架构上能够扩展的能力。看你的数据量,很快单机就处理不了。例如你可能会将不同订单存储在不同节点上,这时候你需要有一个算法,根据 id 找出对应的存储节点,而同一个订单的 content 都存储在一个节点上,显然查询更友好。
|
23
RJH 2020-04-20 16:34:46 +08:00
我建议选第一个,两张表存储,因为你根本不会知道后续会增加什么维度的查询。
本来简单的表,后面可能会随着功能的迭代,增加越来越多的字段。 |
24
fcoolish 2020-04-20 17:24:07 +08:00
反正我选第一个,又不是不会分库分表,然后用缓存索引。
还有数据量大直接从 es 查呗。 |
25
jatesun 2020-04-20 17:37:31 +08:00
第一个还用选吗
|
26
isleon 2020-04-20 17:43:39 +08:00
第二种的话,后面突然让你加个字段你就欲仙欲死了。
|
27
ZoR 2020-04-20 17:47:27 +08:00
第二个后期变更需求,维护会是个灾难
|
28
leoskey 2020-04-20 17:54:33 +08:00
如果项目没死,第二种后期维护的确是个不小的问题。
|
29
chimw 2020-04-20 18:20:40 +08:00
物流信息可以存在时序数据库中,比如 influxdb
|
30
newtype0092 2020-04-20 18:22:14 +08:00
@index90 大佬 MySQL 大概多少数据量时需要考虑横扩呢?
|