V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
BeanYoung
V2EX  ›  数据库

订单数据的统计系统该怎么设计?

  •  
  •   BeanYoung · 2015-11-03 12:13:55 +08:00 · 1618 次点击
    这是一个创建于 3301 天前的主题,其中的信息可能已经有所发展或是发生改变。

    简单说,有订单表,一天一万单左右(还在不断增加),表里存储了订单的金额,状态,商品,商家,用户等信息。现在有个需求就是按照时间区间和各种纬度来展示订单和统计信息,类似于支付宝的历史消费记录。订单在生成的几天内可能会发生状态变化(退款之类的)。

    另外,团队情况是没有 DBA ,后台研发团队比较小,能专职做这个需求的只有一个工程师。

    想到的方法有这么几种:

    1. 直接对订单数据库表做统计。当时间跨度比较大的时候,性能上会有问题。
    2. 用另外的一一张表存储每日的统计信息,查询的时候直接在统计表里做查询。问题在于订单状态有变化的时候,需要用异步任务更新统计表,容易出现数据不一致的情况。
    3. 用触发器和统计表,在订单表有更新的时候,往另外一张表里添加一条任务记录,然后用 crontab 去查询未执行的任务,将订单数据的变化同步到统计表里。问题在于触发器的使用,估计会有不少坑。

    目前想到这三种方法,都有各自的问题。

    有没有做过类似系统的朋友,欢迎来分享一下经验。

    14 条回复    2015-11-03 18:29:47 +08:00
    jugelizi
        1
    jugelizi  
       2015-11-03 13:15:18 +08:00
    如果是展示统计实时性没那么高的话完全放夜里定时去做分析呀然后缓存起来 每天更新一下
    BeanYoung
        2
    BeanYoung  
    OP
       2015-11-03 14:22:54 +08:00
    @jugelizi 这个要的就是实时统计分析
    scys
        3
    scys  
       2015-11-03 14:33:48 +08:00
    你时间跨度有多大。。。一天一万,一年不够 500 万,十年 5000 万,一百年才 5 亿,买台好点的服务,足够处理了。
    abcfyk
        4
    abcfyk  
       2015-11-03 14:41:18 +08:00
    三个都不是好办法。
    现在你的数据明显分为固定的和易变动的数据,把这两块数据拆开不就很容易统计了嘛。
    把已经完成的订单移动到历史订单表里。订单表只保存未完成订单。
    统计起来就方便很多了。
    这个其实就是分库分表法。

    但是。。这种要对所有订单数量做统计的做法本身就很不好。还有一个办法是用 solr 。我们在用这个。
    1 亿以下的数据统计速度都没有太大差别。
    gamexg
        5
    gamexg  
       2015-11-03 14:51:43 +08:00
    最简单的玩法,可以先直接对订单数据库进行统计,性能不够的时候直接用数据库本身的主从复制弄个统计专用从库,简单可靠。性能还是不行在选用方案 2 ,逻辑设计比较好的话不会出现数据不一致的现象。除非有 DBA ,不建议触发器。 /t/232965
    Magic347
        6
    Magic347  
       2015-11-03 15:04:20 +08:00
    更倾向于方法 2 ,对订单业务数据表和统计数据表进行分离。

    可以基于业务数据表每天的最新数据,每天同步写一份日志,统计数据表基于该日志统计并输出。

    另外,针对订单状态时有变化的情况,在统计时需要维护一份历史订单的最新状态文件,每次统计时一旦发现历史订单的状态发生变化,就要同步更新统计结果数据(因为这可能牵涉到退款以及订单金额的统计)。

    最后,针对楼主考虑到的两边统计数据不一致的状况,可以另外开发一个简单的异步对单任务,对业务数据表的数据和统计数据表的数据每日进行一次对帐,当然考虑到可能需要全表扫描业务数据表,因此在非业务高峰期调度对单任务较宜。
    raysmond
        7
    raysmond  
       2015-11-03 15:22:41 +08:00
    感觉可以这样: Redis 做统计和持久化,统计信息全部异步同步到 DB
    wdd2007
        8
    wdd2007  
       2015-11-03 15:45:10 +08:00
    直接做统计吧。。一天一万应该还好。
    domty
        9
    domty  
       2015-11-03 16:01:44 +08:00
    直接创建个 view 去统计这些数据的性能不够吗?
    jeansfish
        10
    jeansfish  
       2015-11-03 16:16:13 +08:00
    不是数据仓库吗?
    loudis
        11
    loudis  
       2015-11-03 16:20:54 +08:00
    想的太多,人家需要的真的这么精确吗,差几个退款单子会影响大的趋势吗? 2 就好了。
    shakoon
        12
    shakoon  
       2015-11-03 16:26:08 +08:00
    用方案二:每天在业务低谷时段(比如凌晨四点)去对上一日的数据做统计后写入另一个表,以后各种统计都去查这个表。如果对实时性要求高,可以每天跑若干次统计。楼主这个其实是个典型的 BI 建模场景。
    wupher
        13
    wupher  
       2015-11-03 16:33:40 +08:00
    可以直接按维度进行统计,也就是出一张订单的时候直接立即计算出统计值。利用 MongoDB 的 json update 操作。性能消耗极小,实时结果,工作量低。缺点是维度预置。

    可以参考 https://count.ly/ 的开源代码,很简单就搞定了。
    BeanYoung
        14
    BeanYoung  
    OP
       2015-11-03 18:29:47 +08:00
    @loudis 需要精确,会根据统计数据做结算。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1810 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:40 · PVG 00:40 · LAX 08:40 · JFK 11:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.