我个人喜欢将文章交互统计表单独分离出来设计,并与文章ID关联起来。这样不至于使文章所太多的字段,提升查询效率。
表结构里有日点击、周点击、月点击、总点击、日投票、周、月、总投票与评论数等。我的建表语句如下:
CREATE TABLE `mycms_post_counts` (
`id` mediumint UNSIGNED NOT NULL COMMENT '文章ID',
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`dayvisit` mediumint UNSIGNED NOT NULL DEFAULT '0' COMMENT '日点击',
`weekvisit` mediumint UNSIGNED NOT NULL DEFAULT '0' COMMENT '周点击',
`monthvisit` mediumint UNSIGNED NOT NULL DEFAULT '0' COMMENT '月点击',
`allvisit` int UNSIGNED NOT NULL DEFAULT '0' COMMENT '总点击',
`dayvote` smallint UNSIGNED NOT NULL DEFAULT '0' COMMENT '日推荐',
`weekvote` smallint UNSIGNED NOT NULL DEFAULT '0' COMMENT '周推荐',
`monthvote` mediumint UNSIGNED NOT NULL DEFAULT '0' COMMENT '月推荐',
`allvote` int UNSIGNED NOT NULL DEFAULT '0' COMMENT '总推荐',
`agree` int UNSIGNED NOT NULL DEFAULT '0' COMMENT '顶',
`diss` int UNSIGNED NOT NULL DEFAULT '0' COMMENT '踩',
`comments` mediumint UNSIGNED NOT NULL DEFAULT '0' COMMENT '评论数'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='文章统计信息' ROW_FORMAT=COMPACT;
当然如果我们站交互足够强,可以考虑增加日评论数、周评论数、月评论数、总评论数等。
下面为了提升性能 为 此表做一下索引优化工作:
ALTER TABLE `mycms_post_counts`
ADD PRIMARY KEY (`id`),
ADD KEY `dayvisit` (`dayvisit`),
ADD KEY `weekvisit` (`weekvisit`),
ADD KEY `monthvisit` (`monthvisit`),
ADD KEY `allvisit` (`allvisit`),
ADD KEY `dayvote` (`dayvote`),
ADD KEY `weekvote` (`weekvote`),
ADD KEY `monthvote` (`monthvote`),
ADD KEY `allvote` (`allvote`),
ADD KEY `agree` (`agree`) USING BTREE;
然后与文章表关联起来:
ALTER TABLE `mycms_post_counts`
ADD CONSTRAINT `post_idship` FOREIGN KEY (`id`) REFERENCES `mycms_post` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
COMMIT;
好了,我们的建表与优化工作到这些就完成了。下面我们去实现点击自动无则插入表字段,有则更新的逻辑。
程序实现逻辑很简单,下面我就以php为例,使用laravel框架封闭的ORM代码,对于数据操作,我们应该封装到Model里,所以我们需要在PostCount模型里增加一个处理点击的方法即可:
//获取统计信息
public static function count($id)
{
$count = self::find($id);//查询ID
if (empty($count)) {
$count = array(
'id' => $id,
'dayvisit' => 1,
'weekvisit' => 1,
'monthvisit' => 1,
'allvisit' => 1,
'dayvote' => 0,
'weekvote' => 0,
'monthvote' => 0,
'allvote' => 0,
'agree' => 0,
'diss' => 0,
'comments' => 0
);
self::create($count);//表里不存在则新插入一条
return $count;
}
return $count->toArray();//返回获取到的统计信息
}
//更新统计
public static function updateView($id, $viewCount)
{
if ($viewCount > 0) {
$self = self::find($id);
$self->increment('dayvisit', $viewCount);
$self->increment('weekvisit', $viewCount);
$self->increment('monthvisit', $viewCount);
$self->increment('allvisit', $viewCount);
}
}
因为我将查看数缓存在了Redis里,所以我会定时去更新数据库,这样不会频繁的去读写Mysql。
这步需要在文章的控制器里去操作:
//增加查看数(缓存时间同book)
private function updateView()
{
$key = 'book:viewcount:' . $this->id;//缓存Key
if (!empty($this->data['counts']['updated_at']) && IlluminateSupportCarbon::now()->gt(IlluminateSupportCarbon::now()->parse($this->data['counts']['updated_at'])->addSecond($this->app['cache_time']))) {
AppModelsPostCount::updateView($this->id, Cache::pull($key)); //从缓存读取并更新数据表
}
Cache::has($key) ? Cache::increment($key) : Cache::put($key, 1); //增加到缓存
}
当前你也可以通过使用cookies来验证用户是否在一直刷新,或者使用IP等更严格的方式来验证用户刷点击数。
前面完整的展示了点击整个逻辑与建表结构的过程,下面我们就需要通过利用数据库提供的事件服务实现每天0点清理点击与投票等信息;
我们可以使用下面的代码:
CREATE DEFINER=`root`@`localhost` EVENT `日清理` ON SCHEDULE EVERY 1 DAY
STARTS '2022-07-18 00:00:01' ON COMPLETION NOT PRESERVE ENABLE
DO UPDATE `mycms_post_counts` SET `dayvisit` = '1', `dayvote` = '0'
看不懂代码?哦,没有关系,我们可以通过视图来创建:
下面我以phpmyadmin为例。打开数据库,在右上角找到“事件”选项:
上面设置为每 1 day 循环执行,起始时间就是每次 循环执行的时间,这里我设置为今天的 0点0分01秒开始。下次循环就在此基础上 加 1 day。
除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/234
《【实战】巧妙利用数据库“事件”实际日点击、周点击、月点击等功能更新》的网友评论(0)