Teradata 中表的分类及其各类型表应该注意的问题总结
SQL:
select *
from (
select
deptno
,sum(sal)
from emp
group by deptno
)
上面sql 在oracle 能执行,但是在Teradata不能执行,为什么?
我们先看看Teradata中表的分类:
n 永久表
n 临时表
全局临时表(Global Temporay Table)
可变临时表(Volatile Temporay Table)
导出表(Derived Table)
n 永久表
下面是一张永久表的建表语句(括弧中红色关键字为可选项):
CREATE MULTISET(SET) TABLE test.demo ,NO FALLBACK ,
NO BEFORE JOURNAL,
NO AFTER JOURNAL
(
i1 INTEGER,
c1 CHAR(10) CHARACTER SET LATIN NOT CASESPECIFIC,
d1 DECIMAL(4,2),
da1 DATE FORMAT 'YYYY-MM-DD',
)
(Unique) PRIMARY INDEX ( i1 )
PARTITION BY RANGE_N(da1 BETWEEN
DATE '2004-01-01' AND DATE '2004-12-31' EACH INTERVAL '1' DAY ,
NO RANGE OR UNKNOWN);
上面建表语句中应该注意的几点:
1、MultiSet和Set的区别:
n MultiSet
¨ 可以插入完全相同的两条记录
¨ 会提高数据插入的速度
n Set
¨ 不可以插入完全相同的两条记录
¨ 保证记录的唯一性
¨ 由于需要查重处理,会降低数据插入的速度
¨ 可以作为一种去重的方法
2、 Note: If a UPI is selected on a SET table, the duplicate row check is replaced by a check for duplicate index values.
3、 表名不能超过30位.
4、 永久表-字符大小写问题
例一:创建scott.emp的ename字段为大小写不敏感:
ename CHAR(10) CHARACTER SET LATIN NOT CASESPECIFIC
select * from scott.emp where ename = 'FAN'; --直接查询将不区分大小写
select * from scott.emp where ename(CASESPECIFIC) = 'FAN';--使用关键字CASESPECIFIC将区分大小写
例二:创建scott.emp的ename字段为大小写敏感:
ename CHAR(10) CHARACTER SET LATIN CASESPECIFIC
select * from scott.emp_case where ename = 'FAN'; --直接查询将区分大小写
下面两个查询不区分大小写:
select * from scott.emp_case where ename(not CASESPECIFIC) = 'FAN';
select * from scott.emp_case where upper(ename) = 'FAN';
n 导出表
特点:
n 对查询是本地的 - 存在于整个查询期间,查询结束后,表被丢掉。
n 并入SQL查询的语法。
n 查询完成后,Spool缓冲区的记录被丢掉。
n 不使用数据字典 - 减少系统负载。
例子:select * from
(select deptno,sum(sal) as sal_sum from scott.emp group by deptno)tmp
注意点:导出表需要表名,进行运算的字段需要别名,上面sql可写成下面形式:select * from
(select deptno,sum(sal) from scott.emp group by deptno)tmp(deptno,sal_sum)
n 可变临时表
与导出表的相似之处:
n 在spool缓冲区中物化。
n 不使用数据字典和交易锁
n 在cache中保留表的定义。
n 用于优化性能
与导出表的不同:
n 是本地的会话(session),而不是查询。
n 在一个会话中,能够被多个查询使用。
n 可以随时被手动删除,会话结束时自动删除。
n 使用 CREATE VOLATILE TABLE语句创建。
例子:
形式1:CREATE VOLATILE MULTISET TABLE wt_i ,NO LOG as ${PDDL}.$table_target WITH NO DATA
ON COMMIT PRESERVE ROWS;
形式2:CREATE VOLATILE MULTISET TABLE wz_h , NO LOG as ${EBIDB}.$table_target WITH NO DATA
PRIMARY INDEX (Record_Dt ,Org_Id)
ON COMMIT PRESERVE ROWS;
形式3:CREATE VOLATILE MULTISET TABLE wcn_b ,NO log
( Pty_Id VARCHAR(50) not NULL
…
,Close_Dt DATE not NULL)
PRIMARY INDEX (Pty_Id)
ON COMMIT PRESERVE ROWS;
注意点:
n MULTISET:默认为 SET;
n NO LOG:默认为 LOG,LOG指示维护交易日志,NO LOG的性能更好;
n ON COMMIT PRESERVE ROWS:默认为ON COMMIT DELETE ROWS;
n PI:根据Join的连接条件设置PI,连接性能更好;
n 一个会话中,最多有64个可变临时表
n 不同会话可以使用同样的可变临时表名称 (因为可变临时表是属于本地会话的)
n 全局临时表
全局临时表与可变临时表有不同的地方:
n 基础定义是永久的,保存在数据字典中。
n 要物化表,要有相应SQL的权限。
n 空间要占用用户的“临时空间(temporary space)”。
n 每个会话最多可以物化32个全局临时表。
n 系统重启动后,还存在。
全局临时表与可变临时表有相似的地方:
n 对会话而言,每个实例是本地的。
n 会话结束后,物化的表被自动删除。(但基础定义仍然存储在数据字典中)
n 都有LOG 和ON COMMIT PRESERVE/DELETE选项。
n 物化表中内容与其他会话不共享。
n 在会话开始时,表被清空。
建表:CREATE GLOBAL TEMPORARY MULTISET TABLE scott.gt_deptsal
(deptno SMALLINT
,avgsal DEC(9,2)
,maxsal DEC(9,2)
,minsal DEC(9,2)
,sumsal DEC(9,2)
,empcnt SMALLINT)
PRIMARY INDEX (deptno)
ON COMMIT PRESERVE ROWS;
查数据字典:select * from dbc.tables where tablename = 'gt_deptsal'
物化表:insert into scott.gt_deptsal values (22,33,33,22,22,22);
查询物化表:物化后DBC.TempTables 表会存在一条表记录,物化表drop后记录删除:
select * from DBC.TempTables;