我在实际运用中,一对多是这样建的。学生表:
学生id  学生姓名
1        张三
2        李四考试表
自增ID  学生id  学科
1        1       语文
2        1       数学
3        2       语文
4        2       英语 
‘考试表’存储了‘学生表’的多条记录。我这样建立合理不合理呢?这样建合,我后面会产生二个问题,感觉不是很方便,大家有什么好的方式可以解决后面的这二个问题呢?
这二个表中的数据可能是上百万哦!
问题1:
在查询‘考试表’中考了语文和数学的学生姓名列出来。
我与的SQL是可以查询出来,不过效率不行,感觉这样建表是不是就是引起的这个查询问题呢?问题2:
我这样建立一对多的方式是不是有问题?大家建立一对多是加了‘关系映射表’ 吗?有什么好处呢?

解决方案 »

  1.   


    1、
    假如我要查询 ‘哪个学生考了语文和数学’的。
    SELECT *,SUM(a.学生id) AS c FROM 学生表 a  
    LEFT JOIN 考试表 b1 ON b1.学生id = a.学生id
    LEFT JOIN 考试表 b2 ON b2.学生id = a.学生id 
    WHERE b1.学科 = '语文' AND b2.学科='数学'
    GROUP BY a.学生id 
    HAVING c >=2 或
    SELECT *,SUM(a.学生id) AS c FROM 学生表 a  
    LEFT JOIN 考试表 b ON  b.学生id = a.学生id 
    WHERE b.学科 IN('语文','数学') 
    GROUP BY a.学生id 这里还不包括排序。所以速度上会很慢。
      

  2.   

    看你有什么需求了,你的1对多也没什么问题
    但是如果数据很多的情况下,还是有数据冗余的。
    比如有1万学生考了语文,那么你的考试表
    自增ID 学生id 学科
    1 1 语文
    2 2 语文
    3,3 语文
    。。还有比如每个学生考了20科,一共有1万学生
    对每个学生而言 考试表
    自增ID 学生id 学科
    1 1 语文
    2 1 数学
    3,1 英语
    ........
    直到1万学生完你可以用另外一种方案
    学生表:
    学生id(主键) 学生姓名
    1 张三
    2 李四
    考试表
    考试id(主键) 学科
    1  语文
    2  数学
    3  英语这连个表中的数据不会有冗余,然后建立一个多对多的关系
    学生id  和考试id  作为联合主键和外键,这样数据冗余会小很多。
    问题一的伪代码
    select sname from student where sid in( select sid from multi-to-multi jion exam where ename=“语文” or ename="数学");
      

  3.   

    合理。符合范式要求。(虽然有些时候,会用课程ID来代码具体的名称,但这并不违反范式)考试表
    自增ID  学生id  学科   时间  成绩
    1        1       语文  201102  50 
    2        1       数学  201102  90 
    3        2       语文
    4        2       英语 
    5        1       语文  201109  75
      

  4.   

    你的语句是什么? 
    楼上已经有人写出了。写出你的语句,且贴出 explain select ..,   show index from ... 
    你需要添加适当的索引。