创建表的语句和例子

我们用CREATETABLE语句来创建表。该语句为数据定义语言(DDL-Data Definition Language)。它的格式如下:

CREATE TABLE 【用户名.】表名

(列名 数据类型【DEFAULT默认值】【,…】);

您可以使用例10-1的DDL语句来创建表 product。该表是第7章中所得到的3个三范式表中的一个。

例10-1

SQL> CREATE TABLE product

2                        (p_code NUMBER(6),

3                         p_name VARCHAR2(30),

4                        p_desc  VARCHAR2(100),

5                        p_price NUMBER(5,2));

10.2 命名和引用规则

除了上面所述,如果您想在Oracle数据库中创建表的话,还必须指定表名、列名、列的数据类型及数据的长度。您有时也需要指定数据的默认值。

Oracle数据库中的表和列名是以英文字母开头的字母数字序列,其命名遵循如下的规则:

■ 必须以英文字母开头,之后跟大写或小写英文字母,或数字字符,或#,或$,或_。

■ 名字的长度最短为一个字母,最长为30个字符。

一定不能与Oracle数据库系统的保留关键字相同,如例10-3(注:以下DDL语句是在SCOTT用户下发的)。

列的数据类型和默认值

在明白了列的命名规则之后,您一定想知道列的数据类型是如何定义的,以及列可以定义为哪些数据类型?在Oracle数据库中经常使用的数据类型有以下4种:

■ VARCHAR2(size):变长字符型数据。其中:

size为该列最多可容纳的字符个数。Size必须定义。它的默认值和最小值均为1,最大值为4000。

■ CHAR(size):定长字符型数据。其中:

size为该列最多可容纳的字符个数。它的默认值和最小值均为1,最大值为2000。

■ DATE:日期型数据。其中:

日期和时间的取值范围是从公元前1471年1月1日到公元9999年12月31日。

NUMBER(p,s):数字型数据。其中:

p为十进制数的总长度(位数),s为十进制数小数点后面的位数。p的最小值为1,最大值为38,s的最小值为-84,最大值为124。

如果您定义了表中的某一列为变长字符型数据(VARCHAR2),那么当您插入或修改该列时Oracle只把实际的字符存入数据库中,如在例10-1中的product表中有如下的定义:

p_desc VARCHAR2(100)

虽然您定义p_desc的最大长度为100个字符,但是如果您在向该列输入数据时输入的为NEW只为3个字符,Oracle实际上只把‘NEW’这3个字符存入到数据库中。所以使用变长字符型数据(VARCHAR2)会节省空间,特别是当所定义的列的取值范围变化很大时。

如果您定义了表中的某一列为定长字符型数据(CHAR),那么当您插入或修改该列时,Oracle存入数据库中的字符数是由size所定义的,没有数据的部分由Oracle填上空格。如果您将例10-1中p_desc的定义改写如下:

p_desc CHAR(100)

此时您定义p_desc的最大长度为100个字符。如果向这一列输入数据时,如输入的为‘NEW’,只有3个字符,Oracle把‘NEW’这3个字符再加上97个空格共100个字符存入到数据库中。所以使用定长字符型数据(CHAR)会浪费一些空间,特别是当所定义的列的取值范围变化很大时,浪费的空间会很大。

一般来讲,变长字符型数据(VARCHAR2)节省空间,但Oracle处理的速度可能较慢。而定长字符型数据(CHAR)会浪费一些空间,但Oracle处理它的速度可能快一些。对于大多数数据库应用来说,变长字符型数据(VARCHAR2)要比定长字符型数据(CHAR)更有效。但对于那些列的长度没有变化的列,定长数据类型(CHAR)是最好的选择。如性别(gender)只有两个选择:男(M-MALE)或女(F-FEMALE),每种选择都可以用一个字符表示。

除了前面介绍的4种常用的数据类型外,为了处理多媒体对象(LOB-Large Object),Oracle提供了如下的LOB数据类型。

CLOB数据类型(Character Large Object):用于在数据库中存储单字节的大数据对象,如讲演稿或简历等。

BLOB数据类型(Binary Large Object):用于在数据库中存储大的二进制对象,如照片或幻灯片等。

CLOB和BLOB数据类型的列中,许多操作是不能直接使用Oracle的数据库命令来完成的,因此Oracle提供了一个叫DBMSLOB的PL/SQL软件包来维护LOB数据类型的列。

BFILE 数据类型(Binary File):用于在数据库外的操作系统文件中存储大的二进制对象,如电影胶片等。BFILE数据类型是外部数据类型,因此定义为BFILE数据类型的列是不能通过Oracle的数据库命令来操作的,这些列只能通过操作系统命令或第三方软件来维护。

为了提高效率,Oracle 还提供RAW数据类型。

RAW数据类型:在数据库中直接存储二进制数据。此种类型的数据占用的存储空间小,操作效率也高。但在网络环境中不同的计算机上传输资料时,Oracle服务器是不进行任何的字符集转换的。

为了和以前的 Oracle 版本兼容,Oracle 继续支持LONG和LONG RAW数据类型。LONG和LONG RAW数据类型:主要用于在Oracle8以前的数据库中存储无结构的数据。如二进制图像、文本件和地理信息等。

在Oracle8以后的版本,LOB数据类型可以完全取代LONG数据类型,而且Oracle服务器操作LOB数据类型比操作LONG数据类型效率更高。另外您只能在一个表中定义一个LONG数据类型的列,但可以在一个表中定义任意多个LOB数据类型的列。LONG数据类型的列最多可以存储2G的数据,而LOB数据类型的列最多可以存储4G的数据。

注意:|这里的LOB包括了CLOB、BLOB等数据类型,LONG包括了LONG和LONG RAW 数据类型。

利用子查询来创建表

假设您的公司在其他国家或城市有许多个分公司,这些分公司的一些分析员要使用统计软件对 emp 表中的一些列进行大规模的统计分析,这些分析可能需要反复查询 emp 表,假设 emp 表存有一百多万行数据,如果这些分析员都访问总公司的 Oracle 服务器上的表emp的话,网络的流量可能会非常大,这样对网络压力和对总公司的Oracle服务器的压力都会很大,系统的整体效率会大幅度下降。

在这种情况下,您可以为他们生成一个临时的表worker,该表只包含了他们所需要的列和记录。之后把这个表传到他们本地的计算机上,这样可以在很大程度上减轻网络和总公司的Oracle服务器的压力,从而使系统的整体效率大为改进。您可以使用类似于例10-16 的DDL命令来建立worker这个表。

例10-16

SQL> CREATE TABLE worker

2 AS

3 SELECT empno, ename name,job, sal+NVL(comm,0) income 4 FROM emp

5 WHERE job NOT IN ('MANAGER','PRESIDENT');

使用子查询来创建表的语句格式如下:

CREATE TABLE 表名【(列名,列名…)】

AS 子查询;

使用子查询来创建表时需要注意如下事项:

(1)Oracle使用您所指定的列和表名来创建表,所有的行(记录)是由子查询得到的,并插入到该表中。

(2)所说明的列名的个数一定要和子查询列的个数相同。

(3)所说明的每一列的数据类型必须与子查询的每一列的数据类型相匹配。(4)所说明的列名必须符合列的命名规则。

(5)如果没有给出列名,列名与子查询中的列名相同,而且列的个数和子查询列的个数也相同。

修改表的结构

Oracle在ALTERTABLE语句中提供了以下4种修改表结构的子语。

(1)在一个表中加入一个新的列。它的格式如下:

ALTER TABLE表名

(列名 数据类型 【DEFAULT 表达式】

ADD

【,列名 数据类型】…);

您没有办法指定您所加入的列的位子,新的列永远为最后一列。

例10-19

SQL> ALTER TABLE worker

2 ADD        (hiredate DATE);

(2)修改在一个表中已经存在的列,其格式如下:

ALTER TABLE 表名

MODIFY (列名 数据类型 【DEFAULT 表达式】【,列名 数据类型】…);

修改一个表中已经存在的列要注意以下的事项:

■ 可以增加字符类型的列的宽度。

■ 可以增加数字类型的列的宽度和精度。

■ 只有当所有列的值都为空或者表中没有数据时,才可以减少列的宽度。只有当所有列的值都为空时,才可以改变某一列的数据类型。

如果改变某一列的默认值,该默认值只影响以后的操作。

只有当某一列的值为空或者没有改变该列大小的情况下,才可以把CHAR类型的列改变成VARCHAR2类型的列,或把VARCHAR2类型的列改变成CHAR类型的列。

例10-21

SQL> ALTER TABLE worker

2 MODIFY (hiredate DEFAULT SYSDATE);

(3)从一个表中删除一列,其格式如下:ALTER TABLE表名DROP COLUMN 列名;

删除一个表中已经存在的列要注意以下的事项:

■ 使用以上的ALTER TABLE 语句,一次只能删除一列。

■ 在使用以上的ALTER TABLE语句删除了一列之后,该表中必须至少还有一列。

因为ALTER TABLE语句是DDL语句,所以所删除的列是无法被恢复的。所删除的列可以包含数据也可以不包含数据。该语句只能在Oracle8i和以上的版本上使用。

例10-27

SQL> ALTER TABLE worker

2 DROP COLUMN hiredate;

在一个表中删除一列,特别是在一个大表中删除一列是相当耗时的,对系统的效率冲击也很大。所以应尽可能地避免在数据库繁忙期间使用上述DDL语句。如果现在数据库特别繁忙,而就在此时您的老板让您立即删除某一个大表中的一列。您该如何处理呢?Oracle 提供了一个折衷的方案,就是在ALTERTABLE语句中使用SET UNUSED子语。

(4)在一个表中把某一列置成无用(UNUSED),其格式如下:

ALTER TABLE表名SET UNUSED(列名);或ALTER TABLE表名

SET UNUSED COLUMN 列名;

当数据库空闲时,您再利用以下的DDL语句来删除已设置为无用(UNUSED)的列。

ALTER TABLE表名

DROP UNUSED COLUMNS

使用SET UNUSED把表中的一列设置成无用(UNUSED)要注意以下的事项;

该选项只能在Oracle8i和以上的版本上使用。

该选项只是将设置成无用(UNUSED)的列标上记号,并不真的删除这一列。

在由该选项设置成无用(UNUSED)的列里,无法用SQL*PLUS 命令或SQL语句看到。

Oracle把设置成无用(UNUSED)的列当作删除列处理。可以把一列也可以把多列设置成无用(UNUSED)。

可以使用DROP(UNUSED)列名选项来删除被设置成无用(UNUSED)的列。因为该语句是一个DDL语句,所以没有恢复无用(UNUSED)列的命令。

例10-29

SQL> ALTER TABLE worker

2 SET UNUSED (income);

 改变对象的名字

什么是数据库中的对象?Oracle数据库中的对象是一个存储在Oracle数据库中的数据结构。一个Oracle数据库中可以存有多种对象。这些对象的定义被存在Oracle数据库的数据字典中。常用的对象有以下5种:

(1)表(Table):存储数据的基本单位,由行和列组成。

(2)索引(Index):为了改进某些查询性能的数据结构。

(3)视图(View):来自一个或多个表的数据子集。

(4)序列(Sequence):数值生成器。

(5)同义词(别名)(Synonym):赋予对象另外的名字。

我们已经详细地介绍了表(Table)对象。其他的4种对象我们将在后续的几章中做详细介绍。除了以上提到的5种对象外,Oracle数据库中还包括存储过程(Procedure)、函数(Function)、触发器(Trigger)等对象。这些内容是在PL/SQL程序设计的课程中介绍的。

如果您在创建某一个对象时考虑不周,对象的名字取得不合适,您可以使用Oracle的RENAME 语句来修改对象的名字。RENAME语句的格式如下:

RENAME 对象原来的名字 对象现在的名字;

只有对象的主人才可以修改对象的名字。

例10-33

SQL> RENAME worker to staff;

注意:

如果您修改了一个对象的名字,那么使用该对象的软件或对象需要重新编译或修改,这可能会对系统的效率产生冲击。

为表和列加注释

按照软件工程的设计方法,当您在设计和开发一个软件系统时,您应该写下完整的文档和注释。Oracle允许您使用COMMENT语句来为表或列添加注释。COMMENT语句的格式如下:

COMMENT ON TABLE 表名|COLUMN 表名.列名IS '正文';

您可以使用例10-37那样的SQL语句在staff表上添加注释。

例10-37

SQL> COMMENT ON TABLE staff

2 IS 'Are you believed comments canhelp you to understand the designs?';

例10-38

SQL> SELECT comments

2 FROM user tab_comments

3 WHERE table name = 'STAFE';

例10-39

SQL> COMMENT ON COLUMN staff.job

2 IS 'If your answer is yes,you will meet a big trouble';

例10-40

SQL> SELECT comments

2 FROM user_col_comments 3 WHERE table_name = 'STAFF'4 AND

column_name = 'J0B';

Oracle没有提供如何从数据库中删除注释的语句。但您可以通过加入空串的方式来从数据库中删除一条注释。您可以使用例10-41的语句来删除staff表中的iob列上的注释。

例10-41

SQL> COMMENT ON COLUMN staff.job

2 IS '';

截断表和删除表

当一个表中的数据已经不再需要时,可以使用TRUNCATE TABLE 语句将它们全部删除掉(截断)。该语句为DDL语句。

TRUNCATE TABLE 语句的格式如下:TRUNCATE TABLE 表名;

TRUNCATE TABLE 语句有如下的特性:

■ 它删除表中所有的数据行,但保留表的结构。

■ 如果没有备份的话,所删除的数据行无法恢复。

■ 该语句释放表所占用的磁盘空间。

■ 它并不触发(运行)表的删除触发器。

如果您不但要删除表中的数据而且还要删除表的结构,您应该使用DROPTABLE语句。该语句也为DDL语匀。

DROP TABLE 语句的格式如下:

DROP TABLE 表名;

DROPTABLE 语句有如下的特性:

■ 它删除表中所有的数据行和表的结构。

■ 它也删除表的所有索引(Indexes)。

■ 如果没有备份的话,所删除的表无法恢复。

■ 它提交所有的挂起的事务(我们将在后面章节中介绍事务处理)。

■ 所有基于该表的视图(Views)和别名(Synonyms)依然保留但已无效。

注意:|TRUNCATE TABLE和 DROP TABLE 语句是非常危险的语句,因为如果使用不当的话,可能会丢失大量宝贵的数据。尽管如此,Oracle还假设使用这两个语句的人是专家,即使用这些语句的人知道他们在做什么和所产生的后果.Oracle只检查用户的权限和语句的语法,如果它们没有问题,Oracle就会忠实地执行用户所发的语句而且没有任何提示。因此建议:在使用这两个语句之前最好做备份。

如果您曾读过其他类似的书,可能会发现本书的这一部分的内容似乎比其他同类书籍的内容多。这是因为我个人认为表是数据库中最重要的对象,因为只有表中存有数据。所谓的数据库设计就是表的设计。它包含了表的结构(列和列数据类型等)的设计,以及表与表之间的关系(主键和外键)设计。另外数据库中的备份和恢复也是针对表的,因为在数据库中真正需要保护的是数据,而只有表中存储着数据.

你可能感兴趣的:(sql,数据库,sql,mysql)