书籍下载量统计¶
简介¶
需求:记录书籍下载事件及时间,便于统计下载量和书籍热度。是否保存用户级别的下载记录,应结合隐私和数据保留要求决定。
数据库设计与实现¶
-
新增下载记录表,保存书籍、用户和下载时间等字段。
-
书籍表增加下载数量汇总字段(如果采用预计算)。
ALTER TABLE `book` ADD `download_count` INT DEFAULT 0;
CREATE TABLE `download_info` (
`id` int NOT NULL AUTO_INCREMENT,
`userid` INT NOT NULL,
`bookid` INT NOT NULL,
`created_at` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
alter table download_info add constraint download_info_user_foreign_key foreign key (userid) references user(id);
alter table download_info add constraint download_info_book_foreign_key foreign key (bookid) references book(id);
后端 API 设计¶
下载书籍时增加一条下载记录,并更新书籍的下载量汇总字段。下面为逻辑示意,实际实现应校验参数,并根据数据库驱动保证操作的一致性。
// 记录下载事件
const { book_id, user_id } = req.query;
// 下载书籍时,增加一条下载记录
const sql = `insert into download_info (userid, bookid) values(?, ?)`;
await DBHelper(
sql,
(err, results) => {
if (err) {
logger.error(err);
res.status(400).send({ error_message: err.message });
return;
}
// 重新计算并更新书籍下载量。生产实现可用事务或原子递增避免并发不一致。
if (results) {
const sql = `update book set download_count = (select count(id) from download_info WHERE bookid=?) where id=?;`;
DBHelper(
sql,
(err, results) => {
if (err) {
logger.error(err);
res.status(400).send({ error_message: err.message });
return;
}
},
[book_id, book_id]
);
}
},
[user_id, book_id]
);
书籍列表 API 返回新增的 download_count 字段。以下为查询示例:
SELECT id, name, cover_photo, author, brief, price, size, tag, download_count FROM book ORDER BY download_count DESC limit 10;
前端交互设计¶
界面展示书籍下载数量:
<span>下载 {download_count} 次</span>
代码实现¶
https://github.com/Novel-Reader/Genshin-novel-reader/pull/81/files
https://github.com/Novel-Reader/Genshin-novel-reader-express-server/pull/27/files
未来¶
管理员可以查看书籍及下载情况。
统计指定时间范围内下载量最高的书籍。