Oracle-DDL

表的结构设计

表的创建及管理

对于数据库而言实际上每一张表都表示是一个数据库的对象,而数据库对象指的就是DDL定义的所有操作,例如:表,视图,索引,序列,约束等等,都属于对象的操作,所以表的建立就是对象的建立,而对象的操作主要分为以下三类语法:

  • 创建对象:CREATE 对象名称…;
  • 删除对象:DROP 对象名称…;
  • 修改对象:ALTER 对象名称…;

常用的数据字段

在oracle中,常用的数据类型有以下几种:

  • 字符串 VARCHAR2(n) n表示的是字符串所能保存的最大长度,基本上保存200个左右的内容
  • 整数 NUMBER(n) 表示最多为n位的整数,有时候可以使用INT代替
  • 小数 NUMBER(n,m) 其中m为小数位,n-m为整数位数,有时候可以用FLOAT代替
  • 日期 DATE 存放日期时间
  • 大文本 CLOB 可以存储海量文字(4Gb),例如存储小说等
  • 大对象 BLOB 存放二进制,例如:电影,MP3,图片,文字
    一般在开发之中使用最多的是VARCHAR2()、NUMBER、DATE、CLOB,而对于BLOB数据类型一般使用较少,一是因为会导致数据库过于庞大,一是读取不方便。

表的创建

语法:

CREATE TABLE 表名称(
 字段1 数据类型 [DEFAULT 默认值],
 字段2 数据类型 [DEFAULT 默认值],
   .....
 字段3 数据类型 [DEFAULT 默认值]
);

表的复制

语法:

CREATE TABLE 复制表名称 AS 子查询

查看用户的表

SELECT * FROM TAB;

复制emp表的表结构,不要数据

CREATE TABLE EMPNULL AS SELECT * FROM EMP WHERE 1=2;

该语句只有ORACLE支持,其他数据库可能存在不同的方法。

表重命名

  • 在oracle数据库中,所有的数据实际上都是通过数据字典保存的,如:
    SELECT * FROM TAB;

  • 以上就是一个数据字典。在oracle中,提供了四种类型的数据字典,最常用的是:cdb_、dba_、user_、all_

  • 下面演示一个user_tables数据字典

    SELECT * FROM USER_TABLES;
    

也就是说oracle中的所有数据都是按照文件保存的,那么所有的内容都会在数据字典中注册,所谓的修改表名称实际上就是修改一条数据。

修改表名称

RENAME 旧的表名称 TO 新的表名称;

确认修改完成

SELECT * FROM TAB;

这种方法是oracle数据库所独有,了解即可。

截断表

在之前讲过的删除表数据的操作,使用的是DELETE操作,但是这种删除操作本身有一个特点就是可以进行事务的回滚,也就是说删除之后并不会立即释放数据的资源:

删除表中的数据
DELETE FROM PERSON;

如果现在希望彻底释放一张表所占用的全部资源(表空间,索引等等)就可以使用截断表的语法,语法如下:

TRUNCATE TABLE 表名称

注意:这种语法是oracle所独有。

表的删除

表的删除操作指的是数据库对象的删除,使用DROP语句,语法如下:

DROP TABLE 表名称

闪回技术 flashback

在oracle10g之后,为了预防用户的误删除表操作,专门提供了回收站的功能,用户所删除的表默认情况下会在一个回收站之中保存,而用户也可以通过回收站进行表的恢复,所以此技术称为闪回(FLASHBACK).

查看回收站

SHOW RECYCLEBIN;

这个时候可以发现所有已经删除的表都在回收站之中保存,那么下面就可以使用如下的语法进行表的恢复;

FLASHBACK TABLE 表名称 TO BEFORE DROP;

恢复MYEMP表

FLASHBACK TABLE MYEMP TO BEFORE DROP;

直接删除回收站中的一些数据表

PURGE TABLE 表名称;

清空回收站

PURGE RECYCLEBIN;

删除表的时候进行直接删除,而不进入回收站

DROP TABLE 表名 PURGE;

这种技术是在oracle10g以后才有的。

修改表结构

如果一张建立好的数据表,发现其初期的结构已经不满足后期的使用要求,则可以进行表的修改操作,而表的修改操作实际上就是数据库对象的修改操作,使用ALTER指令完成
CREATE TABLE MEMBER(
MID NUMBER,
NAME VARCHAR2(50)
);

检查表结构

DESC MEMBER;

向表中增加字段

ALTER TABLE 表名称 ADD(列名称 数据类型 [DEFAULT 默认值],
 列名称 数据类型 [DEFAULT 默认值],...);

如果增加的数据列没有默认值,则所有已有的数据的列的内容都是null,而如果增加的列指定了DEFAULT默认值的话,则所有已有的数据列都是设置的默认值。

修改已有的表结构

ALTER TABLE 表名称 MODIFY(列名称 数据类型 [DEFAULT 默认值],
 列名称 数据类型 [DEFAULT 默认值],...);

修改字段名(无数据)

ALTER TABLE 表名称 RENAME COLUMN 原列名称 TO 新列名称;

删除表中字段的默认值

ALTER TABLE MEMEBER MODIFY NAME DEFAULT NULL;

注意:虽然在SQL语法和oracle中都支持修改表结构的操作,但是这种操作有一定的风险,尽可能避免

删除列怎么写

alter table member drop column age;

约束

表建立完成后,并不能检查表中的数据是否合法,如果想要针对表中的数据做一些过滤的话,则可以通过约束完成,约束的主要功能是保证表中的数据合法性,按照约束的分类,一共有五种约束:

  • 非空约束
  • 唯一约束
  • 主键约束
  • 检查约束
  • 外键约束

非空约束/NOT NULL/NK

当数据表中的某个字段上的内容不希望设置为null的话,则可以使用NOT NULL进行指定。

DROP TABLE MEMBER PURGE;
CREATE TABLE MEMBER(
 MID  NUMBER,
 NAME VARCHAR2(20) NOT NULL
);

非空约束保证数据不为空

唯一约束/UNIQUE/UK

唯一约束指的是某一个列上的数据是不允许重复的,如邮件地址。

DROP TABLE MEMBER PURGE;
CREATE TABLE MEMBER(
 MID  NUMBER,
 NAME VARCHAR2(50) NOT NULL,
 EMAIL VARCHAR2(50) UNIQUE
);

该错误信息并不太详细,没有明确说明违反了哪个唯一性约束,所以我们可以通过添加约束,如下:

添加约束条件

DROP TABLE MEMBER PURGE;
CREATE TABLE MEMBER(
 MID  NUMBER,
 NAME VARCHAR2(50) NOT NULL,
 EMAIL VARCHAR2(50),
 CONSTRAINT UK_EMAIL UNIQUE(EMAIL)
);

插入错误的数据:

INSERT INTO MEMBER(MID,NAME,EMAIL) VALUES(3,'WANGWU','ZHANGSAN@163.COM');

插入上面的数据后,提示如下错误:

ORA-00001: unique constraint (SCOTT.UK_EMAIL) violated

自此,约束有了自定义的名字,可以很明确的提示用户。

主键约束/PRIMARY KEY/PK

主键约束=非空约束+唯一约束。在之前设置唯一约束的时候发现可以设置为null,而如果使用了主键约束之后则不能为null,而主键一般作为数据的唯一的一个标记出现。例如人员的编号。
建立主键约束

DROP TABLE MEMBER PURGE;
CREATE TABLE MEMBER(
 MID  NUMBER   PRIMARY KEY,
 NAME VARCHAR2(50) NOT NULL
);

添加约束,并设置约束名称

DROP TABLE MEMBER PURGE;
CREATE TABLE MEMBER(
 MID  NUMBER,
 NAME VARCHAR2(50) NOT NULL,
 CONSTRAINT PK_MID PRIMARY KEY (MID)
);

从开发角度来说,一张表一般都只有一个主键,但是从SQL语法的规定来说,一张表可以设置多个主键,此种做法叫做复合主键,如:
创建复合主键

DROP TABLE MEMBER PURGE;
CREATE TABLE MEMBER(
 MID  NUMBER,
 NAME VARCHAR2(50) NOT NULL,
 CONSTRAINT PK_MID_NAME PRIMARY KEY (MID,NAME)
);

在复合主键的使用之中,只有两个字段的内容都一样的情况下,才被称为重复数据

注意:正常开发情况下,一张表只设置一个主键。

检查约束/CHECK/CK

检查约束指为表中的数据增加一些过滤条件,如:
设置年龄的时候范围为0-250
设置性别的时候为男、女和其他

设置检查约束

DROP TABLE MEMBER PURGE;
CREATE TABLE MEMBER(
 MID  NUMBER,
 NAME VARCHAR2(50) NOT NULL,
 SEX  VARCHAR2(10) NOT NULL,
 AGE  NUMBER(3),
 CONSTRAINT PK_MID PRIMARY KEY (MID),
 CONSTRAINT CK_SEX CHECK (SEX IN ('NAN','NV','QITA')),
 CONSTRAINT CK_AGE CHECK (AGE BETWEEN 0 AND 250)
);

检查的操作就是对输入的数据进行一个过滤。

外键约束

之前的约束都是在单张表中进行的,而外键约束是在两张表中进行的,这两张表是存在父子关系的,即子表中的某个字段的取值范围是由父表所决定。

多个人有多本书,创建数据表
#创建两张表,如下

DROP TABLE MEMBER PURGE;
DROP TABLE BOOK PURGE;
CREATE TABLE MEMBER(
 MID  NUMBER,
 NAME VARCHAR2(50) NOT NULL,
 CONSTRAINT PK_MID PRIMARY KEY (MID)
);
CREATE TABLE BOOK(
 BID  NUMBER,
 TITLE VARCHAR2(50) NOT NULL,
 MID  NUMBER,
 CONSTRAINT PK_BID PRIMARY KEY (BID)
);

统计每个人拥有书的数量

SELECT M.MID,M.NAME,COUNT(B.BID)
FROM MEMBER M,BOOK B 
WHERE M.MID=B.MID
GROUP BY M.MID,M.NAME;

添加外键约束

DROP TABLE MEMBER PURGE;
DROP TABLE BOOK PURGE;
CREATE TABLE MEMBER(
 MID  NUMBER,
 NAME VARCHAR2(50) NOT NULL,
 CONSTRAINT PK_MID PRIMARY KEY (MID)
);
CREATE TABLE BOOK(
 BID  NUMBER,
 TITLE VARCHAR2(50) NOT NULL,
 MID  NUMBER,
 CONSTRAINT PK_BID PRIMARY KEY (BID),
 CONSTRAINT FK_MID FOREIGN KEY (MID) REFERENCES MEMBER(MID)
);

使用外键最大好处是控制了子表中某些数据的取值范围,但是同样带来了不少的问题,如:

只能删除子表记录之后再删除父表记录

如果想在主表数据删除之后,子表中对应的数据也可以删除的话,则可以在建立外键的时候指定一个级联删除的功能,修改数据库创建脚本;

DROP TABLE MEMBER PURGE;
DROP TABLE BOOK PURGE;
CREATE TABLE MEMBER(
 MID  NUMBER,
 NAME VARCHAR2(50) NOT NULL,
 CONSTRAINT PK_MID PRIMARY KEY (MID)
);
CREATE TABLE BOOK(
 BID  NUMBER,
 TITLE VARCHAR2(50) NOT NULL,
 MID  NUMBER,
 CONSTRAINT PK_BID PRIMARY KEY (BID),
 CONSTRAINT FK_MID FOREIGN KEY (MID) REFERENCES MEMBER(MID) ON DELETE CASCADE
);

此时由于存在级联删除的操作,所以主表中的数据删除之后,对应的子表中的数据也都会被同时删除。

删除数据的时候,让子表中对应的数据设置为null

当主表中的数据删除后,对应的子表中的数据相关项希望设置为null,而不是删除。可以继续修改数据库的创建脚本:

DROP TABLE BOOK PURGE;
DROP TABLE MEMBER PURGE;
CREATE TABLE MEMBER(
 MID  NUMBER,
 NAME VARCHAR2(50) NOT NULL,
 CONSTRAINT PK_MID PRIMARY KEY (MID)
);
CREATE TABLE BOOK(
 BID  NUMBER,
 TITLE VARCHAR2(50) NOT NULL,
 MID  NUMBER,
 CONSTRAINT PK_BID PRIMARY KEY (BID),
 CONSTRAINT FK_MID FOREIGN KEY (MID) REFERENCES MEMBER(MID) ON DELETE SET NULL
);
删除父表之前必须先删除对应的子表,否则无法删除

只有先删除子表,再删除父表才可以;

DROP TABLE BOOK PURGE;
DROP TABLE MEMBER PURGE;

但是这样很麻烦,对于未知的数据库,如果要按照这样的顺序来执行,必须知道表之间的父子关系。在oracle中,提供了一个强制性删除表的操作,不再关心约束,如下:

强制删除表,不再关心约束

DROP TABLE MEMBER CASCADE CONSTRAINT PURGE;

这样删除表之后,子表还在。

更好的做法:
在以后进行数据表删除的时候,最好是先删除子表,再删除父表。

修改约束

约束本身也属于数据库对象,那么也肯定可以进行修改操作,而且只要是修改都使用ALTER指令,约束的修改主要指的是以下两种操作:

为表增加约束:
 ALTER TABLE 表名称 ADD CONSTRAINT 约束名称 约束类型(字段);
删除表中的约束
 ALTER TABLE 表名称 DROP CONSTRAINT 约束名称;

如果要维护约束,肯定需要一个正确的名字才可以。(注意非空约束)

创建一张新表,不含约束。

DROP TABLE MEMBER CASCADE CONSTRAINT PURGE;
CREATE TABLE MEMBER(
 MID  NUMBER,
 NAME VARCHAR2(50) NOT NULL,
 AGE  NUMBER(3)
);
为表增加主键约束。
ALTER TABLE MEMBER ADD CONSTRAINT PK_MID PRIMARY KEY(MID);
增加年龄约束
ALTER TABLE MEMBER ADD CONSTRAINT CK_AGE CHECK(AGE BETWEEN 0 AND 250);

执行后产生了如下错误提示:
ORA-02293: cannot validate (SCOTT.CK_AGE) - check constraint violated
因为表中已经存在了违反约束的数据,所以无法添加约束。

删除member表中的mid的主键约束

ALTER TABLE MEMBER DROP CONSTRAINT PK_MID;

跟表结构一样,约束最好不要修改,在表建立的同时一定要将约束定义好,后期使用中建议不要修改。

查询约束

SELECT CONSTRAINT_NAME,SEARCH_CONDITION,TABLE_NAME FROM USER_CONSTRAINTS;
查询部分字段
SELECT OWNER,CONSTRAINT_NAME,TABLE_NAME FROM USER_CONSTRAINTS;

查看查询结果只有约束的名字,而没有约束的是哪个字段

查询另一张数据字典表

SELECT * FROM USER_CONS_COLUMNS;
查看COLUMN_NAME字段,该字段就是约束的字段名称

再次进行查询该表的其他字段

SELECT OWNER,CONSTRAINT_NAME,TABLE_NAME,COLUMN_NAME FROM USER_CONS_COLUMNS;

该查询结果显示不方便查看,使用格式化来调整
COL OWNER FOR A15;
COL CONSTRAINT_NAME FOR A15;
COL TABLE_NAME FOR A15;
COL COLUMN_NAME FOR A15;

SELECT OWNER,CONSTRAINT_NAME,TABLE_NAME,COLUMN_NAME FROM USER_CONS_COLUMNS;

视图

在我们之前学过的所有的SQL语法之中,查询操作是最麻烦的,为了更好更快地使用数据库,我们需要创建视图,视图中包含了一些复杂的SQL语句。

视图创建语法

CREATE [OR REPLACE] VIEW 视图名称
 AS 子查询

使用以下命令放权

GRANT CREATE VIEW TO c##SCOTT;

查询视图

SELECT * FROM MYVIEW;

通过一个简单的视图查询操作,就可以完成之前的复杂SQL语句的功能,所以视图就是包装了的SQL查询操作。

视图存在则替换,不存在则创建

CREATE OR REPLACE VIEW MYVIEW AS 
 SELECT * FROM EMP WHERE DEPTNO=20;

创建视图有两个选项:

选项一:WITH CHECK OPTION

更新条件

UPDATE MYVIEW SET DEPTNO=30 WHERE EMPNO=7369;

查询该视图,发现SMITH用户的信息已不存在,该用户的部门信息已经更改

此时更新的是一张视图,但是视图本身并不是一个具体的数据表,而且现在更新的操作又是视图的创建条件,这样的做法不可取,为了解决这个问题,可以加入WITH CHECK OPTION.

创建一个视图

CREATE OR REPLACE VIEW MYVIEW AS 
 SELECT * FROM EMP WHERE DEPTNO=20
 WITH CHECK OPTION;

再次更新视图的更新操作:

UPDATE MYVIEW SET DEPTNO=30 WHERE EMPNO=7369;
UPDATE MYVIEW SET sal=5000 WHERE EMPNO=7369;

出现以下错误提示:
ORA-01402: view WITH CHECK OPTION where-clause violation
现在已经无法更新视图的创建条件。

选项二:WITH READ ONLY

虽然使用WITH CHECK OPTION可以保证视图的创建条件不被更新,但是其他的字段却允许更新。

更新一个数据

UPDATE MYVIEW SET SAL=9000 WHERE EMPNO=7369;

视图本身不是具体的真实数据,而是一些查询语句,所以这样更新并不合理,据此,我们可以在创建视图的时候建议设置为只读视图。

CREATE OR REPLACE VIEW MYVIEW AS
 SELECT * FROM EMP WHERE DEPTNO=20
 WITH READ ONLY;

以上是一个简单的的操作语句视图,如果视图中的查询语句是统计操作,则根本就不可能更新,如下:

创建一个视图:

CREATE OR REPLACE VIEW MYVIEW AS
 SELECT D.DEPTNO,D.DNAME,D.LOC,COUNT(E.EMPNO) COUNT,AVG(E.SAL) AVG
 FROM EMP E,DEPT D
 WHERE E.DEPTNO(+)=D.DEPTNO
 GROUP BY D.DEPTNO,D.DNAME,D.LOC;

该信息是统计而来的,根本就不可能更新。
项目中,视图的数量可能多于表的数量。

查看视图的字段

desc myview

查看视图具体的定义

SELECT * FROM USER_VIEWS;
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值