请教一个有关索引的问题(高分送出)
两个有关学生成绩的表
A.学生成绩表
考试编码 年级编码 班级编码 学号编码 成绩 班排名 年排名 ...
-------------------------
B.学生总成绩表
考试编码 年级编码 班级编码 学号编码 总成绩 班排名 年排名 ...
--------------------------
要求:
1.每个年级的每次考试成绩记录数大约为1万条(行),基本上在一次输入后,不会轻易修改数据;
2.在成绩输入完成后,要对班排名/年排名,以及总成绩的班排名/年排名进行计算汇总;
3.A表可能在一定情况下会要求取总成绩的班排名或年排名,也就是说A表要与B表关联
需求:
因为成绩表和总成绩表的数据量会很大,如何对两个表设计索引,提高对成绩和总成绩的查询/更新/插入操作速度...
[解决办法]
关注
[解决办法]
貌似很难同时提高查询修改,插入等操作的吧,建立索引的同时就降低了插入的效率...
[解决办法]
关注,学习.
[解决办法]
是呀,我也想知道,难道这里没人会??
[解决办法]
学习
[解决办法]
在大型数据库,索引是为了加快查询速度.
通常用对where做条件的列,建立索引
[解决办法]
A.学生成绩表
考试编码 年级编码 班级编码 学号编码 成绩 班排名 年排名 ...
-------------------------
B.学生总成绩表
考试编码 年级编码 班级编码 学号编码 总成绩 班排名 年排名 ...
--------------------------
先不说搂主讨论的索引问题,揣测一下数据表的结构吧:
A表--
考试编码 ,估计用于区别考试科目了,不知道1年级考的数学和2年级考的数学编码是否一样,那么上学期和下学期考数学是否一样?还是同一年级同一科目都是一个编码? 还是将考试编码设计成复合的,比如‘2005A3SX’2005年上学期3年级数学科目考试?
年级编码 ,估计区别同一个学生同一科目在不同年级时候的不同成绩吧,调取历史考试成绩应该游泳。也为年排名准备筛选条件了。
班级编码 ,区别不同的班级了
学号编码 ,
成绩 ,
班排名 ,???这个很有问题啊,按这样的结构,搂主的系统应该这样维护数据:增加、删除、修改一条记录的时候,遍历所有同一个班级的同一个考试编号 的同一个年级编号的所有记录,去修改遍历过的记录的当前字段 hoho
年排名 ,???这个比上面的还狠,按这样的结构,搂主的系统应该这样维护数据:增加、删除、修改一条记录的时候,遍历所有同一个年级的同一个考试编号 的所有记录,去修改遍历过的记录的当前字段 hoho hoho
另外修改(增、删) A 表中的任意一条记录,都要维护 B 表中的所有相关记录!!
不如这样:
A学生成绩
年度 , 级 , 班 , 科目 ,考试编号 ,学生(编号),成绩
---------------------------
2005年 3年级 2班 数学 第1次考试 001学生 120分
其实从整个系统考虑的话可能也不是这样,就说学生编号,至少能分辨出哪一年入学的吧,或还有其它信息,那有些机构又可以调整。
B表?! 还是用几个视图吧,SQL Server 几万条记录应该不会有多慢的。
总之,先把表结构设计好,才好讨论其它的。
[解决办法]
简单分析一下A表,考试编码 年级编码 班级编码 学号编码 成绩 班排名 年排名
其中年级编码 班级编码 学号编码属于学生的个人信息,而其余字段为每次考试所有考试科目的明细,两者应该是属于master-detail的关系。个人认为不应该这样设计。
[解决办法]
友情帮顶一下:)
[解决办法]
早上來幫你頂一下,
索引這塊我也比較模糊,幫不上忙了
[解决办法]
我记得微软书本上说过:
--------------------------
索引可以提高查询的速度
但是会降低插入、更新的速度
------------------------------------------------
lz要同时实现查询、更新和插入的功能,我还是学习了
[解决办法]
up,楼上的观点是正确的
[解决办法]
1> 建议这样设计,
设计一:
A表作为基础数据表,去掉B表
B表的数据由A表统计出来,几W数据优化查询和建立了索引,是很快的
可以专门写一个存储过程来统计.
设计二:
A表作为基础数据表,B表作为汇总表
B表数据由A表汇总,这个可以通过写一个存储过程,讲A表的数据汇总再插入B表
因为lZ说A表数据insert后基本很少去修改,
但是A表数据修改后,就不得不重新汇总B表了,这个是一个问题哟!
[如果是Oracle就好了,物化视图就是解决这个问题的好东西!!]
2> 关于索引
的确索引会降低插入,更新的数据,但是对查询带来的好处是远远大于对修改,插入的降低.
而且对插入,更新的速度降低也是非常小的.
[解决办法]
(一)深入浅出理解索引结构
实际上,您可以把索引理解为一种特殊的目录。微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(nonclustered index,也称非聚类索引、非簇集索引)。下面,我们举例来说明一下聚集索引和非聚集索引的区别:
其实,我们的汉语字典的正文本身就是一个聚集索引。比如,我们要查“安”字,就会很自然地翻开字典的前几页,因为“安”的拼音是“an”,而按照拼音排序汉字的字典是以英文字母“a”开头并以“z”结尾的,那么“安”字就自然地排在字典的前部。如果您翻完了所有以“a”开头的部分仍然找不到这个字,那么就说明您的字典中没有这个字;同样的,如果查“张”字,那您也会将您的字典翻到最后部分,因为“张”的拼音是“zhang”。也就是说,字典的正文部分本身就是一个目录,您不需要再去查其他目录来找到您需要找的内容。
我们把这种正文内容本身就是一种按照一定规则排列的目录称为“聚集索引”。
如果您认识某个字,您可以快速地从自动中查到这个字。但您也可能会遇到您不认识的字,不知道它的发音,这时候,您就不能按照刚才的方法找到您要查的字,而需要去根据“偏旁部首”查到您要找的字,然后根据这个字后的页码直接翻到某页来找到您要找的字。但您结合“部首目录”和“检字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“张”字,我们可以看到在查部首之后的检字表中“张”的页码是672页,检字表中“张”的上面是“驰”字,但页码却是63页,“张”的下面是“弩”字,页面是390页。很显然,这些字并不是真正的分别位于“张”字的上下方,现在您看到的连续的“驰、张、弩”三字实际上就是他们在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我们可以通过这种方式来找到您所需要的字,但它需要两个过程,先找到目录中的结果,然后再翻到您所需要的页码。
我们把这种目录纯粹是目录,正文纯粹是正文的排序方式称为“非聚集索引”。
通过以上例子,我们可以理解到什么是“聚集索引”和“非聚集索引”。
进一步引申一下,我们可以很容易的理解:每个表只能有一个聚集索引,因为目录只能按照一种方法进行排序。
(二)何时使用聚集索引或非聚集索引
下面的表总结了何时使用聚集索引或非聚集索引(很重要)。
动作描述 使用聚集索引 使用非聚集索引
列经常被分组排序 应 应
返回某范围内的数据 应 不应
一个或极少不同值 不应 不应
小数目的不同值 应 不应
大数目的不同值 不应 应
频繁更新的列 不应 应
外键列 应 应
主键列 应 应
频繁修改索引列 不应 应
事实上,我们可以通过前面聚集索引和非聚集索引的定义的例子来理解上表。如:返回某范围内的数据一项。比如您的某个表有一个时间列,恰好您把聚合索引建立在了该列,这时您查询2004年1月1日至2004年10月1日之间的全部数据时,这个速度就将是很快的,因为您的这本字典正文是按日期进行排序的,聚类索引只需要找到要检索的所有数据中的开头和结尾数据即可;而不像非聚集索引,必须先查到目录中查到每一项数据对应的页码,然后再根据页码查到具体内容。
[解决办法]
表结构设计的有问题
昨晚上看到聚簇索引和唯一聚簇索引2个概念,不知道有什么不同,呆会发帖子问一下
[解决办法]
A表可以按考试编码,年级编码,班级编码,成绩 建立联合索引
B表可以按考试编码,年级编码,班级编码,总成绩 建立联合索引
索引的顺序为上面的先后顺序
[解决办法]
结合表结构,加些实例数据.会更清楚点.