从JSON操作到MySQL查询哪个更好,效率更高,服务器负载更少?

时间:2017-12-29 22:58:13

标签: mysql json database

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

在这种情况下,我有两个选择。我可以使用以下结构制作两个名为faqfaq_votes的表:

方法1:

  

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

     

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

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

方法2:

  

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

     

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

在第一种情况中,我会触发大量的MySQL查询来完成我的工作。 在第二种情况下,我会发出更少量的查询,但我必须解决大量的JSON操作。

那么,当我们每月讨论数千个操作时,哪个选项更有效,更少服务器负载?

1 个答案:

答案 0 :(得分:2)

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

为什么呢?它不会扩大规模。要记录对项目的第50,000次投票的投射,您必须读取大型JSON对象,修改它,并使用UPDATE操作在数据库中覆盖它。这将需要很长时间。

第八万名选民从高到低改变投票的情况怎么样?这样做会有多复杂。

在您的第一个选择中,每个新投票只需要一个INSERT ... ON DUPLICATE KEY UPDATE ...操作,只需在投票表中添加一个新行即可。 SQL是以这种方式做事的。

修改以这种方式思考这个问题:

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

您的实体表将包含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