You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP如何根据数据库存储数据实现分类div按热度排序

PHP实现分类板块按热度动态排序方案

核心逻辑很简单:先按规则统计每个分类的热度分值,按分值倒序排列分类列表,最后按排好的顺序渲染前端div即可。

1. 前置确认:行为表结构

你已经在存储用户搜索、点击行为,确保行为表(示例表名user_behavior)包含以下核心字段即可:

  • id:主键
  • category_slug:分类唯一标识,比如餐饮分类存restaurants,搜索关键词命中对应分类时也写入对应标识,未命中分类的搜索词留空即可
  • behavior_type:行为类型,比如click代表分类点击、search代表搜索关联分类
  • user_id:操作用户ID(可选,用于防刷)
  • create_time:行为发生时间戳

建议给不同行为设置差异化权重:比如分类点击权重为1,主动搜索对应分类的权重设为2,毕竟搜索行为的用户意向更强,权重可以根据你的业务需求灵活调整。

2. 热度统计SQL

不要每次请求都实时全表统计,后续会加缓存,先写统计逻辑:

SELECT 
  category_slug,
  SUM(
    CASE 
      WHEN behavior_type = 'click' THEN 1 
      WHEN behavior_type = 'search' THEN 2 
      ELSE 0 
    END
  ) AS hot_score
FROM user_behavior
-- 只统计近30天的行为,避免几个月前的老数据长期占住前排
WHERE create_time >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 30 DAY)) 
  AND category_slug IS NOT NULL AND category_slug != ''
-- 防刷的话加GROUP BY前先去重:先按user_id, category_slug分组把同用户同分类的重复记录合并
GROUP BY category_slug
ORDER BY hot_score DESC

执行后会返回按热度从高到低排列的分类标识、对应热度分值。

3. PHP排序逻辑

首先你需要先维护一份全部分类的基础配置数组,包含分类名、图标等展示信息:

// 所有预设分类的基础信息,key为分类唯一标识,和行为表存的category_slug对应
$baseCategories = [
  'restaurants' => ['name' => '餐饮美食', 'icon' => 'food.png'],
  'hotels' => ['name' => '酒店住宿', 'icon' => 'hotel.png'],
  'education' => ['name' => '教育培训', 'icon' => 'edu.png'],
  // 其余分类按你原有预设补全即可
];

接下来读取热度排名,重排分类列表:

// 数据库连接示例,换成你项目自己的DB操作类即可
$pdo = new PDO('mysql:host=localhost;dbname=你的数据库名;charset=utf8mb4', '数据库用户名', '数据库密码');
$cacheKey = 'category_hot_sort';
// 优先读缓存,没有再查库,缓存时间设10分钟即可,分类排名不需要实时更新
// 缓存可以用Redis、文件缓存都行,这里以Redis为例
if (!$sortedSlugs = $redis->get($cacheKey)) {
    $statRes = $pdo->query("SELECT category_slug,SUM(CASE WHEN behavior_type = 'click' THEN 1 WHEN behavior_type = 'search' THEN 2 ELSE 0 END) AS hot_score FROM user_behavior WHERE create_time >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 30 DAY)) AND category_slug IS NOT NULL AND category_slug != '' GROUP BY category_slug ORDER BY hot_score DESC")
        ->fetchAll(PDO::FETCH_KEY_PAIR);
    $sortedSlugs = array_keys($statRes ?: []);
    $redis->set($cacheKey, $sortedSlugs, 600); // 缓存10分钟
}

// 组装排序后的分类列表
$sortedCategories = [];
// 先按热度排名放入有统计数据的分类
foreach ($sortedSlugs as $slug) {
    if (isset($baseCategories[$slug])) {
        $sortedCategories[$slug] = $baseCategories[$slug];
        unset($baseCategories[$slug]);
    }
}
// 没有热度数据的冷门类,按你原来的预设顺序接在后面即可
$sortedCategories = array_merge($sortedCategories, $baseCategories);

4. 前端渲染

直接遍历排好序的数组输出div即可,输出顺序就是热度从高到低:

<?php foreach ($sortedCategories as $slug => $info): ?>
<div class="category-card" data-slug="<?= htmlspecialchars($slug) ?>">
    <img src="/static/category/<?= htmlspecialchars($info['icon']) ?>" alt="<?= htmlspecialchars($info['name']) ?>">
    <span><?= htmlspecialchars($info['name']) ?></span>
</div>
<?php endforeach; ?>

优化建议

  • 一定要加缓存,高流量场景下可以把缓存时间调到30-60分钟,分类排名不需要秒级更新,能大幅降低数据库压力
  • 可以加时间衰减规则,比如近7天的行为权重是30天前行为的2倍,让近期热门的分类更容易排到前面
  • 如果存在恶意刷量的情况,统计热度时先按user_id + category_slug去重,同一个用户24小时内对同一个分类的多次操作只计1次

分类板块参考效果:
分类板块参考效果

内容的提问来源于stack exchange,提问作者Bob0220

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 17:39:19