数据库02:数据库基础操作

关系数据库01

关系指代,元组指代,属性指代。元组是一组值的序列。

超码(superkey)是一个或多个属性的集合。超码可以使在一个关系中唯一地标识一个元组。超码的任意超集也是超码,候选码是最小超码。

主码(primary key)代表被选中的、主要用来在一个关系中区分不同元组的候选码。

一个关系模式(r1)可能在它的属性中包括另一个关系模式(r2)的主码。这个属性在r1上被称为参照r2的外码。r1也称外码依赖的参照关系。

以后会用到的关系

  • department(dept_name, building, budget)
  • course(course_id, title, dept_name, credits)
  • student(ID, name, dept_name, tot_cred)
  • advisor(s_id, i_id)
  • takes(ID, course_id, sec_id, semester, year, grade)
  • classroom(building, room_number, capacity)
  • time_slot(time_slot_id, day, start_time, end_time)

SQL查询语言

基本类型(域)

  • char(n):长度n,长度不够会追加空格
  • varchar(n):可变长度字符串,最大长度n
  • int
  • smallint
  • numeric(p,d):定点数,精度由用户指定,共p位数字(加上符号位),d位小数点后精度--numeric(3,1)只能存储44.5,不能存储444.5
  • real, double precision:浮点数和双精度浮点数
  • float(n):精度至少为n的浮点数

create table命令:

create table r
    (A1 D1,
    A2 D2,
    ...
    An Dn,
    <完整性约束1>,
    ...
    <完整性约束k>);

注意使用分号结束。

完整性约束:

  • primary key(A1,A2,...)
  • foreign key(A1,A2,...) references: 给定属性上的取值必须对应于关系s中某元组在主码属性上的取值
  • not null:在该属性上不允许空值
create table teachers
    (ID     varchar(5),
    course_id   varchar(8),
    sec_id      varchar(8),
    semester    varchar(6),
    year        numeric(4,0),
    primary key (ID, course_id, sec_id, semester, year),
    foreign key (course_id, sec_id, semester, year) references sections,
    foreign key (ID) references instructor);

新创建的关系是空的,使用insert插入。

insert into instructor
    values (10211, 'Smith', 'Biology', 66000);

delete删除元组

delete from student;

drop table删除关系

drop table r; --删除被去掉关系的所有信息
delete from r; --保留关系r,删除r中所有元组

alter table:给r添加列A,属性的域为D

alter table r add A D;
alter table r drop A;

SQL查询基本结构由select、from和where组成

  • select列出需要查询的列
  • from是需要访问的关系表
  • where是from子句中的限定
  • 运算顺序为:from、where、select

1. 单关系查询

select name
from instructor
where dept_name = 'Comp.Sci.' and salary > 70000;

在select后面可以加distinct去除重复,加all显示指明不去重

2. 多关系查询

-- dept_name出现在 instructor和 department中
select name, instructor.dept_name, building
from instructor, department
where instructor.dept_name = department.dept_name;

3. 自然连接

自然连接运算作用两个表并产生一个表作为结果。

自然连接选出同名属性中相等的元组,进行投影去重组合,或者说外连接

select name, course_id
from instructor, teaches
where instructor.ID = teaches.ID;
-- 可以写成
select name, course_id
from instructor natural join teaches;
-- instructor和teaches在共同属性ID上的取值相同,且只有ID

需要注意的是,自然连接多个表时,需要同时满足多个表中的属性都相等

select name, title
from instructor natural join teaches natural join course;

在instructor和teaches的自然连接结果,他们自然连接的结果会导致属性的增加,再与course进行自然连接时,会需要在两个属性(dept_name, course_id)上取值相同,而下面这种形式则不一样

select name, title
from instructor natural join teaches, course
where teaches.course_id = course.course_id;

这种情况会先计算instructor和teaches根据ID属性的自然连接,然后将自然连接的结果与course_id相匹配。所以,用户可以指定需要哪些列相等:

select name, title
from (instructor natural join teaches ) join course using (course_id);

其他运算

  • 更名运算(old-name as new-name)
--改变输出的属性名
select name as instructor_name, course_id
from instructor, teaches
where instructor.ID = teaches.ID;
--改变关系名
select T.name, S.course_id
from instructor as T, teaches as S
where T.ID = S.ID;
  • 字符串运算

SQL对大小写敏感(在MySQL和SQL Server中不区分大小写)

函数upper(大写),lower(小写),trim(去空格)

使用like实现字符串模式匹配:
1.(%):匹配任意字符串。2.(_):匹配任意一个字符。

select dept_name
from department
where building like '%Watson%';
--找出建筑名中包含'Watson'的系名
--也可以在like后使用escape定义转义字符
--like 'ab \% cd%' escape '\'
  • 排序
--order by默认圣墟
select *
from instructor
order by salary dese, name asc;
  • where子句谓词
where salary between 90000 and 100000;
where (instructor.ID, dept_name) = (teaches.ID, 'Biology');

集合运算

使用union、intersect、except对关系进行并、交、差运算。

  • 三种操作均自带去重,保留重复则在后面加all(union all)

SQL中涉及到空值的运算均为 unknown

  • 1<null 为unknown
  • true and unknown 为unknown
  • false and unknown 为false
  • 如果where计算结果为false或unknown,则不能加入到结果

聚集函数

  • avg,min,max,sum,count
  • group by:分组聚集,group by指定属性相同的为一组。
  • having:针对group by中构成的分组
  • 如果出现了where,则只应用在from的结果关系上
  • 如果出现了group by, 满足where的元组通过group by分组
  • 如果出现了having, 将应用到每个分组
  • 对空值的聚集操作,会忽略空值
select course_id, semester, year, sec_id, ave(tot_cred)
from takes natural join student
where year = 2009
group by course_id, semester, year, sec_id
having count(ID) >= 2;
-- 查询对于2009年的每个课程段,如果该课程段有至少两名同学选课,找出选修该课程段的所有学生的总学分的平均值

嵌套子查询

一个select-from-where子查询嵌套在另一个查询where语句中

select distinct course_id
from section
where semester = 'Fall' and year = 2009 and
   course_id in ( select course_id
                   from section
                   where semester = 'Spring' and year = 2010);
-- 找出在2009年秋和2010年春同时开课的所有课程,另一种方式是使用intersect

1.集合的比较

1.1比较时可以使用some和all

  • some:至少比某一个大(>some)
  • all:大于全部(>all)

1.2测试子查询中是否存在元组

  • exists:子句的返回值是bool值
--找出选修了biology系开设的所有课程的学生
--not exists(B except A):关系A包含关系B
select S.ID, S.name
from student as S
where not exists((select course_id
                    from course
                    where dept_name = 'Biology')
                    except(
                        select T.course_id
                        from takes as T
                        where S.ID = T.ID));

in、not in和exists、not exists的区别:

  • exists后面一般都是子查询,当子查询返回行数时,exists返回true
  • in的查询效率高于exists,in后面的查询是返回结果集的
  • 执行顺序:exists先执行外部查询,外部查询每一行进行子查询;in先执行子查询返回结果集
  • not in 只有当子查询中,select后的字段有not null时用not in
  • not in 的执行顺序是查询每条记录,not exists是根据索引查询,不会按条查询
  • not exists查询效率高于not in
--当表中cid存在null值,not in 不对空值进行处理
select * from class
where cid not in
(select distinct cid from stu where cid is not null)
--查询那些班级中没有学生的
select * from class2
where not exists
(select * from stu1 where stu1.cid = class2.cid)

3.使用unique查询是否存在重复元素

  • unique可以在创建表时使用,限制重复

4.with子句提供临时定义关系的方法

--定义max_budget,找出具有最大预算值的系
with max_budget(value) as
    (select max(budget)
    from department)
select budget
from department, max_budget
where department, budget = max_budget.value;

2.数据库的修改

2.1删除

delete from r
where P;

2.2插入

--让Music系修满144学分的学生成为Music系的教师
insert into instructor
select ID, name, dept_name, 18000
from student
where dept_name = 'Music' and tot_cred > 144;

2.3更新

--update 表 set 列 = 新值 where 列名称 = 某值
update instructor
set salary = case
            when salary <= 100000 then salary * 1.05
            else salary * 1.03
        end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容