如何在MySQL中存储最近的使用频率

时间:2017-06-22 08:55:53

标签: mysql sql database

我正在处理Product Catalog应用程序的Invoicing模块。

当用户创建新发票时,product name字段应为自动填充字段,该字段显示产品目录中最近使用的产品。

如何在数据库中存储此“使用新近度/频率”?

我正在考虑添加一个新字段recency,每次使用该产品时,该字段1会增加1/(count of all products),而当使用其他产品时,会减少recency。然后使用此for i, d in evening_data.groupby([identification, name, age,address]): master(d, 'F') 字段进行排序,但在我看来这不是最好的解决方案。

你能帮助我解决这类问题的最佳做法吗?

7 个答案:

答案 0 :(得分:6)

新近度计算的解决方案:

在products表中创建一个名为last_used_on的新列。它的数据类型应该是TIMESTAMP(Unix时代的MySQL表示)。

<强>优点:

  • 时间戳包含日期和时间部分。
  • 可以进行非常精确的计算和比较 日期和时间。
  • 它允许您以您的日期时间格式格式化保存的值 选择。
  • 您可以将任何日期时间格式转换为时间戳。
  • 关于您的自动填充字段,它允许您过滤 产品列表如您所愿。例如,显示所有产品 自 [date-time] 以来使用。或者获取之间使用的所有产品 [date-time-1] [date-time-2] 。或者仅在星期一,下午1:37:12,过去两年,两个月和三天使用产品 天(如此灵活的时间戳)。

<强>资源:

使用率计算的解决方案:

嗯,实际上,你不是在谈论 频率 计算,而是关于 - 尽管可以说频率是也是一个比率。

频率意味着使用时间作为参考单位,并以赫兹( Hz = [1 /秒] )测量。例如,假设您要查询去年产品的使用次数。

另一方面,

比率是两个相关单位之间的比较关系。例如汇率美元/欧元 - 它们都是货币。如果比较发生在相同类型的两个术语之间,则结果是没有测量​​单位的数字:百分比。喜欢: 50个苹果/ 273个苹果= 0.1832 = 18.32%

那就是说,我想您试图计算使用率:与用法数量相关的产品的用途的数量所有产品。就像产品一样:usage rate of the product = 17 usages of the product / 112 total usages = 0.1517... = 15.17%。在自动填充功能中,您希望显示使用率大于给定百分比的产品(例如9%)。

这很容易实现。在products表格中添加usagesint类型的列bigint,并在每次使用产品时简单地增加其值。然后,当您想要获取最多使用的产品时,只需应用此sql语句中的过滤器:

SELECT
    id, 
    name, 
    (usages*100) / (SELECT sum(usages) as total_usages FROM products) as usage_rate
FROM products 
GROUP BY id
HAVING usage_rate > 9
ORDER BY usage_rate DESC;

这是一个小案例:

Study case

最后, 新近度 频率 评分 是三件不同的事情。

祝你好运。

答案 1 :(得分:4)

为了实现未来的灵活性,我建议使用以下附加(*)表来存储所有用户的产品使用历史记录:

名称: product_usage

列:

  • id - 内部代理自动递增主键
  • product_id (int) - 产品标识符的外键
  • user_id (int) - 用户标识符的外键
  • 时间戳(日期时间) - 使用产品的日期/时间

这将允许根据需要对查询进行微调。例如。您可以决定仅根据登录用户的过去使用情况进行排序。或者也许在特定时间范围内的总使用量将更具相关性。这样的表也可能具有审计的双重目的 - 例如报告所有用户中最受欢迎或不受欢迎的产品。

(*) 假设您的数据库架构中已经存在类似的内容

答案 2 :(得分:3)

您的问题与许多其他网络规模的搜索应用程序有关,例如显示拼写更正,相关搜索或“趋势”主题。您正确认识到,新近度和频率都是确定“热门”建议的重要标准。在实践中,希望在两者之间做出妥协:单独的新近度将受到随机波动的影响;但你也不想只使用频率,因为有些产品过去可能已经购买了很多,但它们的受欢迎程度正在下降(或者它们可能已经缺货或被后续机型取代)。

在这些方案中通常使用的非常简单但有效的实现是exponential smoothing。首先,大多数时候它足以以固定的时间间隔(例如,每天一次)更新流行度。设置一个衰减参数α(比如说, .95 ),告诉你昨天的订单数与今天相比有多少。同样,两天前的订单价值α*α~。9 次,与今天相同,依此类推。要估计此参数,请注意该值在 log(.5)/ log(α)天后衰减到一半(α= .95 约为14天)。

每个产品只需要一个额外的字段, orders_decayed。然后,您所要做的就是每晚使用每日总订单更新此值:

  

orders_decayed =α* orders_decayed +(1-α)* orders_today。

您可以根据此值对相应的建议进行排序。

答案 3 :(得分:2)

要获得个人用户体验,您不应该依赖产品表中的字段,而应该依赖于用户的历史记录。

用户创建的过去发票中产品的出现将是一个很好的起点。优点是您不需要为此功能添加字段或表。您只需依赖已经存在的数据。

由于它是一个自动完成字段,因此过去的使用可能并不真正相关。以用户类型显示n个搜索结果。如果您认为在计算订单时包含新近度,结果会更好,请使用它。

答案 4 :(得分:2)

现在,实施可能会延迟,具体取决于产品的显示方式和时间。是否必须是用户特定的使用频率或特定于应用程序(整体)。但是,在这两种情况下,我建议使用history表,稍后您可以将其用于其他分析。

您可以设计history表格至少列以下列:

Id  | ProductId | LastUsed (timestamp) | UserId 

而且,现在您可以创建一个视图,该视图将查询此表格的特定时间范围(类似于上周,上个月或去年的产品频率),并将为您提供特定时间范围内的最高销售产品。

同样可以通过添加附加条件来按用户ID过滤来用于用户的特定频率。

  

我正在考虑增加一个可以增加的新领域新近度   每次使用产品时减1,减少1 /(全部计数)   产品),当使用其他产品时。然后使用此新近度字段   对于订购,但它在我看来并不是最好的解决方案。

是的,为此添加列并每次更新都不是一个好习惯。想象一下,这个产品是最等待的产品,人们喜欢购买它。现在,一次,1000个人或者可能更多地请求此产品以及每个请求您将更新同一行,因为维护并发数据库必须锁定该特定行并更新每个请求,这肯定会发生要获得数据库和应用程序性能,您只需插入一个新行即可。

另一种可能的解决方案是,您可以使用现有的发票表,因为它肯定会包含所有产品和用户特定信息,并创建一个视图以获取上面提到的常用产品。

请注意,这是实现您期望的另一种选择。但是,我个人建议改为使用history表。

答案 5 :(得分:1)

场景

  

当用户创建新发票时,产品名称字段应为自动填充字段,该字段显示产品目录中最近使用的产品。

您建议的解决方案

  

如何在数据库中存储此“使用新近度/频率”?

如果是Web应用程序,请不要将其存储在服务器的数据库中。每个用户都有不同的选择。

将其作为Cookie或Localstorage存储在用户的浏览器中,因为它可以改善用户体验。

如果您仍想将其存储在MySQL表中,

执行以下操作

  1. 如上所述创建列recency

  2. 每次使用该项目时,如上所述将计数增加1.

  3. 使用其他物品时请勿减少。

  4. 要获取最近使用最多的项目,

  5. 查询

    SELECT * FROM table WHERE recence = (SELECT MAX(recence) FROM table);
    

    旁注

    仅在您希望在不依赖用户的情况下显示最近使用最多的产品时才使用数据库。

答案 6 :(得分:1)

由于您不确定要选择的措施,以及与用户体验相关的问题,我建议您采取一系列措施,并为用户提供选择他/她更喜欢的选项的选项。例如,可用度量集可包括上周,上个月,过去3个月,去年,总体总数中最受欢迎的产品。出于性能考虑,我更喜欢将这些统计信息存储在单独的表中,该表由例如每3小时运行一次的预定作业刷新。