为产品实施喜欢,评论和观看计数器

时间:2015-11-20 06:51:54

标签: mysql e-commerce counter deadlock

我创建了一个电子商务后端,我的每个产品都有以下计数器属性

- product views
- product likes
- product comments count

我对产品数据库表的当前数据库列是

 - id
 - likes_count
 - views_count
 - comments_count
 - category_id
 - category_parent_id
 - category_sub_parent_id
 - handling_charge
 - shipping_charge
 - meetup_address
 - is_additional_fields
 - status
 - is_deleted
 - created_at
 - updated_at

如以下博客Wanelo engineering blog所示 实现一个经常在单行上更新的计数器会导致innodb上的行锁定,如果频繁更新会导致应用程序死锁情况。但对此的解决方案在博客中得到了很好的解释,我对此有所了解。但是,如果有多个计数器与单个产品相关联,可以在应用程序增长时同时更新。我该如何设计计数器的数据库表。我是否必须维护单独的表格

likes counter table

 - id     - product_id      - count

views counter table

 - id     - product_id     - count

comments counter table

 - id     - product_id     - count

通过维护单独的表,即使产品同时更新(如+ comment + view),它也会单独更新,并减少行死锁情况的可能性。 如果它在一个表中并且如果所有它的更新同时出现,则可能导致问题。

问题:有没有更好的方法可以为计数器设计表格?有什么建议吗?

2 个答案:

答案 0 :(得分:2)

产品表中的视图中的计数器很好。

对于像(product_id,user_id)这样的列的喜欢的单独表格,因此每个用户只能喜欢一次产品。否则,如果它只是一个简单的计数器,它们就能够混合。

用于评论的单独表格,例如(product_id,comment_text,date .. etc)

这就是你问的问题吗?

答案 1 :(得分:0)

使用后台队列来缓冲插入/更新,如您共享的链接中所建议的那样非常标准,我建议也是如此。

您可以像单个计数器一样重新计算多个计数器。可以在Memcached / Redis中缓存查看计数,也可以将它们存储在单独的表中(尽管我建议只使用一些分析解决方案)。

在你的工人中:

function moveFigure(FigName:String; FieldName:String):boolean;
var
  x:Integer;
  y:Integer;
begin
  if (FigureSelected=true) and (FieldSelected=true) then
   begin
     x := strtoint(FieldSelectedName[2]);
     y := Ord(FieldSelectedName[1])-64;

     FigureSelectedName.top  := 80 + (x * 70);
     FigureSelectedName.left := 80 + (y * 70);
   end;
end;

在你的模特中:

class ProductCountsWorker
  # ...

  def perform(product_id)
    Product.find(product_id).update_counts!
  end
end

另一个建议是将此视图计数功能拆分为关注点。

Rails Low-Level Caching docs