数据库

244 阅读5分钟

关系模型概念

关系是对表的一种关系描述,关系里面元组不可重复但是表可以

关系中行的顺序,列的顺序可以调换

每个列的类型是一致的,要么是整形或者别的

第一范式

属性不可再分,叫做关系的第一范式

下边的图其中的某些字段(属性)可以再分解所以不符合第一范式

候选码(候选键)

关系模型中(Table表)某属性组可以区分或者标识元组。就是说哪个或者哪几个属性可以唯一的标识元组呢?

例如学生的关系靠学号,用姓名不行(重名),同理生日其他都不行

候选码可以有多个

主键

有多个候选码时选择一个作为主键

外键

关系 R 的一个属性组,它不是R的候选码但是它与另外一个关系 S 的候选码对应

两个关系通过外键联系起来,合同表的客户号是另一个表的主键,所以客户号是外键

关系模型操作

并运算

要满足并相容性,两个关系的域要相同,也就是说属性数目相同,属性类型和取值相同才可以做并集

运算结果需要去掉重复值

差运算

需要并相容性,表示出现在某一关系不在另一关系的集合

广义积运算

就是把所有可能的组合列出来

选择操作

选择某行

投影操作

从某种关系里选取某些列组成新的关系

theta连接操作

在两个关系的笛卡尔积里面选取某些特定关系的元组

连接操作很快尽量用

自然连接

从在两个关系R,S的笛卡尔积中选与另一个关系B里相同属性组,也就是笛卡尔积里面一定有某些元组和B一样的

是一种特殊的等值连接

SQL语言(1)

DDL数据定义语言,CREATE DTABASE

DML数据操纵语言, INSERT DELETE UPDATE SELECT等

sql是DDL,DML,DCL(数据控制语言)一体的语言

DDL:CREATE建立,ALTER修改,DROP撤销

DML:INSERT,DELETE,UPDATE,SELECT

DCL:GRANT, REVOKE

定义数据库

先建立数据库

CREATE DATABASE 数据库名

再建立表

CREATE TABLE 表名(
列名 列数据类型 [主键 | 候选键][not null],
...
)

数据类型

  • char固定长字符串
  • varchar可变长字符串
  • int整
  • real浮点数
  • data日期
  • ...

示例:定义学生表

CREATE TABLE Student(
SId char(8) not null,
Sname char(10),
Ssex char(2)
)

表中追加元组

需要用到DML语言

INSERT INTO 表名[
列名,
列名,
...
]
VALUES(
值,
值,
...
)

值和列需要对应

示例:追加学生表

INSERT INTO Student
VALUES('434210','张三''男')
值按照表默认顺序

简单查询

语法:

SELECT 列名...
FROM 表名...
WHERE 条件

示例:

检索所有学生信息
SELECT * 
FROM Student

检索学生姓名和性别
SELETC Sname,Ssex
FROM Student

检索表中年龄小于等于19岁的学生的姓名和年龄
SELECT Sname,Sage
FROM Student
WHERE Sage<=19

结果排序

在后面加
ORDER BY 列名 [ASC | DESC]

模糊查询

  • % 匹配0个或者多个字符
  • _ 匹配单个字符
  • \ 转义字符用于去掉特殊字符的含义

示例:检索所有姓张的学生

SELECT Sname
FROM Student😊
WHERE Sname LIKE '张%'

多表联合查询

通过连接运算完成

语法:

SELECT 若干列名
FROM 若干表名
WHERE 条件

示例:按照001号课的成绩高到底显示学生姓名

SELECT Sname
FROM Student,SC
WHERE Student.S_Id = SC.C_Id AND SC.C_Id = '001'
ORDER BY Score DESC

表名.属性名 来限定

表的重命名

SELECT 列名 AS 列别名
FROM 表明 AS 表别名
WHERE 条件

示例:求有薪水差额的任意两位教师

SELECT T1.Tname as Teacher1,T2.Tname as Teacher2
FROM Teacher T1,Teacher T2
WHERE T1.Salary > T1.Salary

这里将Teacher表命名成两个所以可以用别名进行select

示例:求既学过001的课又学过002课的同学

SELECT S_Id
FROM SC S1,SC S2
WHERE S1.S_Id = S2.S_Id AND S1.C_Id = '001' AND S2.C_Id = '002'

SC是Student Course

S1.S_Id = S2.S_Id表示学生名字一致,连接

S1.C_Id = '001' AND S2.C_Id = '002'表示学过的课程

这里定义了S1是学习001,S2是学习002的

SQL的增删改

将检索出来的信息加到表中

INSERT INTO St(Sname)
SELECT Sname FROM Student WHERE Sname LIKE '张%'

删除元组(一行),DELETE命令

语法:

DELETE FROM 表名
WHERE 条件

更改元组用update

UPDATE 表名
SET 列名 = 表达式
WHERE 条件

例子:将计算机系教师工资上调10%

UPDATE Teacher 
SET Salary = Salary*1.1
WHERE D_Id in (SELECT D_Id FROM Dept WHERE Dname = '计算机')

D代表学院,D_Id表示系号,查询某一系的系号等于计算机

撤销表

DROP TABLE 表名

DELETE FROM是删除元组,DROP是包括了结构全删

SQL复杂查询

子查询

出现在WHERE中的SELECT的语句,其返回了一个集合

IN子查询语法:

表达式 [NOT] IN 子查询

例子:列出张三,王三的所有信息

SELECT * 
FROM Student
WHERE Sname IN ("张三""王三")

例子:列出选修001课的同学

SELECT S_Id,Sname
FROM Student
WHERE S_Id IN (SELECT S_Id FROM SC WHERE C_Id = '001')

例子:列出选修001和002课的同学

SELECT S_Id
FROM SC
WHERE C_Id = '001' AND S_Id in (SELECT S_Id FROM SC WHERE C_Id = '002')
先选001的同学,AND后面是选002课的

例子:找出001课最高的同学们

SELECT S_Id
FROM SC
WHERE C_Id = '001' AND Score >= ALL (SELECT Score FROM SC WHERE C_Id = '001')
子查询返回所有同学的成绩,相当于比所有同学都高

EXISTS子查询

测试集合是否为空

语法:

[NOT] EXISTS (子查询)

示例:搜索选修赵三老师的同学姓名

SELECT DISTINCT Sname 
FROM Student
WHERE EXISTS 
(SELECT * 
FROM SC,Course,Teacher
WHERE SC.C_Id = Course.C_Id AND SC.S_Id = Student.S_Id AND Course.T_Id = Teacher.T_Id AND Tname = '赵三')

Student和SC连接,SC和Course连接,Course和Teacher连接

聚集函数

就是表达式运算,不允许用在WHERE中

  • COUNT 求个数
  • SUM 求和
  • AVG 求平均
  • MAX 最大
  • MIN 最小

例子:求计算机系教师工资总和

SELECT SUM(Salary) 
FROM Teacher,Dept
WHERE Dept.Dname = '计算机' AND Dept.D_Id = Teacher.D_Id

分组

按照某条件分类

语法:

GROUP BY 分组条件
可以按照列进行分组

上面是对每个组求平均

示例:求不及格课程超过两门的学生学号

SELECT S_Id FROM SC
WHERE Score<60
GROUP BY S_Id HAVING COUNT(*)>2
HAVING表示提取满足条件的分组