目录
一、数据库三范式
1.第一范式(确保每列保持原子性)
第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。
2.第二范式(确保表中的每列都和主键相关)
第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
3.第三范式(确保每列都和主键列直接相关,而不是间接相关)
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
二、表空间
-
可以给数据仓库分成若干块,每一块就叫做一个表空间;
-
每个表空间都可以对应一个用户;
-
初步使用数据库的时候,先创建一个用户,再给此用户指定一个表空间;
-
如果不给用户创建表空间,就默认使用Oracle的默认表空间;
1.与创建用户的关系
-
先创建表空间;
-
让
user06
与此表空间关联; -
再建表(此时,新建的表就会在刚创建的表空间里);
2.创建表空间
--name:此表空间的名字
create tablespace name;
--此表空间的属性
datafile 'E:\TableSpaceFile\user_01\user01.dbf'size 10M;
--必须先drop 再手动删除磁盘文件
drop tablespace user06 tbs;
三、用户
1.创建用户
-
只有管理员才能创建用户;
-
用管理员身份再PL/SQL中输入;
--create:创建 identified:密码
create user user06 identified by tiger;
用户已经创建成功,但是缺少某个权限(缺少登录权限),导致登陆失败;
接下来需要给此用户赋予一个登录权限;
2.赋予权限
a.登录权限
--grant:授予
grant connect to user06;
然后就可以登陆了:
登陆后,发现没有操作权限:
b.操作权限
--给一个操作表的权限
grant resource to user06;
--给一个管理员权限
grant dba to user06;
3.回收权限
--回收所有权限
--回收管理员权限
revoke dba from user06;
--回收操作权限
revoke resource from user06;
--回收登录权限
revoke connect from user06;
4.删除用户
-
如果此用户有表,则默认不能删除;
-
先删除表,再删除用户;
drop user user06;
四、Oracle数据类型
-
字符类型:对应Java中的字符串;
-
数值:对应Java中的数字(整数、小数);
-
日期类型:对应Java中的日期类(Date);
-
用的很少(原因):前端拿到是字符串类型,但是保存在数据库要转换成日期类型;
-
从数据库拿数据到展示页面,把日期类型的数据转换成字符串,干脆把日期作为字符串保存在数据库;
-
如果展示数据比较多,日期运算比较少,我们就需要把日期作为字符串保存在数据库中,需要计算日期的时候,把日期从数据库拿出来,利用SimpleDateFormat转换成Date类型,进行日期运算;
-
-
大数据类型(最后两个):一般用来存放图片、音频、视频等较大的文件,基本被弃用(因为现在有专门的图片、视频服务器);
1.字符
a.char
定长字符串,例如:char(6)里面保存的字符串长度是6,如果字符串长度不到6,会默认使用空格填充。
b.varchar2
可变长度字符串,不会用空格填充,例如:varchar(10)里面保存的字符串长度最多是10位,但是可以小于10位。
2.数值
a.整数
int:整型
long:长整型,使用较少;
number:可以表示整数和小数;
b.小数
number:可以表示整数和小数;
c. number demo
number(10,0) 10表示总长度,0表示小数位数(0即为整数)
number(10,2) 10表示总长度(整数位数+小数位数),2表示小数长度(2即为两位小数,如:2.22)
3. 日期
-
date
只有年月日; -
date
格式为:'yyyy-mm-dd'
; -
时间戳:
timesmap
是年月日时分秒; -
时间戳格式为:
'yyyy-mm-dd hh24:mi:ss'
;
--date只有年月日,时间戳:timesmap是年月日时分秒
insert into students values(2023,'james','m',
to_date('2022-2-3','yyyy-mm-dd'),'四年三班','经济管理学院');
Demo
--建表
create table students(id char(6),name varchar2(25),inschool date,score int);
--插入数据,错误示范(所插入的日期数据不是日期类型的):insert into students values('202202','unclebird','2022-09-01',90);
insert into students values('202202','unclebird',to_date('2022-09-01','yyyy-mm-dd'),90);
--查询
select * from students;
--新增一列
alter table students add(address varchar2(50));
--修改一个字段
alter table students modify (address varchar2(60));
--做以上操作的时候,表中最好是没有数据的,否则很容易出错
alter table students modify (id char(3));
操作注意事项:
做一些操作的时候尽量在写入数据之前;
--修改id的长度为3
alter table students modify (id char(3));
结果:
五、数据完整性
1.实体完整性
a.主键约束(Primary)
-
创建表的时候,每个表都要有主键,主键起到唯一识别的作用;
-
插入数据的时候,主键值不可以重复,某个值也不可以为null;
-
当我们在某一列上添加主键约束的时候,数据库会在这一列上添加二叉树索引;
-
索引(Rowid):可以理解为一本书的目录,目的是提高查询的效率;
-
注意:频繁增删改查数据的时候,Oracle会重新生成新的二叉树索引;
例如:学生的学号都是不一样的,所以可以作为主键;
Demo:
只要在cid上添加了主键约束,那么插入数据的时候,cid的值就是不能重复的,这样保证了数据的唯一;
已有的值再添加会报错;
b.唯一约束(Unique)
在name上添加了唯一约束(Unique),插入数据的时候,name不可以重复,但是某个值可以为null;
c.添加约束
右键table点击Edit再checks中添加:
2.域完整性
定义了id长度为6,输入10位就不可以,这就是域完整性;
3.引用完整性
EG :
--向doctor中插入数据
insert into doctor values(2022,'尼古拉斯','医生','内科',35);
--由于doctor_id:'2222'不存在,所以会报错
insert into patient values(101,'tom','m',2222,203);
六、各表的关联关系
表之间的关系是分方向的,共有四种关系:
-
一对一
-
一对多
-
多对一
-
多对多
1.分析ER图
a.多对多
-
一个学生可以选修多门课程;
-
一门课程可以被多个学生选修;
-
这个情况下,学生表和课程表之间就是多对多;
Demo
建表完两表后:
-
此时,两张表是没有对应关系的,可以创建一个中间表,来体现对应关系;
-
创建中间表的字段:至少有两个字段,分别对应每张表的主键,根据需要可以再添加其他字段;
-
中间表:
stuc
; -
字段:
stuid
、cid
、mark(分数);
建完中间表后:
-
此时中间表是没有主键的;
-
假设要设置主键,有两种方案:
-
设置联合主键,让
stuid
和cid
变成一个主键; -
添加一个字段,让其字段担任主键角色;
-
b. 多对一 + 一对多
-
一个医生医治多个病人,一个病人只对应一个医生;
-
这种关系就是一对多、多对一;
-
从医生到病人是一对多,从病人到医生是多对一;
c.一对一
-
一个私人医生对应一个病人;
-
一个病人只有一个私人医生;
2.如何建表
a.表设计
在设计表的时候,如果两个表之间是多对多关系,最好创建一个中间表,把原来的多对多关系编程两个一对多、多对一的关系;
b.根据ER图建表
--看数据字典(每个公司不一样) 医生表
--constraint pk_doctor_id primary key(doctor_id) 创建主键为doctor_id
--jobtitle varchar2(20) default '医生' 默认值为"医生"
create table doctor(doctor_id int not null,doctor_name varchar2(20),
jobtitle varchar2(20) default '医生',department varchar2(20),age int,
constraint pk_doctor_id primary key(doctor_id));
--病人表
create table patient(patient_id int not null,patient_name varchar2(20),
patient_sex varchar2(2),doctor_id int,room_id int,
constraint pk_patient_id primary key(patient_id));
目前,这两张表是不存在关联关系的,需要通过外键建立关联关系;
c.设置外键
病人表的外键对应医生表的主键
违反(引用)完整约束条件
插入数据的时候,会拿外键的值去主键所在的表中查找是否存在此值,如果存在,则插入成功,否则报错;
--向病人表中插入数据
insert into patient values(101,'tom','m',null,203);
--建议先向doctor中插入数据 所以先删除patient的数据
delete from patient;
--向doctor中插入数据
insert into doctor values(2022,'尼古拉斯','医生','内科',35);
--由于doctor_id:'2222'不存在,所以会报错
insert into patient values(101,'tom','m',2222,203);
--添加正确的病人信息
insert into patient values(101,'lucy','m',2022,203);
insert into patient values(102,'jack','m',2022,203);
怎么辨别表关系类型(几对几)
-
看ER图;
-
看数据;
如:Lucy和Tom同属于一个医生,那么就是一对多、多对一的;
查询医生都给那些人看病
--看医生都给哪些病人看病
select patient_name,doctor_name from doctor,patient where doctor.doctor_id=patient.doctor_id and doctor.doctor_id=2022;