【问题标题】:Schema/Strategy and queries for ranking system排名系统的架构/策略和查询
【发布时间】:2011-07-04 05:06:20
【问题描述】:

我的数据库中有以下架构:

| items | CREATE TABLE `items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `description` text COLLATE utf8_unicode_ci,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |

| rankings | CREATE TABLE `rankings` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `item_id` int(11) DEFAULT NULL,
  `rank` int(11) DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |

我基本上希望用户能够添加项目并将它们相互排名。我系统中的管理员将能够查看按平均排名排序的项目列表。我目前正在使用这样的查询来确定所有用户的平均排名:

SELECT AVG(r.rank) AS rank, i.* FROM rankings r LEFT OUTER JOIN items i ON r.item_id = i.id GROUP BY i.id ORDER BY rank ASC;

我正在苦苦挣扎的是如何在添加新项目并且尚未被任何用户排名时制定查询或插入策略。我看到的两个可行策略是:

1) 构造查询以获取所有用户的排序列表,这样未排序的项目仍会被计算在内,但可能会添加到每个用户的列表末尾,按创建日期排序

2) 添加新商品时,在排名表中为新商品的每个用户添加一行,在当前排名中排在最后

想法?

【问题讨论】:

  • +1 只是为了在您的问题中包含正确的 SHOW CREATE TABLE 输出。谢谢,谢谢。

标签: database-design database-schema


【解决方案1】:

我不是 mysql 用户,所以这两种语法中的一种适合你。在 AVG 计算中使用 ifNull

SELECT AVG(ifNull(r.rank,0)) AS rank, i.* 
  FROM rankings r LEFT OUTER JOIN items i ON r.item_id = i.id
GROUP BY i.id
ORDER BY rank ASC;

或者,如果 mysql 不允许嵌套这样的函数:

SELECT AVG(s.rank) as avg_rank, s.*
  FROM ( SELECT ifNull(r.rank,0) AS rank, i.* 
           FROM rankings r LEFT OUTER JOIN items i ON r.item_id = i.id
         GROUP BY i.id ) as s
ORDER BY avg_rank ASC;

您还应该在表定义中使用ON DELETE CASCADErankings.item_iditems.id 之间建立外键关系。

【讨论】:

  • 感谢 Mark 的输入,是的,我需要通过级联删除添加外键关系。这确实为我节省了一些时间。但是,您建议的查询对我来说并不完全,因为它们不考虑某些用户尚未排名的项目。我认为使用 ifNull 足以让我继续下去。我会尽快报告。
【解决方案2】:

我现在最终选择了上面的选项 #2,即在添加新项目时为每个用户/项目组合创建一个排名行。我担心可扩展性,但无论如何它已经足够了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    • 2021-10-30
    • 2012-07-06
    相关资源
    最近更新 更多