数据定义
基本概念
基本表
- 本身独立存在的表
- SQL中一个关系就对应一个基本表
- 一个(或多个)基本表对应一个存储文件
- 一个表可以带若干索引
存储文件
- 物理结构对用户透明
- 索引存放在存储文件中
视图
- 从一个或几个基本表导出的表
- 数据库中至存放数据的定义而不存放视图对应的数据
- 视图是一个虚表,其数据仍然存放在导出视图的基本表中
- 在概念上与基本表相同,用户可以在视图上再定义视图
SQL数据的定义
SQL的数据定义功能:定义数据库、基本表、视图和索引
定义数据库
语法:
CREATE DATABASE [IF NOT EXISTS] <数据库名>
- 定义数据库实际上定义了一个命名空间.
- 在这个空间中可以定义各种数据库对象,例如基本表,视图,索引等
- 如果没有IF NOT EXISTS选项,在创建一个已经存在的数据库时会出现报错
删除数据库
语法:
DROP DATABASE [IF EXISTS] <数据库名>
删除数据库的同时把数据库的数据库对象全部删除
如果没有IF EXISTS选项,在删除一个不存在的数据库时就会出现错误
示例
CREATE DATABASE test; //定义数据库test CREATE DATABASE IF NOT EXISTS test; //如果不存在数据库test,定义数据库test DROP DATABASE test //删除数据库test DROP DATABASE IF EXISTS test; //如果存在数据库test,删除数据库test
使用数据库
语法:
使用数据库👇
USE DATABASE_name;
显示所有数据库👇
SHOW DATABASES
//不要忘记有s
定义基本表
语法:
CREATE TABLE <表名> (<列名> <数据类型>[ <列级完整性约束条件> ] [, <列名> <数据类型>[ <列级完整性约束条件>] ] … [, <表级完整性约束条件> ] ) ;
如果完整性约束条件涉及到该表的多个属性列,则必须定义在表级上,否则既可以定义在列级也可以定义在表级。
列级完整性约束:在每行的定义之后
行级完整性约束:在所有的数据类型定义最后的
示例
定义教师表instructor
CREATE TABLE instructor (ID CHAR(8) , name VARCHAR(20), age INT, salary NUMERIC(8,2), sex CHAR(1) DEFAULT ‘M’ , dept_name VARCHAR(20));
数据类型
- 关系的每一个属性来自一个域,它的取值也必须是域中的值
- SQL中域的概念用"数据类型"来实现
- 关系数据库支持非常多的数据类型,不同的数据库管理系统支持的数据类型可能不完全相同
主要数据类型
难点:
- NUMERIC(p,d):定点数,由p位数字(不包括符号,小数点)组成,小数点后面有d位数字
- DATE:日期,包含年月日,格式为YYYY-MM-DD
- TIME:时间,包含一日的时分秒.格式为:HH:MM:SS
CHAR和VARCHAR
- 定长数据类型
-
- 自动添加空格以补齐字符定义长度
- 可变长度的数据类型
-
- 自动删除后继的空格
- 字符串比较
-
- 当比较两个CHAR类型的值时,如果长度不同,则比较之前会紫红在短值得后面加上额外的空格来使长度一致
- 当比较一个CHAR和VARCHAR类型的时候,如果VARCHAR类型的值较短,比较值钱它会补齐空格,取决于固定的数据库系统
- 因此,即使值相同的CHAR类型和VARCHAR类型比较,也可能出现比较结果不相同的情况.建议使用VARCHAR来避免此类问题
SMALLINT和INT
- SQL标准的整数类型
- MySQL还支持的整数类型:TINYINT,MEDIUMINT,BIGINT
NUMERIC(p,d)
- 定点数
- 这个数有p位数字(不包含符号和小数点),其中d位数字在小数点右边
- 例如:如果属性的数据类型是NUMERIC(3,1)可以精确存储44.5,但是不能精确存储444.5,或者0.32这样的数.
数据类型长度定义
- 定义表的属性时,不仅要指明其数据类型,还需指明其长度
-
- 对于字符串数据类型来说,长度代表字段能够容纳的字符的数目
- 对于数值类的数据类型来说,长度则代表字段使用多少个字节来存放数值
- 有些数据类型的长度是固定的,不需要指定,如INT数据类型的长度固定为4个字节
- 例如:CHAR(20);NUMERIC(8,3);SMALLINT;
空值(NULL)和DEFAULT值
- NULL值
-
- 缺失的值,未知的值
- NULL值不是数字o也不是空字符串"",更不是填入字符串"NULL",而是表示"不知道","不确定"或者"没有数据"的意思
- 表的列可以存放NULL值
- SQL将涉及空值的任何运算的结果视为"UNKNOWN"
- DEFAULT值
-
- 表示某一字段的默认值.当没有输入数据的时候,则使用此默认的值
- 示例
//定义教师表instructor CREATE TABLE instructor (ID CHAR(8) , name VARCHAR(20), age INT, salary NUMERIC(8,2), sex CHAR(1) DEFAULT ‘M’ , dept_name VARCHAR(20));
定义完整性数据库
还可以对表进一步定义,如主码,空值的设定,使数据库的用户能够根据应用的需要对基本表的定义做出更为精确和详尽的解释
五种完整性约束
- NOT NULL和NULL约束
- UNIQUE约束
- PRIMARY约束
- FOREIGN KEY约束
- CHECK约束
NOT NULL约束
- 是否允许该字段的值为NULL
- 当某一字段的值一定要输入才有意义时,可以设置为NOT NULL
- 如主码列就不允许出现空值,否则就失去了唯一标识一条记录的作用
- 只能用于定义列约束
UNIQUE约束
- UNIQUE约束用于指明基本表在某一列或多个列的组合上的取值必须唯一
- 定义了UNIQUE约束的那些列称为 唯一码 ,系统自动为唯一码建立唯一索引,从而保证了唯一码的唯一性
- 唯一码允许为空,但是系统为了保证其唯一性,最多只可以出现一个NULL
- UNIQUE既可用于列约束,也可以用于表约束
- UNIQUE定义列约束时:
-
- <列名> UNIQUE
- UNIQUE定义表约束时:
-
- UNIQUE (<列名>[{,<列名>}])
示例:
建立一个教师表Instructor,定义name为唯一码
CREATE TABLE instructor (ID CHAR(8) , name VARCHAR(20) UNIQUE, age INT, salary NUMERIC(8,2), sex CHAR(1) DEFAULT ‘M’ , dept_name VARCHAR(20));
//建立一个教师表instructor,定义name+sex为唯一码。 CREATE TABLE instructor (ID CHAR(8) , name VARCHAR(20), salary NUMERIC(8,2), sex CHAR(1) DEFAULT ‘M’ , dept_name VARCHAR(20), UNIQUE(name,sex));
系统为name+sex建立唯一索引,确保同一性别的教师没有重名
PRIMARY KEY约束
- PRIMARY KEY约束用于定义基本表的主码,起到了唯一标识的作用,其值不能为NULL也不能重复,以此来保证实体的完整性
- PRIMARY KEY与UNIQUE的区别
-
- 在一个基本表中只能定义一个PRIMARY KEY约束,但可定义多个UNIQUE约束;
- 对于指定为PRIMARY KEY的一个列或者多个列的组合,其中任何一个列都不能出现空值,而对于UNIQUE所约束的唯一码,则允许为空
- 不能为同一个列或者一组列既定义UNIQUE约束,又定义PRIMARY KEY约束
- 既可以用于列约束,也可以用于表约束
示例:
建立一个教师表instructor ,定义ID为instructor的主码 CREATE TABLE instructor (ID CHAR(8) PRIMARY KEY, name VARCHAR(20), salary NUMERIC(8,2), sex CHAR(1) DEFAULT ‘M’ , dept_name VARCHAR(20));
建立一个学生课程成绩表takes,定义ID+course_id+sec_id+semester+year为takes的主码
CREATE TABLE takes (ID VARCHAR(5), course_id VARCHAR(8), sec_id VARCHAR(8), semester VARCHAR(6), year NUMERIC(4,0), grade VARCHAR(2), PRIMARY KEY (ID, course_id, sec_id, semester, year));
CHECK约束
- CHECK约束用来检查字段值所允许的范围。 如: 一个字段只能输入整
数, 而且限定在0-100的整数, 以此来保证域的完整性。 - CHECK既可以列约束,也可用于表约束.语法格式:
CHECK(<条件>)
示例:
建立一个学生课程成绩表takes,定义grade 的取值范围为0到100之间。
CREATE TABLE takes (ID VARCHAR(5), course_id VARCHAR(8), sec_id VARCHAR(8), semester VARCHAR(6), year NUMERIC(4,0), grade NUMERIC(5,2) CHECK (grade >=0 AND grade <=100));
完整性约束
修改基本表ALTER
ALTER TABLE <表名>
[ ADD <新列名> <数据类型> [ 完整性约束 ] ]
[ DROP <列名|完整性约束名> ]
[MODIFY <列名> <数据类型> ];
其中, <表名>指定需要修改的基本表,
ADD子句用于增加新列和新的完整性约束条件,
DROP子句用于删除指定的完整性约束条件,
MODIFY子句用于修改原有的列定义
基本表
假设基本表为student表
CREATE TABLE Student ( Sno CHAR(5) NOT NULL UNIQUE, Sname CHAR(20) UNIQUE, Ssex CHAR(1) , Sage INT, Sdept CHAR(15) );
修改基本表示例
向Student表增加“入学时间” 列, 其数据类型为日期型:
ALTER TABLE Student ADD Scome DATE;
➢ 不论基本表中原来是否已有数据, 新增加的列一律为空值
删除Student表中的属性列Sage:
ALTER TABLE Student DROP Sage;
将学生姓名SNAME的长度增加到30:
ALTER TABLE Student MODIFY Sname VARCHAR(30);
➢ 修改原有的列定义有可能会破坏已有数据
删除基本表drop
当某个基本表无用时,可将其删除。
删除后,该表中的数据和在此表上所建的索引都被删除,而建立在该表上的视图不会随之删除,系统将继续保留其定义,但已无法使用。
如果重新恢复该表,这些视图可重新使用
删除基本表的语法格式:
DROP TABLE <表名>[RESTRICT| CASCADE];
◼ RESTRICT:删除表是有限制的
➢ 将要删除的基本表不能被其他表的约束所引用(如CHECK, FOREIGN
KEY等),不能有视图,不能有触发器,不能有存储过程或函数等。
➢ 如果存在依赖该表的对象,则此表不能被删除。
➢ 缺省情况。
◼ CASCADE:删除该表没有限制
➢ 在删除基本表的同时,相关的依赖对象一起删除。
删除Student表
DROP TABLE Student CASCADE ;
◼ 基本表定义被删除,数据被删除
◼ 表上建立的索引、触发器等也将被删除
◼ 基于表的视图将不可用
超码
1、超码
超码是一个或多个属性的集合,这些属性可以让我们在一个实体集中唯一地标识一个实体。如果K是一个超码,那么K的任意超集也是超码,也就是说如果K是超码,那么所有包含K的集合也是超码。
例如:学生是一个实体,则学生的集合是一个实体集,而超码是用来在学生的集合中区分不同的学生。假设学生(实体)具有多个属性:学号,身份证号,姓名,性别。因为通过学号可以找到唯一一个学生,所以{学号}是一个超码,同理{学号,身份证号}、{学号,身份证号,姓名}、{学号,身份证号,姓名,性别}、{身份证号}、{身份证号,姓名}、{身份证号,姓名、性别}也是超码.
虽然超码可以唯一标识一个实体,但是可能大多数超码中含有多余的属性。所以我们需要候选码。
可以唯一标识一个整体的具有代表性的就是超码
候选码
2、候选码
候选码:如果任意超码的真子集不能包括超码,则称其为候选码,候选码是最小超码;如果K,J都不是超码,那么K和J组成的集合(K,J)有可能是候选码。
在上例中,只有{学号}、{身份证号}都是候选码;另外,如果性别和姓名可以唯一标识一个学生,则{姓名,性别}也为超码。
候选码和主码的区别如下:
1、一个表中可以有多个候选码,但只有一个主码。
2、候选码和主码都能唯一标识表中的一个元组,一个表中可以有多个候选码,从多个候选码中选出一个作为主码。
超码包括候选码,虽然超码可以唯一标识一个实体,但是可能大多数超码中含有多余的属性,所以我们需要候选码。若关系中的一个属性或属性组的值能够唯一地标识一个元组,且它的真子集不能唯一的标识一个元组,则称这个属性或属性组做候选码。
子集比真子集范围大,子集是包括本身的元素的集合,真子集是除本身的元素的集合
总结
所有码都是一个集合。所有可以用来在实体集中标识唯一一个实体的集合,都是超码。如果任意超码的真子集不能包括超码(换句话说就是:它的真子集不能唯一的标识一个元组),则称其为候选码。被数据库设计者选中的,用来在同一实体集中区分不同实体的候选码就是主码,可以是一个属性或者多个属性的集合。
简单的说,超码包括候选码,候选码包括主码
定义索引
- 建立索引的目的:加快查询速度
- 谁可以建立索引
-
- DBA 或 表的属主(即建立表的人)
- DBMS 一 般会 自动 建立以 下列 上的索 引: PRIMARY KEY ,UNIQUE
- 谁维护索引
-
- DBMS自动完成
- 谁使用索引
-
- DBMS自动选择是否使用索引以及使用哪些索引
INDEX和CLUSTER(聚集索引)
建立索引是为了提高查询速度, 但随着索引的增多, 数据更新时, 系
统会花费许多时间来维护索引。 这时, 应删除不必要的索引。
删除索引的语法格式:
DROP INDEX 索引名 ON 数据表名
删除索引时,系统会从数据字典中删去有关该索引的描述.
例: 删除学生课程成绩表takes的索引takes_index:
DROP INDEX takes_index ON takes;
数据更新
插入数据INSERT
功能:将新元组插入指定表中
INSERT INTO子句
- 属性列的顺序可以和表定义中的顺序不一样
- 没有指定属性列
- 指定部分属性列
VALUES子句
- 提供的值必须与INTO子句匹配
-
- 值的个数
- 值的类型
将一个新学生的信息(学号: 201415128;姓名: Chen;性别:
M;所在系: Bioinformatics;年龄: 18岁)插入到Student表中。
INSERT INTO Student (Sno,Sname,Ssex,Sdept,Sage) VALUES (‘20141512’, ‘Chen’,‘M’,‘Bioinformatics’,18); INSERT INTO Student VALUES (‘20141512’, ‘Chen’,‘M’,‘Bioinformatics’,18)
RDBMS在执行插入语句时会检查所插元组是否破坏表上已定义的完
整性规则
➢ 实体完整性
➢ 参照完整性
➢ 用户定义的完整性
✓ NOT NULL约束
✓ UNIQUE约束
✓ 值域约束
更新数据update,set
功能:修改指定表中满足WHERE子句条件的元组
◼ SET子句
➢ 指定修改方式
➢ 要修改的列
➢ 修改后取值
◼ WHERE子句
➢ 指定要修改的元组
➢ 缺省表示要修改表中的所有元组
将学生20141512的年龄改为22岁
UPDATE Student
SET Sage=22
WHERE Sno='20141512';
将所有学生的年龄增加1岁
UPDATE Student
SET Sage= Sage+1;
删除数据DELETE
删除学号为20141512的学生记录
DELETE
FROM Student
WHERE Sno= '20141512';
删除所有的学生记录
DELETE FROM Student;
执行此语句后, Student表即为一个空表,但其定义仍存在数据
字典中。
更多示例
create table department (dept_name varchar (20), building varchar (15), budget numeric (12,2), primary key (dept_name));
create table course (course_id varchar (7), title varchar (50), dept_name varchar (20), credits numeric (2,0), primary key (course_id), foreign key (dept_name) references department (dept_name));
create table instructor (ID varchar (5), name varchar (20) not null, dept_name varchar (20), salary numeric (8,2), primary key (ID), foreign key (dept_name) references department (dept_name));
create table teaches (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 section (course_id, sec_id, semester, year) , foreign key (ID) references instructor (ID) )
create table section (course_id varchar (8), sec_id varchar (8), semester varchar (6), year numeric (4,0), building varchar (15), room_number varchar (7), Time_slot_id varchar (4), primary key (course_id, sec_id, semester, year), foreign key (course_id) references course (course_id));
插入Comp. Sci. 系开设的名为“Database Systems”的课程CS-437,它
有4个学分
insert into course values (’CS-437’, ’Database Systems’, ’Comp. Sci.’, 4); insert into course (course_id, title, dept_name, credits) values (’CS-437’, ’Database Systems’, ’Comp. Sci.’, 4); insert into course (title, course_id, credits, dept_name) values (’Database Systems’, ’CS-437’, 4, ’Comp. Sci.’);