我创建了一个电子商务后端,我的每个产品都有以下计数器属性
- 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),它也会单独更新,并减少行死锁情况的可能性。 如果它在一个表中并且如果所有它的更新同时出现,则可能导致问题。
问题:有没有更好的方法可以为计数器设计表格?有什么建议吗?
答案 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
另一个建议是将此视图计数功能拆分为关注点。