【问题标题】:Which one is better from JSON operations vs MySQL queries for better efficiency and less server load?JSON 操作与 MySQL 查询哪一个更好,以提高效率并减少服务器负载?
【发布时间】:2017-12-29 22:58:12
【问题描述】:

首先,我知道它们是完全不同的东西,不能直接比较,但让我解释一下我的问题。我想存储民意调查以及用户只能从 UpvoteDownvote 中选择的投票。我想记录每一个动作,这意味着我必须在数据库中存储更多数据。

在这种情况下,我有两个选择。我可以创建两个名为 faqfaq_votes 的表,其结构如下:

方法一:

常见问题表列:idquestion(string)answer(text)created_at(timestamp)updated_at(timestamp)

faq_votes 表格列:idfaq_id(foreign)user_id(foreign)vote(boolean)

或者我可以将所有内容存储在一个表中,我只需在faq 表中添加两列。但在这种情况下,我必须以JSON 格式存储投票。

方法二:

常见问题表列:idquestion(string)answer(text)upvotes(JSON)downvotes(JSON)created_atupdated_at

示例 JSON:{ "total": 5, "users":[ 3,6,10,12,2 ] }

在第一种情况,我会触发大量的 MySQL 查询来完成我的工作。 在第二种情况下,我会触发更少的查询,但我将不得不触发大量 JSON 操作。

那么,当我们谈论每月增加数千次操作时,哪个选项更能提高效率并减少服务器负载?

【问题讨论】:

  • 为什么方法 1 需要更多查询?使用存储过程,您可以一次往返将所有数据传递给 MySQL。
  • 为什么你认为这两种情况下查询的数量会不同?
  • 您可以在单个查询中插入多行 INSERT INTO faq_votes VALUES (null, 1, 1), (null, 1, 2), (null, 1, 3)
  • 从两个表中检索数据是通过连接完成的,而不是多个查询。
  • 虽然 MySQL 现在已经内置了 JSON 函数,但是有时候用普通的 join 很容易做一些事情确实很复杂。我不相信它很有用。

标签: mysql json database


【解决方案1】:

您的第二种选择(将选民的用户 ID 存储在 JSON 对象中)比您的第一种选择差得多

为什么?它不会扩大规模。例如,要记录对某个项目的第 50,000 次投票,您必须读取一个大型 JSON 对象,对其进行修改,然后使用 UPDATE 操作在数据库中覆盖它。那将需要很长时间。

如果第 80,000 名选民将她的选票从上改为下,情况会怎样?这样做的操作有多复杂。

在您的第一个替代方案中,每个新投票只需要一个 INSERT ... ON DUPLICATE KEY UPDATE ... 操作,并且只需将一个新行放入投票表中。 SQL 就是以这种方式做事的。

编辑这样想这个问题:

  • 两个实体:用户和常见问题解答。
  • 用户和常见问题解答之间的一种关系:投票。

您的实体表将具有 user_idfaq_id 唯一标识符,以及您的应用程序需要的任何其他列。

您的关系表,称为vote,每张选票将有一行。它将user_idfaq_id 相关联。此关系表需要三列。

user_id     PK   FK to user.user_id
faq_id      PK   FK to faq.faq_id
vote        TINYINT   1  or -1
datestamp   TIMESTAMP   the time of casting the vote.

注意vote 表有一个复合主键。这可以防止用户对一个常见问题进行多次投票。

这样的结构为您提供了非常灵活的报告。例如,此查询将查找过去两天投票最多的常见问题解答。

 SELECT v.faq_id, SUM(v.vote) votes
   FROM vote v 
  WHERE v.datestamp >= CURDATE() - INTERVAL 2 DAY
  GROUP BY v.faq_id
  ORDER BY SUM(v.vote) DESC
  LIMIT 1

此示例为您提供过去一周投反对票最多的用户

 SELECT v.user_id, u.user_name, COUNT(*) downvotes
   FROM vote v
   JOIN user u ON v.user_id = u.user_id
  WHERE v.vote < 0 
    AND v.datestamp >= CURDATE() - INTERVAL 1 WEEK
  GROUP BY v.user_id, u.user_name
  ORDER BY COUNT(*) DESC
  LIMIT 1

【讨论】:

  • 但是是的,根据你的说法,在这种情况下什么样的结构会好。
猜你喜欢
  • 1970-01-01
  • 2011-03-09
  • 1970-01-01
  • 1970-01-01
  • 2013-03-30
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
相关资源
最近更新 更多