将计算值存储在数据库中是个坏主意吗?

时间:2018-05-07 13:49:38

标签: sql sql-server database database-design relational-database

让我们说我正在开发一个商店项目。所以,我必须创建一个名为' Product'在我的数据库中。说我也希望用户能够喜欢'我的产品。这样我就可以创建另一个名为' ProductLike'存储用户' ids以及他们喜欢的产品的ID。

主要方案:每次用户向我的网站发送请求以获取产品页面时,我都必须重新计算该产品的数量。

我的问题是:所以,我知道标准方法不是存储'计算值'在数据库中。但是这样的情况呢? (需要很长时间才能计算出值的情况)。例如,在上面的例子中,有一个名为' NumberOfLikes'的列更好。在'产品'表存储计算出的产品数量是多少?

4 个答案:

答案 0 :(得分:1)

  • UserProductLike表可以获取用户喜欢的产品数量,其中userid是您用户的ID。

enter image description here

答案 1 :(得分:1)

<强>更新

  

在“产品”表格中使用名为“NumberOfLikes”的列来存储计算出的产品数量是不是更好?

恕我直言,这个问题的直接答案是“不,除非你因为喜欢的计数而出现真正的性能问题”。

如果您确实遇到了性能问题,并且已将其来源确定为喜欢的数量,那么您可能需要考虑在LikesCount表中添加products列。如果您确实添加了这样的列,请注意,您必须在ProductLike表的每次更改时更新它 - 删除,更新和插入。
这意味着你将不得不为这个表写一个触发器来处理所有这些情况,但它不应该太难,因为你可以在一个触发器中完成所有事情 - 如下所示:

create trigger ProductLikeChaneged on ProductLike 
for insert, update, delete
as

    update p
    set LikesCount = (select count(*) from ProductLike as pl where pl.productId = p.Id)
    from product as p
    where exists
    (
        select 1 from inserted as i where p.id = i.productId
    )
    or exists
    (
        select 1 from deleted as d where p.id = d.productId
    )

原始版
根据您的描述,“计算”产品的喜欢数量只是ProductLike表中的行数,其中产品ID是您当前向用户显示的产品的ID。
这可以非常快速地完成,特别是如果ProductLike表聚簇索引是ProductId然后是UserId,从而允许SQL Server使用聚簇索引查找而不是表扫描。

基本上,您的ProductLike表应如下所示:

 Create table ProductLike
 (
     ProductId int,
     UserId int,
     Constraint PK_ProductLike PRIMARY KEY (ProductId, UserId)
 )

请注意,默认情况下,SQL Server将使用主键作为表的聚簇索引。

然后,产品页面的select语句可以是这样的:

select Name, Description, -- Other product related details
       (select count(*) 
        from productLike as pl 
        where pl.ProductId = p.Id) as likeCount
from product as p

答案 2 :(得分:0)

对于现实生活,他们是真正的解决方案。您应该实现此字段并对数据库进行非规范化以保持性能。你有几个选择来保持这个领域的最新成果:

免责声明:您的问题是基于意见的,我想会暂时关闭。

答案 3 :(得分:0)

通过“计算”值,我怀疑你的意思是累积请求数量。

在数据库设计和维护方面最简单的方法是将每个请求作为一行存储在表中,并在需要时进行汇总。这有一些很好的功能:

  • 用户可以非常轻松地“不要求”或“不同”。
  • 插入(通常)位于工作台的“末端”,从而最大限度地减少碎片和加速插入。注意:如果多个线程同时写入,则可能导致争用最后一页。
  • 计数可以灵活,仅限于特定日期范围或用户类型。
  • 数据是可钻取的。也就是说,对于给定的计数,你确切知道它产生了什么。

如果数据上有正确的索引和分区,则摘要通常非常合理。

也就是说,这样的总结并不能满足所有需求。传统方法是使用触发器来维护汇总表 - 为维护增加了许多复杂性(需要插入,删除和更新触发器)。我认为@ daniherrera的答案为最佳方法提供了指导。