哪种方法最适合在mysql中存储以后将用于统计的单词列表?

时间:2013-04-24 08:11:49

标签: php mysql database

详情

我有一个测验(我们称之为测验1)。 Quiz1每次生成时都使用相同的词表。 如果用户需要,他们可以跳过单词来完成测验。我想将这些跳过的单词存储在mysql中,然后再对它们进行统计。

起初我打算将错过的单词作为字符串存储在一列中。每个单词都用逗号分隔。

|testid |       missedwords                     | score     |   userid  |
*************************************************************************
| quiz1 | wordlist,missed,skipped,words         |  59       |   1       |
| quiz2 | different,quiz,list                   |  65       |   1       |

这种方法的问题在于,我希望在每个测验结束时显示统计数据,这些统计信息包含了参加quiz1的用户最常错过的单词。
我假设如上所述将错过的单词存储在一列中对于此目的而言是低效的,因为我需要提取信息然后计算它 - (可能使用php计算 - 除非我将计算的数据存储在单独的表中)。

然后我想也许我需要为遗漏的单词创建一个单独的表 下表的优点是可以很容易地计算下表中的单词。

|Instance|  missed word     |
*****************************
|   1    |  wordlist        |
|   1    |  missed          |
|   1    |  skipped         |

另一种方法 我可以用计数器创建一个表,并在每次进行quiz1时更新它。

Testid  |   wordlist|   missed| skipped| otherword|
**************************************************
Quiz1   |        1  |        1|       1| 0        |

这种方法的问题在于我需要为每个测验使用不同的表格,因为每个测验都会使用不同的单词。此外,信息也会丢失,因为只保留了相关数据,而不是用户错过哪些相关数据。

问题

您会使用哪种方法?为什么?欢迎使用替代方法来完成这项任务。如果您发现我的逻辑中存在任何缺陷,请随时指出它们。

修改 用户可以根据自己的喜好重复测验。他们的信息不会更新,而是为他们重新开始的每个测验创建一个新实例。

5 个答案:

答案 0 :(得分:3)

执行此操作的最佳方法是将单词集合完全标准化。这样,分析将变得简单快捷。

quiz_words with wordID, word
quiz_skipped_words with quizID, userID, wordID

获取用户的所有跳过单词:

SELECT wordID, word 
FROM quiz_words 
JOIN quiz_skipped_words USING (wordID) 
WHERE userID = ?;

您可以添加group by子句以使组计数相同。

获取特定单词的计数:

SELECT COUNT(*) 
FROM quiz_words 
WHERE word LIKE '?';

答案 1 :(得分:1)

根据database normalization theory,第二种方法更好,因为理想情况下,一个关系表单元格应该只存储一个值,即原子和不可分离的值。每个单词都是一个实体实例。

另外,我可能建议不要创建Quiz-Word表,但是在Missed-Word表中保留另一列用于测验,为此指定了该单词,然后将此列用作{{{1}的外键。 1}}表。那么你可能会避免实时表生成(这是数据库设计中的“不良做法”)。

答案 2 :(得分:1)

为什么没有测验表和quiz_words表,quiz_words表会存储id,quizID,word作为列。然后,对于每个测验实例,在quiz_words表中为用户使用的每个单词创建记录。

然后你可以根据quizID和/或测验类型在quiz_words表上运行mysql计数

答案 3 :(得分:1)

最佳解决方案(来自我的pov)你想要达到的目标是标准化的方法:

  • test表格,其中包含test_id列和其他列
  • missed_words表格中有id(AI PK)和word(UQ),此处您还可以拥有hits列,每列都应增加在test_missed_words中与此单词建立关联的时间,这样您就可以获得已编译的统计数据,并且不需要从选择查询中计算它们
  • test_missed_words这是一个包含test_idmissed_word_id(复合PK)的链接表

这样您就没有冗余数据(遗漏的单词),您可以轻松提取您想要的统计数据

答案 4 :(得分:1)

保留尽可能多的信息(并且能够在以后编译用户特定的统计数据以及现在的整体统计数据)我将创建一个类似于以下的表结构:

                  Stats
quizId  |   userId  |     type|    wordId|
******************************************
1       |        1  |   missed|         4|
1       |        1  |  skipped|         7|

type可以是定义不同类型操作的int,也可以是字符串表示 - 取决于您是否相信它可以更多。 ^^

然后:

     Quizzes
quizId  |  quizName|
********************
       1|    Quiz 1|

为每个测验制作单词列表,如:

     WordList (pk: wordId)
quizId  |   wordId|   word|
***************************
      1 |       1 |    Cat|
      1 |       2 |    Dog|

您可以随心所欲地使用user表格,我们只是将id表格链接到此系统。

这样,id表中的所有stats字段都将是非唯一键。当用户跳过或错过某个字词时,您可以将该字词id与相关的statsquizId一起添加到type表格中。以这种方式获取统计信息可以轻松实现per-userper-wordper-type基础 - 或三者的组合。它还可以使每个测验的单词列表轻松可用于进行测验。 ^^

希望这有帮助!