• 通过 URL 来查数据? at 2018年07月07日

    遇到PM这样提需求,我一般都回「你把需求想法描述清楚,或者给一个可以抄的网站看看」

  • 粗暴

  • 很少听说过压工资的互联网公司…

  • Yes.

    对于简单场景,用ORM来做reporting也是可行的。对复杂场景,不能说AR抽象程度不够,本质上每个gem有自己的解决的领域。

    # Sam: complicated reports are really hard in AR

    代码重复问题,其实这就是一个tradeoff,ORM里的方法对于reporting来说,理论上确实可以共用,但实现上是很难共用,硬要共用的话,必然是写成N+1的方式,之前做过一个项目,reporting部分就是这种思路写的,数据量还不大的时候一个页面就可以达到几十秒。

    如果reporting部分想共用的话,其实需要写UDF和view,试过几次效果还不错。

    刚看了这篇文章,mini sql的用途写的非常清晰了:https://meta.discourse.org/t/new-official-direct-sql-access-api-for-discourse-mini-sql/90441

     # Sam: complicated reports are really hard in AR
     builder = DB.build <<-SQL
    SELECT ftl.url,
           COALESCE(ft.title, ftl.title) AS title,
           ftl.link_topic_id,
           ftl.reflection,
           ftl.internal,
           ftl.domain,
           MIN(ftl.user_id) AS user_id,
           SUM(clicks) AS clicks
    FROM topic_links AS ftl
    LEFT JOIN topics AS ft ON ftl.link_topic_id = ft.id
    LEFT JOIN categories AS c ON c.id = ft.category_id
    /*where*/
    GROUP BY ftl.url, ft.title, ftl.title, ftl.link_topic_id, ftl.reflection, ftl.internal, ftl.domain
    ORDER BY clicks DESC, count(*) DESC
    LIMIT 50
    SQL
    
     builder.where('ftl.topic_id = :topic_id', topic_id: topic_id)
    
  • 这个确实很有用,之前用Rails做项目遇到统计需求很尴尬,用AR来做特别难,一般最终结果就写成了sql+rails的合体,导致可维护性特别差。

    本质上是统计需求和ORM并不是同一个维度上的事情,ORM解决的是表和对象之间的关系,而统计需求其实是面向主题的。 另外一个问题是ORM做统计的话经常会产生N+1查询。所以统计需求我一般都直接纯sql的方式来写,不使用任何AR相关API,例如:

    AR.connection.execute(<<-SQL)
      /* 按SKU分组,计算出出仓数量 */
      WITH shipment_items_by_sku AS (
          SELECT product_variant_id, SUM(quantity) AS ship_count
            FROM shipment_items
           WHERE deleted_at IS NULL AND company_id = 1
        GROUP BY 1
      ),
      /* 按SKU分组,计算出订单数量、最大金额等 */
      order_items_by_sku AS (
        SELECT pv.company_id,
               oi.product_variant_id,
               sum(oi.quantity)   AS order_count,
               sum(oi.sum_price)  AS sum_money,
               max(oi.price)      AS max_money,
               min(oi.price)      AS min_money,
               avg(oi.price)      AS avg_money
          FROM order_items AS oi
               INNER JOIN product_variants AS pv ON pv.id = oi.product_variant_id
         WHERE pv.deleted_at IS NULL AND oi.deleted_at IS NULL AND oi.company_id = 1
      GROUP BY 1,2
      ORDER BY 3 DESC
         LIMIT 10
      )
    
      SELECT order_items_by_sku.*, 
             coalesce(sibs.ship_count, 0) AS ship_count
        FROM order_items_by_sku
             LEFT JOIN shipment_items_by_sku AS sibs ON order_items_by_sku.product_variant_id = sibs.product_variant_id
    ORDER BY order_items_by_sku.order_count DESC
    SQL
    

    但这么写的话带来一个问题,用户传参的地方需要自己去防止sql注入,不过mini sql的出现解决了sql注入问题(使用的prepared statment),我觉得mini sql当然不是去和ORM比,其实是弥补了ORM在统计和ETL领域的不足。看了一下mini sql在discourse的应用,也是用来做统计相关:

  • Ruby Docker with jemalloc at 2018年06月21日

    这个结论怎么得来的,之前用alpine 跑sidekiq 内存涨的还是飞快的

  • 卧槽 还作诗

  • 招聘困难 at 2018年06月20日

    所以女朋友是HR?

  • 继续继续

  • 讨要薪资 at 2018年06月17日

    不是6月15日发工资嘛,今天17号了,该发多少发多少就完了呗

hey!