2021-03-26伪列,约束

伪列

  1. rowID 列的id 物理地址 不变的

  2. rownum 列的编号 逻辑地址 可变的

    a.select rowid,rownum,e.* from emp e ;

    在这里插入图片描述

    b. select rowid,rownum,e.* from emp e where deptno = 20;

    在这里插入图片描述

  3. 业务查询:

    查询emp中工资最高的前三个员工信息

    (1)错误做法:

    在这里插入图片描述

    此时查询的表还是没有排序之前的表emp,因此rownum没有发生变化

    (2)正确做法使用子查询:

    select rownum,ename,sal from (select * from emp order by sal desc) where rownum <4 ;

    在这里插入图片描述

    此时查询的表是一个子查询中排序后的表,此时的rownum已经发生变化

    (3)总结:

    遇到top-n 问题全都套用以下公式即可:

    select rownum,… from (select * from xxx****表 order by xxx) where rownum < n ;

    注: 在使用rownum之前,先解决排序问题!!

  4. 插入重复项

    (1)创建student表

    在这里插入图片描述

    (2)插入重复数据

    在这里插入图片描述

    在这里插入图片描述

  5. 删除重复数据

    (1)错误方式:

    ① 以stuno为依据删除,是错误的!

    此删除将会删除所有stuno相同的所有数据,并没有去重

    ② 以distinct方式删除数据,也是错误的!

    select distinct stuno from mystudent ;

    此方式只能比较数据,不能依据rowID进行操作

    在这里插入图片描述

    在这里插入图片描述

    (2)正确方式:

    手动:Delete from mystudent where rownum=1;

    Delete from mystudent where rownum=3;

    思路:根据stuno分组,将重复的数据放在一组中,然后在每组中只保留一个数据即可

    在这里插入图片描述

    a.先根据stuno分组

    在这里插入图片描述

    b. 根据rowid来去重,保留rowid中最小或最大的都行 在这里插入图片描述

    c. 删除非保留的数据

    delete from mystudent where rowid not in (select min(rowid) from mystudent group by stuno); 在这里插入图片描述

  6. Rowid: 物理伪列

    18位真实的存在物理硬盘上的地址

    AAAAAA AAA AAAAAA AAA

    对象 文件 块 行

    在这里插入图片描述

约束简介

  1. 数据表只支持数据的存储操作,数据库中保证数据完整性,增加了数据约束,如果有些数据需要满足若干条件后才可以进行操作,例如:某些数据不能重复,假设定义用户信息,身份证编号绝对不能重复。

  2. 数据库约束有六种:

    检查(check)

    唯一(Unique)

    非空(Not null)

    默认约束(Default)

    主键(Primary key)

    外键(Foreign Key)

  3. 创建student表

    在这里插入图片描述

    在这里插入图片描述

    √ 插入数据:

    在这里插入图片描述

    x 主键约束:

    在这里插入图片描述

    在这里插入图片描述

    √ 有默认值:

    在这里插入图片描述

    x 唯一约束:

    在这里插入图片描述

    x 非空约束:

    在这里插入图片描述

    x 检查约束:

    在这里插入图片描述

  4. 约束分类

    在这里插入图片描述

  5. 约束的命名

    (1)规范:CONSTRAINT 约束类型_字段名

    在这里插入图片描述

    (2)注意事项:约束名是 多个表公用的 (多个表中的约束 不能重名)

    create table student2(
     id number(3) constraint PK_stuno    primary key  ,
     name varchar2(10)
    );
    
    

    在这里插入图片描述

检查约束(CHECK,CK)

  1. 检查约束指:在数据列上设置一些过滤条件,当过滤条件满足的时候才可以进行保存数据,如果不满足则不允许保存数据。

  2. 检查约束案例:如果设置年龄的信息,年龄0~250,性别男/女

CREATE TABLE member(
   mid     NUMBER,
   mname  VARCHAR2(20)
   age      NUMBER(3)  
   CONSTRAINT pk_mid PRIMARY KEY(mid)
   CONSTRAINT ck_age CHECK(age BETWEEN 0 AND 250)
);

请问,除了“年龄”检查,在age上应该还要做什么约束??从实际的开发来讲,检查约束往往不会设置,而检查一般都会通过程序完成。

唯一约束

  1. 唯一约束的特点是在某一列上的内容不允许出现重复

    例如,收集用户的信息,包含编号,姓名,email;明显email数据是不可能重复的,所以可以使用UNIQUE约束。

  2. 范例:使用唯一约束

    CREATE TABLE  member(
          mid   NUMBER  ,
          mname   VARCHAR2(20) NOT NULL  UNIQUE,
          email      VARCHAR2(20) UNIQUE
    );  
    
  3. 向member增加数据

    (1)范例:增加正确的数据

    INSERT INTO member(mid,mname,email)VALUES(1,‘JACK’,‘[email protected]’);

    (2)范例:增加错误的数据(邮箱不可以有重复的)

    INSERT INTO member(mid,mname,email)VALUES(2,‘TOM’,‘[email protected]’);

非空约束

  1. 非空约束指表中某个字段的内容不允许为空值,如果要使用非空约束,只需要在每个列后面使用“NOT NULL”声明即可。

  2. 范例:使用非空约束

    注意:在mname列定义时,增加NOT NULL表示该列不允许出现NULL值。

    CREATE TABLE  member(
          mid   NUMBER,
          mname   VARCHAR2(20) NOT NULL
    );
    
  3. 向member增加数据

    (1)范例:正确的增加语句

    INSERT INTO member(mid,mname)VALUES(1,‘JACK’);

    (2)范例:错误的增加数据

    INSERT INTO member(mid,mname)VALUES(1,NULL);

    INSERT INTO member(mid)VALUES(1);

    注意:在设置了非空约束后,如果出现了违反非空约束的操作,什么自动准确 的定位到哪个模式、哪张表、哪个字段,这样在进行错误排查时最方便所在

默认约束

  1. 默认约束指定某列的默认值,

    在没有明确插入数据时默认添加指定的默认值。

  2. 范例:使用默认约束

    在sex列定义时,增加default表示该列默认值为‘男’。

    CREATE TABLE  member(
          mid   NUMBER,
          mname   VARCHAR2(20) NOT NULL,
          sex   VARCHAR2(20)  default  '男'
    );
    
    

主键约束

  1. 主键约束=非空约束+唯一约束

  2. 设置主键列,不能为空也不能重复。像用户的编号,也不能为空

  3. 范例:定义主键约束

    推荐使用第二种方法,错误时提示的信息,可以精确定位到列。

    CREATE TABLE  member(
          mid   NUMBER   PRIMARY KEY,
          mname   VARCHAR2(20) NOT NULL);CREATE TABLE  member(
          mid   NUMBER   ,
          mname   VARCHAR2(20) NOT NULL,
          CONSTRAINT pk_mid PRIMARY KEY(mid)
    );
    
  4. 在正常情况下一张表只能够定义一个主键,在SQL中也允许定义多个列为主键,这样的操作称为:复合主键,如果是复合主键表示若干个列的内容完全重复的时候会违反约束。

  5. 范例:定义复合主键

    **注意:**数据库设计第一原则,不要使用复合主键,即一张表一个主键。

    CREATE TABLE  member(
          mid   NUMBER,
          mname   VARCHAR2(20) NOT NULL,
          CONSTRAINT pk_mid PRIMARY KEY(mid,mname)
    );
    

外键约束

  1. 外键约束主要是在父子表关系中体现的一种约束操作。下面通过一个具体操作观察为什么会有外键。例如:现在希望描述一种概念:一个人有多本书,如果设计表需要设计两张数据表,则初期的设计如下。

  2. 范例:初期设计(不使用外键)

    CREATE TABLE  member(
          mid   NUMBER,
          mname   VARCHAR2(20),
          constraint pk_mid primary key(mid)
    );
    CREATE TABLE  book(
          bid   NUMBER,
          title   VARCHAR2(20),
          mid   NUMBER
    );
    
  3. 于是下面开始为表增加相关的数据。

    范例:增加正确数据

    insert into member(mid,mname)values(1,‘jack’);

    insert into member(mid,mname)values(2,‘tom’);

    insert into book(bid,title,mid)values(10,‘java开发’,1);

    insert into book(bid,title,mid)values(11,‘PHP开发’,1);

    insert into book(bid,title,mid)values(12,‘C开发’,2);

    insert into book(bid,title,mid)values(13,‘NET开发’,2);

    但也有可能出现如下的信息:

    insert into member(bid,title,mid)values(13,‘神精是如何炼成’,9);

    此时member表中并没有编号为9的成员信息。但由于没有设置约束,所以即使用父表(member)中不存在对应的编号,子表也可以使用,这就是一个错误。

  4. 实际上,book表中的mid列的内容的取值应该是由member表中的mid列所决定 ,所以现在可以利用外键约束来解决此类问题。在设置外键约束时必须要设置指定外键列(book.mid列)需要和哪张表的哪个列有关联。

  5. 范例:添加外键

    CREATE TABLE  book(
          bid   NUMBER,
          title   VARCHAR2(20),
          mid   NUMBER,
          CONSTRAINTS fk_mid FOREIGN KEY(mid) REFERENCES member(mid)
    );
    
  6. 对外键而言最麻烦的是有一堆的限制。

    限制一:在删除父表之前需要先删除掉它对应的全部子表后才可以删除。

    范例:member是父表,book是子表,如果没删除book,member表是不能够删除的。

    DROP TABLE book;

    因此,先删除book,再删除member

列级约束

create table student(
 stuno number(3) constraint PK_stuno  primary key  ,
 stuname varchar2(10) constraint NN_stuname not null constraint UQ_stuname unique ,
 stuaddress varchar2(20) default '天津'  constraint CK_stuaddress 
 	check(length(stuaddress)>2),
 stubid number(3)
);

insert into student values(1, 'zzz',default,1) ;

表级约束

create table student2(
 stuno number(3) ,
 stuname varchar2(10) ,
 stusex varchar2(10),
 stuaddress varchar2(20) ,
 stubid number(3),
  constraint PK_sno primary key(stuno) , 
  constraint UQ_sname_subid unique(stuname,stubid),
constraint CK_saddress check( length(stuAddress)>2)
);

​ 表级约束只有四个,没有默认和非空 这俩只有列级约束

外键约束补充

  1. 创建课程表

    create table sub(
    	sid  number(3) primary key, 
    	sname   varchar2(10)
    );
    
    
  2. 添加数据

    insert into sub values(1,‘java’);

    insert into sub values(2,‘oracle’);

  3. 创建学生表

    create table student3(
     stuno number(3) ,
     stuname varchar2(10)  ,
     stuaddress varchar2(20) ,
     subid number(3)  ,
     constraint FK_student3_sub foreign key(subid) references sub(sid) 
    );
    
  4. 插入数据:
    insert into student3(stuno,stuname,subid) values(1,‘zs’,1);
    insert into student3(stuno,stuname,subid) values(2,‘ls’,1);
    insert into student3(stuno,stuname,subid) values(3,‘ww’,2);

  5. 尝试插入非法数据:
    insert into student3(stuno,stuname,subid) values(4,‘zl’,3);

    ORA-02291∶违反完整约束条件(SCOTT.FK_STUDENT3_SUB)- 未找到父项关键字

  6. sub表和student3

    在这里插入图片描述

    如果删除父表中 外键所指向列的数据,会报错

    delete from sub where sid=1;

    ORA-02292∶违反完整约束条件(SCOTT.FK_STUDENT3_SUB)- 已找到子记录

级联删除

  1. 先删除原来的学生表

    drop table student3;

  2. 再重新创建学生表,此时再创建表的同时设置级联删除属性

create table student3(
 stuno number(3) ,
 stuname varchar2(10) ,
 stuaddress varchar2(20) ,
 subid number(3) , 
 constraint FK_student3_sub foreign key(subid) references sub(sid) on delete cascade
);

  1. 插入数据

    insert into student3(stuno,stuname,subid) values(1,‘zs’,1);

    insert into student3(stuno,stuname,subid) values(2,‘ls’,1);

    insert into student3(stuno,stuname,subid) values(3,‘ww’,2);

  2. 删除sub表中sid为2的数据

    delete from sub where sid=2 ;

    加了联级删除,如果要删除主表数据的话,则会联动子表数据一起被删除

级联置空

  1. drop table student3;

  2. 再重新创建学生表,此时再创建表的同时设置 级联置空属性

create table student3(
 stuno number(3) ,
 stuname varchar2(10)  ,
 stuaddress varchar2(20) ,
 subid number(3)  , 
 constraint FK_student3_sub foreign key(subid) references sub(sid) on delete set null 
);

  1. 插入数据

    insert into student3(stuno,stuname,subid) values(1,‘zs’,1);

    insert into student3(stuno,stuname,subid) values(2,‘ls’,1);

  2. 删除sub表中sid为1的数据

    delete from sub where sid=1 ;

    加了联级置空,如果要删除主表数据的话,则会联动子表数据被置空

猜你喜欢

转载自blog.csdn.net/qq_52332852/article/details/115234179