目录
1.1.为什么要使用DML?
DQL是查询语句,查询数据库中的记录,那么数据库表中的数据是怎么来的呢?即使,我们数据库表中保存的数据是一开始就有的,那么数据库中的表如果一成不变也并不满足我们的需求。所以,我们需要一种语句,来帮助我们添加、删除、修改数据库中的记录。
1.2.什么是DML?
DML是SQL语言中包含了操作数据库对象中包含的数据的语句。
什么意思呢?
DML与DQL不同,DQL是将从记录中拿出我们想要的数据,DML是对记录本身进行操作。
1.3.DML的组成
语句 | 作用 |
Insert | 向数据表中插入一条记录 |
Delete | 删除数据表中的一条或多条记录,也可以删除数据表中的所有记录,但是,它的操作对象仍是记录 |
Update | 用于修改已存在表中的记录的内容 |
1.4. 应用场景
insert | 注册 |
update | 修改密码 |
delete | 退出、删除、剔除会员 |
select | 登录|查看会员 |
1.5.insert
1.5.1.语法结构
insert into 表名 [(字段列表)] values(值列表); 添加记录
1.5.2.前提条件
1.类型 长度 兼容:字段 兼容值
类型长度兼容的意思是我们前面字段列表要和后面的值列表完全对应,也就是说,后面的值的顺序,数据类型,值的长度要和前面的字段列表的约束完全对照。
2.值满足约束:主键(唯一+非空)非空(必填) 唯一(不重复 ) 默认(没有填写使用默认值) 检查(满足条件)外键(参考主表主键列的值)
这里的意思就是,我们创建的新记录中的每个值都要满足该值对应的字段的约束。就像主键的要求是非空+唯一,那么我们新纪录的主键值就不能是重复或为空。
假设我们的新记录中值只包含了部分字段而不是全部字段,那该条记录的其他字段的值就是我们定义好的默认值。
如果,我们新纪录中的值不满足字段的约束条件,那么就不能添加,添加失败
外键的值则是参考主表中主键列的值。
3.个数必须相同: 指定列,个数顺序与列相同;没有指定,个数与表结构的列个数和顺序相同 (null也得占位,没有默认值)
个数相同的意思就是,我们每次添加记录的时候,如果指定了该条记录的字段列表,那么我们后面的值列表中的值,就要和前面的字段列表的个数保持一致;如果没有指定该条记录的字段列表,那么我们就需要依照表结构中的字段给每一个字段都传入一个值。
总结:实际上,我们需要满足的条件就有一条,就是,在编写插入语句的时候,前面的字段列表和后面的值列表一定要对应,而且值的数据类型、长度等要满足对应的字段的要求。
1.5.3.基本使用
添加所有列 insert into 表名 values(值列表 );
--insert into 表名 values(值列表 );
insert into dept values(97,'v','x');
添加指定列 insert into 表(指定列) values(值列表);
--insert into 表(指定列) values(值列表);
insert into emp(empno,ename,deptno) values(1111,'haha',20);
使用其他表添加数据【haha_emp的表结构与emp表一致】
insert into 表名 select 查询列 from 源表 where 过滤数据;
insert into 表(指定列) select 查询列 from 源表 where 过滤数据;
--insert into 表名 select 查询列 from 源表 where 过滤数据;
insert into haha_emp select empno,ename,sal,deptno from emp where deptno = 10;
--insert into 表(指定列) select 查询列 from 源表 where 过滤数据;
insert into haha_emp(empno,ename,deptno) select empno,ename,deptno from emp where deptno = 20;
1.5.4.总结
1.无论是添加所有列还是添加指定列,都是向数据库中的某张表添加了一条数据
2.添加数据时,要满足添加数据的条件:字段列表与值列表要保持一致。
3.添加数据的时候,可以通过其他表中的数据来进行添加。
1.6.update
1.6.1.语法结构
update 表名 set 字段=值 [,....] 修改所有数据
1.6.2.前提条件
1.记录存在
所谓的记录存在的意思就是,保证记录存在于表中,否则我们所谓的修改都没有目标,修改记录也就无从说起
2.类型长度兼容:字段兼容值
3.个数相同
1.6.3.基本使用
update 表名 set 字段=值 [,....] where 过滤行记录;
--update 表名 set 字段=值 [,....] where 过滤行记录;
update haha_emp set sal = sal+10000,deptno=20 where sal>22000;
update 表名set (字段列表) =(select 字段列表 from 源表 where 过滤源表记录) where 更新记录的条件手动更改字段值
--update 表名set (字段列表) =(select 字段列表 from 源表 where 过滤源表记录) where 更新记录的条件手动更改字段值:
update haha_emp set(sal,deptno) =(select sal,deptno from emp where empno = 7369) where empno = 7369;
1.7.delete
1.7.1.语法结构
delete [from] 表名 where 过滤行记录
1.7.2.前提条件
1. delete 可以删除指定部分记录,删除全部记录
delete删除的是通过where过滤记录后找到的全部数据,当我们的where后的判断恒为true或是不添加where判断时,就是删除全部记录。
2.先删除从表 再删除主表
记录上存在主外键关联时, 删除存在关联的主表的记录时,注意参考外键约束, 约束强制不让删除。
简单来说,就是当要删除的记录存在关联,此时,我们要删除主表的记录的时候,会因为其有存在关联的从表而无法删除。这是因为,如果我们可以删除,那么从表中的那列关联主表的值就会变为无效数据。
1.7.3.基本使用
删除所有记录
--删除所有记录
delete from haha_emp;
delete from haha_emp where 1 = 1;
删除指定类型的数据
delete from emp where deptno = 20;
主外键关联关系下的两张表
1.删除从表数据 -----> 直接删除
delete from emp where deptno = 20;
2.删除主表数据 -----> 未被主表引用 ------> 可以直接删除
delete from dept where deptno = 40;
3.删除主表数据 -----> 已被主表引用 ------> 不可以直接删除
delete from dept where deptno = 10;
问题:我们发现此时,我们不能删除主表
分析:这是因为主表中的deptno在从表emp中有实际的引用,所以,我们不能直接删除该条数据,我们需要给从表中的数据提供一个处理方案,然后才可以删除主表数据。
解决:
方式一:先删除从表中引用了的那些从表数据,再删除主表数据
方式二:删除主表数据的同时删除从表中所引用的那些从表数据 : 在外键约束的设置位置最后添加 on delete cascade
方式三:删除主表数据的同时把从表中引用了当前主表数据的从表数据的外键字段值设置为null : 在外键约束的设置位置最后添加 on delete set null
1.8.截断数据
1.8.1.语法结构
truncate table 表名;
1.8.2.前提条件
1.表实际存在,不存在会找不到表
2.表中存在数据,否则该条语句没有意义
1.8.3.截断数据的特点
1.能够删除所有的数据
这里的删除所有的数据是表本身还在,只是数据被删除了.
2.不会开启事务
3.表结构上检查是否被从表关联,如果是并不能使用数据截断
当我们要截断的表的结构中存在主外键的关系,那么就不能使用数据截断。
1.8.3.基本使用
truncate table emp;
1.8.4.delete和truncate的区别
1.truncate不涉及事务,所以,不能回滚;delete涉及事务,所以可以回滚
2.truncate截断的是所有的数据;delete则是删除全部或删除部分记录都可
3.truncate从结构上检查是否存在主外键,存在就不可以删除;
delete从记录上检查是否存在主外键,存在,按参考外键约束来进行删除。
二、DDL数据定义语言
2.1.为什么要使用DDL?
DML语句是对表中的记录层级进行操作,但是记录实际上是保存在一个表中的,或者说,记录是表的组成成分。那么我们的表是否也需要一种语言来进行操作。
这就是我们SQL语言中的DDL数据定义语言。
2.2.DDL的作用、分类
2.2.1.DDL的作用
DDL数据定义语言是用于操作对象和对象的属性的语言。这种对象指的是包括数据库本身,以及数据库对象、表、视图等
2.2.2.DDL的分类
语句 | 作用 |
create | 可以创建数据库和数据库的一些对象 |
drop | 可以删除数据表、索引、条件约束等 |
alter | 修改数据表定义及属性 |
2.3.设计表
2.3.1.为什么要设计表?
我们的表是需要我们自己来创建的,而在创建之前,我们需要依据一定的规矩来设计我们想要创建的表的结构
2.3.2.三范式
什么是范式?
范式是设计数据库的一种行业的准备。这个标准也可以被成为是条件。
范式的分类
一范式1NF | 数据库的每一列都是不可分割的基本数据项 |
二范式2NF | 前提:满足一范式 每一行都可以被唯一区分,非主属性非部分依赖于主属性 |
三范式3NF | 前提:满足二范式 属性不可依赖于其他非主属性 |
范式的目的
范式的最终目的避免数据重复冗余,1NF-->列不可再分最小原子 (避免重复);2NF-->主键依赖(确定唯一);3NF-->消除传递依赖(建立主外键关联 拆分表);
2.3.3.主外键约束
主表|父表 : 被从表依赖|参考引用的表 Dept
从表|子表 : 存在外键字段的表 Emp
2.3.4.表与表之间的关系
1.一对一 : 用户表 身份证表 --> 主外键关联关系
2. 多对一|一对多 : 学生表 和 班级表
员工表 与 部门表 ------ 主外键关联关系
3.多对多 : 通过中间表描述
2.3.5.设计表总结
设计表首先应该按需遵循三范式
1. 确定表名
2. 确定字段名 类型 +约束(主键 外键 非空 默 检查认 唯一)
主键: 唯一标识一条记录(唯一并且非空)
唯一: 唯一
非空:不能为空
默认: 当没给值时使用给定一个默认值
外键:参考其他表(自己)的某个(某些)字段
检查:自定义的规则
2.4.Create创建表
2.4.1.为什么要创建表?
数据库中的数据是以表的形式进行存储的,也就是说,数据存在于表中,那么表是从哪里来的呢?表又是依据什么创建的呢?
首先,数据库是我们存储数据的手段,数据当然是我们人类提供的,那么,数据在数据库中怎么存储,存储到什么样的表中,都是都我们人为指定的。
所以,我们要创建一个专门的表用来存储我们想要存储的数据类型。
总的来说,创建表的目的是为了能够对应的存储我们需要被存储的数据
2.4.2.创建表
表名必须唯一,如果存在 ,必须先删除,然后才可以创建
create table 表名(
字段名 类型(长度) 约束,
...其他字段....
..约束........
);
实际创建举例
--创建表,不添加约束
create table tb_user(
userid number(5),
username varchar2(6 char), --(6 char)6个字符 ,默认字节数
userpwd varchar2(20),
age number(3) ,
gender char(3) ,
email varchar2(30),
regtime date
);
2.4.3.约束
什么是约束?
我们在创建表的时候,我们并不仅仅是设置一个列名以及该列的数据类型即可,我们还需要为表中的每个列都设定一个约束。
约束的分类
主键约束 | primary key |
唯一约束 | unique |
非空约束 | not null |
默认约束 | default(默认值) |
检查约束 | check() |
外键约束 |
对于约束,我们也可以把约束分成逻辑约束和物理约束。
逻辑约束:基于代码层面进行判断
物理约束:在表结构中给字段添加约束-----不便于后期的维护
2.4.4.表和约束的同时创建
除外键约束外的其他约束
1.创建表的同时添加约束 ,字段后直接添加约束,默认的约束名
通过不同的关键字来确认我们为哪一列对应添加哪种约束
--创建表的同时添加约束 ,字段后直接添加约束,默认的约束名
create table tb_user(
userid number(5) primary key,
username varchar2(30) check(length(username) between 4 and 20) not null,
userpwd varchar2(20) not null check(length(userpwd) between 4 and 18),
age number(3) default(18) check(age>=18),
gender char(3) default('男') check(gender in('男','女')),
email varchar2(30) unique,
regtime date default(sysdate)
);
2.创建表(同时创建约束+指定名称)
这里指定的名称是我们所添加的这条约束的名称,简单来说就是为约束取名
通过关键字constraint
--创建表(同时创建约束+指定名称)
create table tb_user(
userid number(5) constraint pk_user primary key,
username varchar2(30) constraint xixihaha check(length(username) between 4 and 20) constraint xixihehe not null,
userpwd varchar2(20) not null check(length(userpwd) between 4 and 18),
age number(3) default(18) check(age>=18),
gender char(3) default('男') check(gender in('男','女')),
email varchar2(30) unique,
regtime date default(sysdate)
);
3.创建表结构中,在所有字段声明的后面同意为字段添加约束
这种方式是,将添加约束的语句和实现字段的语句分隔开来。
--创建表结构中,在所有字段声明的后面同意为字段添加约束
create table tb_user(
userid number(5),
username varchar2(30) constraint nn_user_name not null ,
userpwd varchar2(20) constraint nn_user_pwd not null ,
age number(3) default(18) ,
gender char(3) default('男'),
email varchar2(30),
regtime date default(sysdate),
constraint pk_user_id primary key (userid),
constraint ck_user_name check(length(username)between 4 and 20) ,
constraint ck_user_pwd check(length(userpwd) between 4 and 18),
constraint ck_user_age check(age>=18),
constraint ck_user_gender check(gender in('男','女')),
constraint uq_user_email unique(email)
);
4.创建表(追加创建约束+指定名称)
这种方式相较于上面那种方式而言,添加约束与定义字段更为分离,直接是先创建出表,再为表中的各个字段添加约束
--创建表,不添加约束
create table tb_user(
userid number(5),
username varchar2(6 char), --(6 char)6个字符 ,默认字节数
userpwd varchar2(20),
age number(3) ,
gender char(3) ,
email varchar2(30),
regtime date
);
--创建表(追加创建约束+指定名称)
alter table tb_user add constraint pk_user_id primary key (userid);
alter table tb_user add constraint ck_user_name check(length(username)between 4 and 20) ;
alter table tb_user add constraint ck_user_pwd check(length(userpwd) between 4 and 18);
alter table tb_user add constraint ck_user_age check(age>=18);
alter table tb_user add constraint ck_user_gender check(gender in('男','女'));
alter table tb_user add constraint uq_user_email unique(email);
外键约束的添加
单个约束的添加,这样看起来会更明确一些,这里以外键约束举例
1.在字段后面直接指定外键约束,默认的约束名
--1)在字段后面直接指定外键约束,默认的约束名
create table tb_txt(
txtid number(10),
title varchar2(32) constraint nn_txt_title not null,
txt varchar2(1024),
pubtime date default(sysdate),
userid number(5) references tb_user(userid) --指定了外键约束
);
2.在字段的后面指定约束名添加外键约束
--2)在字段的后面指定约束名添加外键约束
create table tb_txt(
txtid number(10),
title varchar2(32) constraint nn_txt_title not null,
txt varchar2(1024),
pubtime date default(sysdate),
userid number(5) constraint pk_userid references tb_user(userid) --指定了外键约束
);
3.表结构结束之前为指定字段添加外键约束
--3)表结构结束之前为指定字段添加外键约束
create table tb_txt(
txtid number(10),
title varchar2(32) constraint nn_txt_title not null,
txt varchar2(1024),
pubtime date default(sysdate),
userid number(5),
constraint fk_txt_ref_user_id foreign key(userid) references tb_user(userid)
);
4.表结构结束之后追加外键约束
--4)表结构结束之后追加外键约束
alter table tb_txt add constraint fk_txt_ref_user_id foreign key(userid) references tb_user(userid);
2.5.drop删除表
删除表就意味着整张表的删除、消失,所以,删除表的同时会将该表相关的约束等全都删除
2.5.1.删除表的各种情况
要删除的表类型 | 删除流程 |
普通表 | 直接删除 |
主表下的从表 | 直接删除 |
主表 | 先删除所有从表,再删除主表cascade constraints |
--drop table 表名 (cascade constraints)
drop table tb_txt cascade constraints;
drop table tb_user cascade constraints;
--删除表
drop table emp_his;
--主从表关系下删除表
--先删除从表 再删除主表 ;同时删除约束
drop table tb_txt cascade constraints;
drop table tb_user cascade constraints;
--删除主表的同时级联删除约束
drop table emp_his cascade constraints;
2.6.修改表结构
2.6.1.修改表结构的分类
修改表名 | rename to |
修改列名 | alter table 表名 rename column to |
修改类型 | alter table 表名 modify(字段 类型) |
修改约束 | 先删除 后添加 |
添加列 | alter table 表名 add 字段 类型 |
删除列 | alter table 表名 drop column 字段 |
2.6.2.实际举例
--修改表名
rename tb_txt to tb_txt_new;
--修改列名
alter table tb_txt_new rename column txtid to tid;
--修改类型
alter table tb_txt_new modify(tid varchar2(20));
--添加列
alter table tb_txt_new add col varchar2(30);
--删除列
alter table tb_txt_new drop column col;
select * from tb_txt_new;
2.7.补充
2.7.1.已有表的拷贝
--已有表中拷贝结构 : 无法拷贝字段的约束
--只拷贝结构不拷贝数据 create table 表名 as select 字段列表 from 已有表 where 1!=1;
create table haha_emp as select empno,ename,sal,deptno from emp where 1!=1;
--拷贝结构同时拷贝数据 create table 表名 as select 字段列表 from 已有表 where 条件;
create table hehe_emp as select empno,ename,sal,deptno from emp where deptno = 30;