
4.2 创建表
本节从实用的角度介绍如何创建一个表以及如何使得创建的表易于管理。我们先介绍Oracle创建表的规则,并通过实例说明如何创建一个表。
4.2.1 Oracle创建表的规则
Oracle数据库推荐了一些与表相关的标准,读者在实际中最好使用这些标准,对于维护数据库表和顺利建表都很有好处。
● 命名尽量简单,表名要具有一定的意义,即表名要清楚描述表中存储的数据内容,如一个临时员工表的表名为temp_employees。
● 每个表都有一个表空间,这样易于管理和维护,对一个表空间的维护不影响其他的表,并且该表空间是本地管理的。
● 使用标准EXTENT尺寸减少表空间碎片。
● Oracle数据库允许表名的最大长度为30个字符。
4.2.2 创建普通表
创建数据库的目的是存储数据,而这些数据就存储在表中,表是数据库中最基本的数据存储结构。下面我们使用CREATE TABLE指令来创建表。
要创建表,用户必须就要创建表的属性,此时,我们使用dba用户登录数据库服务器,如例子4-2所示。
例子4-2 使用dba用户登录数据库服务器
SQL> conn /as sysdba 已连接。
接下来创建一个临时员工表,该员工表属于SCOTT用户,并且存储在USERS表空间中,如例子4-3所示。
例子4-3 创建一个临时员工表temp_employees
SQL> create TABLE scott.temp_employees 2 (employee_id number(4), 3 employee_name varchar(30), 4 employee_sex char, 5 department varchar(30)) 6 TABLEspace users; 表已创建。
一旦使用DDL语句创建了表对象,对象的信息如表名,表存储的表空间等将记录在数据字典中,数据字典将在第7章讲,这里只需要读者知道这个概念,例子4-3中创建表的信息将记录在数据字典dba_tables中。下面使用例子4-4验证是否成功创建该表。
例子4-4 验证例子4-3中是否成功创建表TEMP_EMPLOYEES
SQL> select owner,table_name,tablespace_name 2 from dba_tables 3 where owner = 'SCOTT'; OWNER TABLE_NAME TABLESPACE_NAME ------------------------------ ----------------------------------------------------- ---------------------------- SCOTT BONUS USERS SCOTT DEPT USERS SCOTT DEPT_TEMP SYSTEM SCOTT EMP USERS SCOTT EMP_TEMP SCOTT ORD SYSTEM SCOTT PRODUCT SYSTEM SCOTT SALGRADE USERS SCOTT SUPPLIER SYSTEM SCOTT TEMP_EMPLOYEES USERS 已选择10行。
输出结果的最后一行说明,已经成功创建了表TEMP_EMPLOYEES,该表所属的用户为SCOTT,而存储该表的表空间为USERS。
说明
如果在创建表时不指定用户名字,直接写表名,则默认是当前用户创建的表,如果不指定表空间名,则Oracle将使用默认表空间创建该表。
在创建表的原则中,Oracle推荐了一个表最好放在一个表空间而且该表空间是本地管理的(减少维护数据字典的负担),所以如果我们已经创建了一个本地管理的表空间,可以使用更多的参数在本地管理的表空间中创建表,在Oracle10g中创建的表空间,本地管理是默认方式。如例子4-5所示,我们先创建一个本地管理的表空间lin,然后再在该表空间中创建一个表。
例子4-5 创建一个本地管理的表空间lin
SQL> create TABLEspace lin 2 datafile 'd:\temp\lin.dbf' 3 size 30M 4 extent management local 5 uniform size 1M; 表空间已创建。 SQL> create TABLE scott.employees 2 (ecode number(4), 3 ename varchar2(25), 4 eaddress varchar2(30), 5 ephone varchar2(15)) 6 storage (initial 100k next 100k pctincrease 0 minextents 1 7 maxextents 8) 8* TABLEspace lin 表已创建。
这里需要解释storage中的参数含义,initial指对于该表而言,当表的数据量增加时,需要的自动分配磁盘空间第一次分配100KB,第二次也是100KB,所分配的最大磁盘为8个EXTENTS。最小为1个EXTENTS,而PCTINCREASE是一个权值参数,指当第三次为该表增加磁盘空间时,需要按规则计算:NEXT*(1+PCTINCRASE/100)(n-2),其中n>=3,即如果第三次需要增加磁盘空间时,分配100*(1+0/100)(3-2)=100K,第四次需要增加磁盘空间时,分配100*(1+0/100)(4-2)=100K,可以看出如果选择PCTINCRASE为0,则每次分配的磁盘空间和NEXT参数值相同。
下面使用例子4-6,验证是否成功建立表employees。
例子4-6 验证是否成功建立表employees
SQL> select TABLE_name,TABLEspace_name ,initial_extent,next_extent 2 from dba_TABLEs 3 where owner = 'SCOTT' 4 and TABLE_name = 'EMPLOYEES'; TABLE_NAME TABLESPACE_NAME INITIAL_EXTENT NEXT_EXTENT ------------------------- ----------------------------------- ------------ -------------- ------------------- EMPLOYEES LIN 102400 1048574
上述输出说明,表employees已经成功创建,并且在表空间Lin中,该表的参数INITIAL_EXTENT为100KB(102400/100 = 100KB),而且NEXT_EXTENT也为100KB。
4.2.3 创建临时表
临时表是非常特殊的表,该表只对当前用户的当前会话有效。创建临时表的目的就是使得某些操作效率更高。临时表中的数据是当前会话的私有数据,当前会话只操作自己的数据,没有数据锁的争用,这极大地提高了临时表操作的效率。下面依次对创建临时表和临时表的可见性做详细介绍。
下面通过使用CREATE GLOBAL TEMPORARY指令来创建临时表。如例子4-7所示,该临时表为SCOTT用户的EMP表中所有JOB为MANAGER的员工信息。
例子4-7 使用CREATE GLOBAL TEMPORARY指令来创建临时表
SQL> create global temporary TABLE 2 scott.emp_temporary 3 on commit preserve rows 4 as 5 select * 6 from scott.emp 7 where job = 'MANAGER'; 表已创建。
注意
该临时表默认存储在系统的临时段中,如果临时表空间为空,也无法创建成功,会有如下错误提示。
SQL> create global temporary TABLE 2 scott.emp_temporary 3 on commit preserve rows 4 as 5 select * 6 from scott.emp 7 where job = 'MANAGER'; from scott.emp * ERROR 位于第 4 行: ORA-25153: 临时表空间为空
遇到这样的问题,只要新建立一个临时表空间,然后改变系统的临时表空间为新建立的表空间即可。
读者可以根据例子4-8验证是否成功创建该临时表。
例子4-8 验证是否成功创建该临时表
SQL> select owner,TABLE_name,TABLEspace_name 2 from dba_TABLEs 3 where TABLE_name = 'EMP_TEMPORARY'; OWNER TABLE_NAME TABLESPACE_NAME -------------------- -------------------- ---------------------------- ---------------------------- SCOTT EMP_TEMPORARY
输出结果中TABLESPACE_NAME列为空,说明临时表并不存放在默认表空间,也不存放在临时表空间中,而是存储在临时段中,临时段是一个磁盘区,当用户使用SQL语句执行查询时,如果需要对返回的数据进行排序,Oracle首先需要在内存中完成排序工作,如果内存容量不够,就需要把计算的中间结果放在临时段中。
例子4-9 查询表EMP_TEMPORARY是否为临时表
SQL> select table_name,tablespace_name,temporary 2 from dba_tables 3 where owner = 'SCOTT' 4 and table_name = 'EMP_TEMPORARY'; TABLE_NAME TABLESPACE_NAME T ------------------------------------ ------------------------------------------------------- EMP_TEMPORARY Y
例子4-9的输出说明,表EMP_TEMPORARY为临时表,而且该表没有存放在用户SCOTT的默认表空间中,而是存储在临时段中。
临时表在当前用户的当前会话下可用。如果用户使用其他用户登录如使用dba用户,或者重新启动了数据库,则无法使用该临时表。例子4-10说明了当使用相同的用户名,如SYS用户重新登录数据库时,查询临时表emp_temporary的输出结果。
例子4-10 查询临时表emp_temporary的输出结果
SQL> conn /as sysdba 已连接。 SQL> desc scott.emp_temporary; 名称 是否为空? 类型 --------------------------------------------- -------- ------------- EMPNO NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NUMBER(2) SQL> select * 2 from emp_temporary; from emp_temporary * ERROR 位于第 2 行: ORA-00942: 表或视图不存在
上例说明,使用DBA(用户名为SYS)用户重新登录数据库时,可以查看到临时表emp_temporary的数据字典定义,但是不能成功查询该表中的数据。也就是说临时表只对当前用户的当前会话有效,一旦用户退出当前会话,则临时表就失去了作用。
如果不再使用临时表,则最好删除,毕竟它占用存储空间,而且一旦用户改变或重新登录,都无法重新使用该表,如例子4-11所示为删除临时表。
例子4-11 删除临时表
SQL> DROP TABLE scott.emp_temporary; 表已丢弃。