教科书敢深入浅出点儿吗?

今天看萨师煊萨教授的《数据库系统概论》,头晕目眩。

一个关系通常是由赋予它的元组语义来确定的。元组语义实质上是一个n目谓词(n是属性集中属性的个数)。凡是该n目谓词为真的笛卡儿积中的元素(或者说凡符合元组语义的那部分元素)的全体构成了该关系模式的关系。

有谁能在读了一遍以后顺利地在脑海中反映出来这段话在说什么?我读了N遍,前前后后地翻术语定义,总算明白原来他要说的就是表结构和表中的数据。

联想到前段时间看Tom KyteEffective Oracle By Design,里面用引水机和需要喝水的人这样的比喻来阐述Free Lists以及Freelist Groups的关系,用在一个大房间里挑选配对跳舞的男孩儿女孩儿来比喻Nested Loop Join和Sort Merge Join,即使人家那是英语,看完一遍以后也会有心中透亮的感觉。

要说这教材和Tom的书定位不同,不能比较也不能苛求,象元组语义,n目谓词这种令人发指的词汇是作为一个教材必须要阐述的知识,但是难道就不能在叽里咕噜了这些之后多加个个深入浅出,浅显易懂的比喻或者解释?

总是觉得某些教科书一派术语的堆砌,冗长乏味,毫无生机,打开翻翻就满脑袋汗,翻到这章不想看是翻到那章也不想看,按照老罗的说法叫“装B”。或许因为这本《数据库系统概论》的抬头写着“面向21世纪课程教材”,所以才格外显得高科技吧。

当然看这本书也并非无所得,下面出个题目,有兴趣的可以先想一想再看答案。

一张表SC,两个字段,SNO和CNO,SNO表示学生学号,CNO表示学生选修的课程编号。表结构和数据构成通过下面的SQL生成。

create table sc (sno number,cno number);
insert into sc values(1000,1);
insert into sc values(1000,2);
insert into sc values(1000,3);
insert into sc values(1001,2);
insert into sc values(1001,3);
insert into sc values(1002,2);
insert into sc values(1002,3);
insert into sc values(1003,3);
commit;

要求通过一条SQL语句求出所有至少选了1002学生所选的全部课程的学生。也就是结果要出来1000和1001这两条记录。

答案在下面,告诉我们一个反向思考的方法,比较有趣。

select distinct sno
from sc scx
where not exists (select *
from sc scy
where scy.sno = 1002
and not exists (select *
from sc scz
where scz.sno = scx.sno
and scz.cno = scy.cno))
and scx.sno <> 1002;