2011-11-21 50 views
0

我正在为一个flashcards应用程序设计一个MySQL数据库。我有一张名为“课程”的表格,我在那里保存课程的ID,名称和说明以及一张名为“物品”的表格,我在这里保留了所有的抽认卡。表格项目保存唯一的ID,课程ID以及问题,答案和更多详细信息。还有一张名为重复的表格,我在那里存储用户记忆的闪卡的数据。如果我想得到一个用户还没有记忆的flashcard,我使用LEFT JOIN查询数据库,以便从闪存卡中获取所有数据,并从重复的行中获取所有数据。但是,我必须指定何去何从一定的烧录卡所属的,所以我的查询看起来更Ø多少有点像:我应该为flashcards应用使用单独的表吗?

SELECT * 
    FROM (SELECT * 
       FROM flashcards 
       WHERE course='coursename') AS flashcards 
     LEFT JOIN repetitions 
      ON flashcards.id=repetitions.flashcardid 
    WHERE repetitions.lastrepetition IS NULL 
    LIMIT 1; 

它会更好有各门课程separare表,这样我就不必指定我的意思是什么?这会加快数据库吗?不会有很多课程(约10-20),每门课程将包含大约5k-10k的卡片。

对不起,我忘了说,如果用户没有记忆闪卡,那么在表重复中就不会有任何等价的记录。我实际做的是: 1.我选择所有的flashards在哪里coursename ='coursename', 2.我选择所有重复WHERE用户='用户'和coursename ='coursname, 3.然后我左加入记录第一个表与第二个表中的记录。我从某个过程中获得所有的flashcards,其中一些记录在重复表中有相应的等效形式, 4.然后我使用WHERE重复为NULL,并且我只获得那些在重复表中没有其等价物的flashcards。

SELECT * FROM 
    (SELECT * FROM flashcards WHERE course='coursename') AS f 
    LEFT JOIN 
    (SELECT * FROM repetitions WHERE user='user' AND course='coursename') AS r 
    ON f.id=r.flashcardid 
    WHERE repetitions IS NULL LIMIT 1) 

上述查询工作正常,但我不知道它是否不会需要太多的RAM /内存,如果有更多的人使用的应用程序。

我有atm唯一更好的解决方案是从flashcards表中只选择id并将LIMIT设置为用户的限制(假设每个会话有30个flashcards)。然后,而不是30次,我将只使用此查询一次。我可以在GET变量中传递这些id。 (这个解决方案的唯一问题是,如果用户在他的PC上研究闪存卡,然后移动到手机并忘记关闭PC的会话并返回到个人电脑,一些重复可能会被覆盖。无论如何,这将是一个非常罕见的情况,但仍有可能)。


感谢您的帮助!你的建议实际上是正确的。我刚才发现我犯了一个错误 - 在我最初的查询中,我不必要地添加了'WHERE repetitions.course ='coursename'的情况。 但是,我仍然必须使用右括号来确定用户。

SELECT * FROM flashcards AS f 
LEFT JOIN (SELECT * FROM repetitions WHERE user='username') AS r 
ON f.id=r.flashcardid 
WHERE f.course='coursename' AND r IS NULL 

回答

0

你不应该把课程分成自己的表格。

难道你不能这样做吗?

select * from flashcards 
left join repititions 
    on flashcards.id = repititions.flashcardid 
where course = 'coursename' 
and repititions.lastrepitition is null 
limit 1 
0

我看不出有任何理由为每门课程添加单独表的开销和麻烦。另外,不需要该子查询。您的查询可写为:

SELECT * 
    FROM flashcards f 
     LEFT JOIN repetitions r 
      ON f.id = r.flashcardid 
    WHERE f.course = 'coursename' 
     AND r.lastrepetition IS NULL 
    LIMIT 1; 
+0

嗨!感谢您的回答。不幸的是,这个查询不起作用。如果用户还没有研究过flashcard,那么在右表中就不会有任何记录,并且如果我在两个表上都使用WHERE,我将不会从左表中获取所有记录,但只有那些具有其等价物的记录在右边的表格中。 – lukeshek

+0

我用这个查询ATM: 选择items.id,items.question,items.answer FROM(SELECT ID,问题,回答的项目WHERE courseid = '$ courseid')AS LEFT JOIN项目(SELECT itemid的FROM重复其中userid = '$用户ID' AND courseid = '$ courseid')AS重复ON items.id = repetitions.itemid WHERE repetitions.itemid IS NULL LIMIT 1 – lukeshek

+0

我不知道,也许这将是更好的,如果我有两个表中的记录等同?但是,如果我添加一个新的flashcard到一个拥有3k用户的课程中,我必须确保每个用户在右表中有一个单独的等价物,所以我会在左边添加一个记录表和3K记录到右表... 我不确定括号内的查询会发生什么情况? MySQL是否必须为这些记录创建一个临时表? – lukeshek