【问题标题】:trying to build a mySQL database from a JSON format, but can't figure out how [closed]尝试从 JSON 格式构建 mySQL 数据库,但不知道如何 [关闭]
【发布时间】:2021-06-29 23:47:12
【问题描述】:

我目前有这个 JSON 文件,它记录用户对给定问题的回答,并根据回答进行一些计算。当我在前端工作时,使用 json 更方便。用户名和密码系统没有任何安全性,仅供测试。现在我正在尝试使用更安全的用户帐户系统构建 mySQL 数据库,但我似乎无法找到一种方法来构建与此文件执行相同操作的表。

{ 
"username" : "a6",
"password" : "password", 
"joined" : 1621995190170,
"progress" : [
   { 
      "Question ID" : "00001", 
      "Question" : "-----",
      "SetAnswer" : "xxxxx", 
      "Recorded" : "yyyyy", 
      "Score" : 945, 
      "AttemptedAt" : 1611682870221, 
      "Factor" : 4,
      "AttemptAgain" : 1617014020591
   }, 
   { 
      "Question ID" : "00002", 
      "Question" : "-----",
      "SetAnswer" : "xxxxx", 
      "Recorded" : "yyyyy", 
      "Score" : 945, 
      "AttemptedAt" : 1611682870254, 
      "Factor" : 4,
      "AttemptAgain" : 1617014020564
   }, 
   { 
      "Question ID" : "00003", 
      "Question" : "-----",
      "SetAnswer" : "xxxxx", 
      "Recorded" : "yyyyy", 
      "Score" : 945, 
      "AttemptedAt" : 1611682870254, 
      "Factor" : 4,
      "AttemptAgain" : 1617014020564
   }...
(it goes on for 10,000+ entries)

我遇到的问题是每个用户的每个问题都需要记录很多东西,为每个用户制作一个表格将是一个非常糟糕的主意。任何有关设计 SQL 数据库的帮助将不胜感激。

【问题讨论】:

  • 您是否尝试过创建一个包含“question id”、“question”、“setanswer”、“recorded”、“score”、“attemptedat”、“factor”、“attemptagain”列的表格?
  • 同意 mkrieger1。创建一个“用户”表,获取用户的“id”并将其链接到问题表并根据信息插入条目。
  • @mkrieger1 是的,我想到了,但是每个用户 12000 行会使该表的行数过高,对吧?我一直认为更高的行数(大约 10 万或数百万)会影响效率,不是吗?
  • @Achs98:如果您获得“很多”记录,这取决于用户数量,但是您需要很多用户才能“太高”。顺便说一句,“太高了”有多高?

标签: mysql json database-design


【解决方案1】:

欢迎来到entity-relationship data design 的世界。你有三个实体

  • 用户
  • 问题
  • 回答

每个实体都有自己的表。

您的实体具有这些关系。

  • 每个用户可以有零个或多个答案。所以你的答案表需要一个user_id 列。
  • 每个问题也可以有零个或多个答案。所以你的答案表也需要一个question_id 列。

从您的 Javascript 对象示例中,我得到了这三个表定义。

CREATE OR REPLACE TABLE user (
  user_id         BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  username        VARCHAR(255) NOT NULL,
  hashed_password VARCHAR(255) NOT NULL,
  joined          TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (user_id)
)
COLLATE='utf8mb4_general_ci';

CREATE OR REPLACE TABLE question (
  question_id     BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  question        VARCHAR(1000),
  set_answer      VARCHAR(1000),
  factor          FLOAT NOT NULL DEFAULT 1.0,
  PRIMARY KEY (question_id)
)
COLLATE='utf8mb4_general_ci';

CREATE OR REPLACE TABLE answer (
  answer_id       BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  user_id         BIGINT UNSIGNED NOT NULL,
  question_id     BIGINT UNSIGNED NOT NULL,
  recorded_answer VARCHAR(1000),
  score           FLOAT,
  attempted       TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  attemted_again  TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (answer_id)
)
COLLATE='utf8mb4_general_ci';

填充这些表后,您可以通过这样的查询获得与示例类似的结果集。

SELECT user.user_id, user.username, user.joined,
       question.question_id, question.question, 
       question.set_answer, question.factor,
       answer.recorded_answer, answer.score, 
       answer.attempted, answer.attempted_again
  FROM user
  LEFT JOIN answer   ON user.user_id = answer.user_id
  JOIN question ON answer.question_id = question.question_id

这就是发生的事情。

  • user_idquestion_idanswer_id 数字唯一标识每个用户、问题和答案。
  • SELECT 子句枚举您想要的数据。
  • FROM 子句表示您需要逐个用户的结果。
  • LEFT JOIN 子句实现了用户可以有零个或多个答案的关系。您可以将answer.user_id 视为指向用户。
  • JOIN 子句实现了关系,说明每个分析器必须有一个问题。 question_id 指向问题。

顺便说一下,包括 MySQL 在内的 SQL 数据库系统可以毫不费力地处理各种表中的数百万行,所以不用担心。 (当表变得那么大时,您可能需要添加索引,但这是在您使应用程序正常工作之后。)

【讨论】:

  • 哇,非常感谢,非常感谢!
  • 不客气。提前付款!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-11
  • 2020-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-20
  • 2017-11-17
相关资源
最近更新 更多