如何在 JSON 中存储个人资料视图? MySQL
How to store profile views inside the JSON? MySQL
每个用户都有一列,它会显示有多少人查看了他的个人资料。
我不需要只显示有多少人查看了个人资料,我还想按时间排序。
我是这样做的,但是如果我达到5000万以上,我就会被查询所困扰,因为它会很慢,而且我可能会遇到意想不到的问题。
观看次数table
User_Id
Viewed_Date
3
...
2
...
2
...
3
...
2
...
2
...
3
...
1
...
我尝试了另一种方式,所以我删除了视图 table 并将其替换为用户列
用户table
Id
Name
Views
1
User1
{ "Last 1 day": 0, "Last 7 days": 0, "Last 30 days": 0, "Last 365 days": 0, "All time": 0 }
2
User2
{ "Last 1 day": 25, "Last 7 days": 0, "Last 30 days": 0, "Last 365 days": 0, "All time": 25 }
3
User3
{ "Last 1 day": 31, "Last 7 days": 162, "Last 30 days": 0, "Last 365 days": 0, "All time": 193 }
JSON 看起来像这样
{
"Last 1 day": 0,
"Last 7 days": 0,
"Last 30 days": 0,
"Last 365 days": 0,
"All time": 0
}
我想问一下更新内部视图的最佳方法是什么JSON,有什么想法吗?
(来自评论)(以前称为 VIEWS
)
CREATE TABLE VISITS (
USER_ID int(11) NOT NULL,
VISITED_IN datetime NOT NULL
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
(您在 JSON 方法的评论中受到严厉批评;我不会重复。)“5000 万行”可能不是问题。
-- If you need to keep the exact time of every view, have this:
CREATE TABLE view_details (
user_id MEDIUMINT UNSIGNED ..., -- pick suitable INT size
view_date DATETIME ...,
PRIMARY KEY(user_id, view_date),
INDEX(view_date, user_id)
) ENGINE=InnoDB;
-- This is a "Summary table" of views by day by user:
CREATE TABLE daily_views (
user_id MEDIUMINT UNSIGNED ...,
view_day DATE ...,
ct SMALLINT UNSIGNED ..., -- pick suitable INT size
PRIMARY KEY(user_id, view_day),
INDEX(view_day, user_id)
) ENGINE=InnoDB;
当您插入 view_details
时,也执行“IODKU”(“upsert”)
INSERT INTO daily_views (user_id, view_day, ct)
VALUES ($user_id, CURDATE(), 1)
ON DUPLICATE KEY UPDATE
ct = VALUES(ct) + 1;
-- In MySQL 8.0, ct = OLD.ct + 1
这为您提供了每个用户的每日计数。对于 weekly/monthly/etc 计数....例如,对于昨天结束的一周:
SELECT SUM(ct)
FROM daily_views
WHERE user_id = $user_id
AND view_day >= CURDATE() - INTERVAL 7 DAY
AND view_day < CURDATE();
(根据您要报告的用户和所需的日期范围,有很多变化。)
抵制每周、每月等总结 table 的诱惑。 通常只有一个摘要table就足够了,而且速度“足够”,甚至是“所有时间”。如果您觉得速度不够快,请提供更多统计信息(典型值view/day、用户数、总浏览量等);我们可以讨论替代方案。
如果您期望每秒 有数百次浏览,我们可能需要进行一些调整。同时,我在这里展示的内容应该可以很好地适应 大多数 应用程序。
更多讨论:Summary Tables
但是,JSON呢?
每个午夜需要发生什么?每个用户的 JSON 中的每个数字都需要重新计算。 (哦,除了“所有时间”——它不会因为时钟滴答而改变。) 当然,有一组 SELECT ... GROUP BYs
可以计算所有数据。然后你必须去每个用户并更新它。
每个用户都有一列,它会显示有多少人查看了他的个人资料。
我不需要只显示有多少人查看了个人资料,我还想按时间排序。
我是这样做的,但是如果我达到5000万以上,我就会被查询所困扰,因为它会很慢,而且我可能会遇到意想不到的问题。
观看次数table
User_Id | Viewed_Date |
---|---|
3 | ... |
2 | ... |
2 | ... |
3 | ... |
2 | ... |
2 | ... |
3 | ... |
1 | ... |
我尝试了另一种方式,所以我删除了视图 table 并将其替换为用户列
用户table
Id | Name | Views |
---|---|---|
1 | User1 | { "Last 1 day": 0, "Last 7 days": 0, "Last 30 days": 0, "Last 365 days": 0, "All time": 0 } |
2 | User2 | { "Last 1 day": 25, "Last 7 days": 0, "Last 30 days": 0, "Last 365 days": 0, "All time": 25 } |
3 | User3 | { "Last 1 day": 31, "Last 7 days": 162, "Last 30 days": 0, "Last 365 days": 0, "All time": 193 } |
JSON 看起来像这样
{
"Last 1 day": 0,
"Last 7 days": 0,
"Last 30 days": 0,
"Last 365 days": 0,
"All time": 0
}
我想问一下更新内部视图的最佳方法是什么JSON,有什么想法吗?
(来自评论)(以前称为 VIEWS
)
CREATE TABLE VISITS (
USER_ID int(11) NOT NULL,
VISITED_IN datetime NOT NULL
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
(您在 JSON 方法的评论中受到严厉批评;我不会重复。)“5000 万行”可能不是问题。
-- If you need to keep the exact time of every view, have this:
CREATE TABLE view_details (
user_id MEDIUMINT UNSIGNED ..., -- pick suitable INT size
view_date DATETIME ...,
PRIMARY KEY(user_id, view_date),
INDEX(view_date, user_id)
) ENGINE=InnoDB;
-- This is a "Summary table" of views by day by user:
CREATE TABLE daily_views (
user_id MEDIUMINT UNSIGNED ...,
view_day DATE ...,
ct SMALLINT UNSIGNED ..., -- pick suitable INT size
PRIMARY KEY(user_id, view_day),
INDEX(view_day, user_id)
) ENGINE=InnoDB;
当您插入 view_details
时,也执行“IODKU”(“upsert”)
INSERT INTO daily_views (user_id, view_day, ct)
VALUES ($user_id, CURDATE(), 1)
ON DUPLICATE KEY UPDATE
ct = VALUES(ct) + 1;
-- In MySQL 8.0, ct = OLD.ct + 1
这为您提供了每个用户的每日计数。对于 weekly/monthly/etc 计数....例如,对于昨天结束的一周:
SELECT SUM(ct)
FROM daily_views
WHERE user_id = $user_id
AND view_day >= CURDATE() - INTERVAL 7 DAY
AND view_day < CURDATE();
(根据您要报告的用户和所需的日期范围,有很多变化。)
抵制每周、每月等总结 table 的诱惑。 通常只有一个摘要table就足够了,而且速度“足够”,甚至是“所有时间”。如果您觉得速度不够快,请提供更多统计信息(典型值view/day、用户数、总浏览量等);我们可以讨论替代方案。
如果您期望每秒 有数百次浏览,我们可能需要进行一些调整。同时,我在这里展示的内容应该可以很好地适应 大多数 应用程序。
更多讨论:Summary Tables
但是,JSON呢?
每个午夜需要发生什么?每个用户的 JSON 中的每个数字都需要重新计算。 (哦,除了“所有时间”——它不会因为时钟滴答而改变。) 当然,有一组 SELECT ... GROUP BYs
可以计算所有数据。然后你必须去每个用户并更新它。