一个表设计问题

mawerss1 7月前 112

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

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

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

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

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

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

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

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


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

    甚至我以前做的一个海淘系统,订单和物流采用了不同的子系统,只能通过类似微服务的接口调用,这样保证重构系统的时候,接口不变就可以了。
  • xieshaohu 7月前
    引用 21
    选第一种,页面上加载订单信息和物流信息调用两个接口。原因 :功能解耦了,后台数据库负载低,应用接口也变得简单。
  • index90 7月前
    引用 22
    @mawerss1 横向扩展是指你需要考虑当一台机器已经无法满足你的容量需求时,在架构上能够扩展的能力。看你的数据量,很快单机就处理不了。例如你可能会将不同订单存储在不同节点上,这时候你需要有一个算法,根据 id 找出对应的存储节点,而同一个订单的 content 都存储在一个节点上,显然查询更友好。
  • 楼主 mawerss1 7月前
    引用 23
    @index90 目前是根据用户 id 来分库的
  • RJH 7月前
    引用 24
    我建议选第一个,两张表存储,因为你根本不会知道后续会增加什么维度的查询。

    本来简单的表,后面可能会随着功能的迭代,增加越来越多的字段。
  • fcoolish 7月前
    引用 25
    反正我选第一个,又不是不会分库分表,然后用缓存索引。
    还有数据量大直接从 es 查呗。
  • jatesun 7月前
    引用 26
    第一个还用选吗
  • isleon 7月前
    引用 27
    第二种的话,后面突然让你加个字段你就欲仙欲死了。
  • ZoR 7月前
    引用 28
    第二个后期变更需求,维护会是个灾难
  • leoskey 7月前
    引用 29
    如果项目没死,第二种后期维护的确是个不小的问题。
  • chimw 7月前
    引用 30
    物流信息可以存在时序数据库中,比如 influxdb
  • newtype0092 7月前
    引用 31
    @index90 大佬 MySQL 大概多少数据量时需要考虑横扩呢?
  • 游客
    32
返回