2007年01月16日

2006年  包含着 浮躁、焦虑、收获

浮躁:年轻不可避免的问题。在工作、生活中无法克制住这样的

心情,不能冷静客观的分析事情。
焦虑:对未来的焦虑。职业生涯的持续发展、工作的稳定性、收

入的提升。有压力就会有动力。可是有时我有一种莫名的焦虑,

为了生存而焦虑。
收获:我有了自己的下一代,我的女儿(儿子)就要出世了。希

望她(他)能带有感激心情来面对父母和这个世界。感谢父母给

了她(他)一次生命,一次为实现自己理想和愿望而奋斗的机会

。而不是过多的无偿索取,不奉献、不劳作。真的希望她(他)

有《洗澡堂家的男人们》这个电视剧中的主人公这样的心态。再

一个收获,今年我投资收益(80%)。

真的很感谢我的老婆!!!  可能她看不到这个文章,但是2006

年她为我做了不少,在有能力的情况下,一定要多实现她的愿望

我一直以《洗澡堂家的男人们》中家中长子作为自己孝敬父母的

榜样。希望父母能安度晚年。

2007年展望

1、性格和心态的培养
耐心和恒心。 做任何事情都需要耐心和恒心。只有这样你才能

成功。知道和做到是有很大差距的,不断告诫自己耐心、务实、

坚持。工作中耐心解决每一个问题,耐心对待同事和客户;耐心

对待家庭中每一人,使他们能感受到我的关心;耐心面对挫折、

失望、焦虑。找寻出路。
2、理财
将理财进行到底。说回来还是心态的培养。心态和性格决定你的

收益。‘投资’非‘投机’。确立一个有效的筛选机制,长期持

有,获取收益。2007年目标,投资收益(20%),截至2006年12

月31日前的资产价值。
3、责任
作为儿女承担的责任、作为丈夫承担的责任、作为父亲承担的责

任、作为兄弟承担的责任… …

都需要我耐心、耐心、再耐心

2006年10月26日

—-同行业对比分析

—-财务报表

—-业务分析

—-行业分析

—-企业盈利能力分析

—-基本面分析

 

 

———摘自《21世纪经济报道》

银行业:

1、资本充足率                  12%以上  (国际标准)

2、资产收益率 ROA        20%左右  (国际标准)

3、股权收益率 ROE       1.5~2         (国际标准)

 

银行的零售业务主要包括:消费信贷、个人理财、银行卡、零售类中间业务等

2006年10月24日

  问:每年投资收益20%,复利方式。当初投资1万元40年后的本息?(不要使用电子设备)

  :)   答案是“梦”

 

  “股神”投资理财思路之一,一生只买卖12次股票。为什么这样说?

 

 

  投资和投机?怎样区分?

 

 我应该怎样选择,为什么做这样投资?为什么会买这样的股票?

 依据!!!

 

 

 

2006年07月11日

Oracle物理结构故障是指构成数据库的各个物理文件损坏而导致的各种数据库故障。这些故障可能是由于硬件故障造成的,也可能是人为误操作而引起。所以我们首先要判断问题的起因,如果是硬件故障则首先要解决硬件问题。在无硬件问题的前提下我们才能按照下面的处理方发来进一步处理。

  控制文件损坏:

  控制文件记录了关于oracle的重要配置信息,如数据库名、字符集名字、各个数据文件、日志文件的位置等等信息。控制文件的损坏,会导致数据库异常关闭。一旦缺少控制文件,数据库也无法启动,这是一种比较严重的错误。

  损坏单个控制文件:

  1. 确保数据库已经关闭,如果没有用下面的命令来关闭数据库:

  svrmgrl>shutdown immediate;

  2. 查看初始化文件$ORACLE_BASE/admin/pfile/initORCL.ora,确定所有控制文件的路径。
 
  3. 用操作系统命令将其它正确的控制文件覆盖错误的控制文件。

  4. 用下面的命令重新启动数据库:

  svrmgrl>startup;

  5. 用适当的方法进行数据库全备份。

  损坏所有的控制文件:

  1. 确保数据库已经关闭,如果没有用下面的命令来关闭数据库:

  svrmgrl>shutdown immediate;

  2. 从相应的备份结果集中恢复最近的控制文件。对于没有采用带库备份的点可以直接从磁带上将最近的控制文件备份恢复到相应目录;对于采用带库备份的点用相应的rman脚本来恢复最近的控制文件。

  3. 用下面的命令来创建产生数据库控制文件的脚本:

svrmgrl>startup mount;

svrmgrl>alter database backup controlfile to trace noresetlogs;

  4. 修改第三步产生的trace文件,将其中关于创建控制文件的一部分语句拷贝出来并做些修改,使得它能够体现最新的数据库结构。假设产生的sql文件名字为createcontrol.sql.

  注意:

  Trace文件的具体路径可以在执行完第3步操作后查看$ORACLE_BASE/admin/bdump/alert_ORCL.ora文件来确定。

  5. 用下面命令重新创建控制文件:

  svrmgrl>shutdown abort;

  svrmgrl>startup nomount;

  svrmgrl>@createcontrol.sql;

  6. 用适当的方法进行数据库全备份。

  重做日志文件损坏:

  数据库的所有增、删、改都会记录入重做日志。如果当前激活的重做日志文件损坏,会导致数据库异常关闭。非激活的重做日志最终也会因为日志切换变为激活的重做日志,所以损坏的非激活的重做日志最终也会导致数据库的异常终止。在ipas/mSwitch中每组重做日志只有一个成员,所以在下面的分析中只考虑重做日志组损坏的情况,而不考虑单个重做日志成员损坏的情况。

  确定损坏的重做日志的位置及其状态:

  1. 如果数据库处于可用状态:

  select * from v$logfile;

  svrmgrl>select * from v$log;

  2. 如果数据库处于已经异常终止:

  svrmlgr>startup mount;
  svrmgrl>select * from v$logfile;
  svrmgrl>select * from v$log;

  其中,logfile的状态为INVALID表示这组日志文件出现已经损坏;log状态为Inactive:表示重做日志文件处于非激活状态;Active: 表示重做日志文件处于激活状态;Current:表示是重做日志为当前正在使用的日志文件。

  损坏的日志文件处于非激活状态:

  1. 删除相应的日志组:

  svrmgrl>alter database drop logfile group group_number;

  2. 重新创建相应的日志组:

  svrmgrl>alter database add log file group group_number (’log_file_descritpion’,…) size log_file_size;

  损坏的日志文件处于激活状态且为非当前日志:

  1. 清除相应的日志组:

  svrmgrl>alter database clear unarchived logfile group group_number;

  损坏的日志文件为当前活动日志文件:

  用命令清除相应的日志组:

  svrmgrl>alter database clear unarchived logfile group group_number;

  如果清除失败,则只能做基于时间点的不完全恢复。

  打开数据库并且用适当的方法进行数据库全备份:

  svrmgrl>alter database open;

  部分数据文件损坏:

  若损坏的数据文件属于非system表空间,则数据库仍然可以处于打开状态可以进行操作,只是损坏的数据文件不能访问。这时在数据库打开状态下可以单独对损坏的数据文件进行恢复。若是system表空间的数据文件损坏则数据库系统会异常终止。这时数据库只能以Mount方式打开,然后再对数据文件进行恢复。可以通过查看数据库日志文件来判断当前损坏的数据文件到底是否属于system表空间。

  非system表空间的数据文件损坏

  1. 确定损坏的文件名字:

  svrmgrl>select name from v$datafile where status=’INVALID’;

  2. 将损坏的数据文件处于offline状态:

  svrmgrl>alter database datafile ‘datafile_name’ offline;

  3. 从相应的备份结果集中恢复关于这个数据文件的最近的备份。对于没有采用带库备份的点可以直接从磁带上恢复;对于用带库备份的点用相应的rman脚本来恢复。

  4. 恢复数据文件:

  svrmgrl>alter database recover datafile ‘file_name’;

  5. 使数据库文件online:

  svrmgrl>alter database datafile ‘datafile_name’ online;

  6. 用适当的方法进行数据库全备份。

  system表空间的数据文件损坏:

  1. 以mount方式启动数据库

  svrmgrl>startup mount;

  2. 从相应的备份结果集中恢复关于这个数据文件的最近的备份。对于没有采用带库备份的点可以直接从磁带上恢复;对于用带库备份的点用相应的rman脚本来恢复。

  3. 恢复system表空间:

  svrmgrl>alter database recover datafile ‘datafile_name’;
 
  4. 打开数据库:

  svrmgrl>alter database open;

  5. 用适当的方法进行数据库全备份。

  表空间损坏:

  若非system表空间已经损坏,则数据库仍然可以处于打开状态可以进行操作,只是损坏的表空间不能访问。这样在数据库打开状态下可以单独对损坏的表空间进行恢复。若是system表空间损坏则数据库系统会异常终止。这时数据库只能以Mount方式打开,然后再对表空间进行恢复。可以通过查看数据库日志文件来判断当前损坏的表空间是否是system表空间.

  非system表空间损坏:

  1. 将损坏的表空间处于offline状态:
 
  svrmgrl>alter tablespace ‘tablespace_name’ offline;

  2. 从相应的备份结果集中恢复关于这个表空间最近的备份。对于没有采用带库备份的点可以直接从磁带上恢复;对于用带库备份的点用相应的rman脚本来恢复。

  3. 恢复表空间:

  svrmgrl>alter database recover tablespace ‘tablespace_name’;

  4. 使表空间online:

  svrmgrl>alter tablespace ‘tablespace_name’ online;

  5. 用适当的方法进行数据库全备份.

  system表空间损坏:

  1. 以mount方式启动数据库

  svrmgrl>startup mount;

  2. 从相应的备份结果集中恢复system表空间最近的备份。对于没有采用带库备份的点可以直接从磁带上恢复;对于用带库备份的点用相应的rman脚本来恢复。

  3. 恢复system表空间:

  svrmgrl>alter database recover tablespace system;

  4. 打开数据库:

  svrmgrl>alter database open;

  5. 用适当的方法进行数据库全备份。

  整个数据库的所有文件损坏:

  整个数据库所有文件的损坏一般是在共享磁盘阵列发生无法恢复的灾难时才发生,这种情况下只能对数据库进行恢复。若数据库的归档目录也已经丢失,则数据库不可能做完全恢复,会有用户数据的丢失。

  没采用带库备份的现场:

  1. 将最近的备份从磁带上把各个文件解包到相应的目录下。

  2. 以mount方式打开数据库:
 
  svrmgrl>startup mount;

  3. 恢复数据库:

  svrmgrl>recover database until cancel;

  4. 打开数据库:

  svrmgrl>alter database open resetlogs;

  5. 用适当的方法进行数据库全备份。

  采用带库备份的现场:

  1. 以nomount方式打开数据库:

  svrmgrl>startup nomount;

  2. 通过相应的rman脚本进行数据库软恢复。

  $rman cmdfile=hot_database_restore.rcv

  3. 打开数据库:

  svrmgrl>alter database open resetlogs;

  4. 用适当的方法进行数据库全备份。

  存在最近的数据库完整冷备份前提下的一些经典紧急情况的处理:

  数据文件,归档重作日志和控制文件同时丢失或损坏:

  无新增archives 时的状况:
 
  条件和假设:自上次镜像备份以来尚未生成新的archive log(s); Archivelog Mode; 有同步的datafile(s) 和control file(s) 的镜像(冷)拷贝

  恢复步骤:

  1. 将镜像拷贝的datafile(s) 和control file(s) 抄送回原始地点:

  $ cp /backup/good_one.dbf /orig_loc/bad_one.dbf

  $ cp /backup/control1.ctl /disk1/control1.ctl

  2. 以mount 选项启动数据库:

  $ svrmgrl
 
  svrmgrl> connect internal

  svrmgrl> startup mount

  3. 以旧的control file 来恢复数据库:

  svrmgrl> recover database using backup controlfile until cancel;

  *** 介质恢复完成
  
  (必须马上cancel )

  4. Reset the logfiles (对启动而言不可省略):

  svrmgrl> alter database open resetlogs;

  5. 关闭数据库并做一次全库冷备份。

 

新增archives 时的状况:

  条件和假设:自上次镜像备份以来已经生成新的archive log(s); Archivelog Mode; 有同步的datafile(s) 和control file(s) 的镜像(冷)拷贝;archive log(s) 可用。

  恢复步骤:

  1. 如果数据库尚未关闭,则首先把它关闭:

  $ svrmgrl
 
  svrmgrl> connect internal

  svrmgrl> shutdown abort

  2. 将备份文件抄送回原始地点:

  所有Database Files

  所有Control Files(没有archive(s) 或redo(s) 的情况下,control files 的更新无任何意义)

  所有On-Line Redo Logs (Not archives)

  init.ora file(选项)

  3. 启动数据库:

  $ svrmgrl

  svrmgrl> connect internal

  svrmgrl> startup

  数据文件, 重作日志和控制文件同时丢失或损坏:

  条件和假设:Archivelog Mode; 有同步的所有所失文件的镜像(冷)拷贝;archive log(s) 可用

  恢复步骤(必须采用不完全恢复的手法):
  
  1. 如果数据库尚未关闭,则首先把它关闭:

  $ svrmgrl

  svrmgrl> connect internal

  svrmgrl> shutdown abort

  2. 将备份文件抄送回原始地点:

  所有Database Files

  所有Control Files

  所有On-Line Redo Logs(Not archives)

  init.ora file(选项)

  3. 启动数据库然而并不打开:

  svrmgrl>startup mount

  4. 做不完全数据库恢复,应用所有从上次镜像(冷)备份始积累起来的archives:

  svrmgrl> recover database until cancel using backup controlfile;

  ……
  ……

  cancel

  5. Reset the logfiles (对启动而言不可省略):

  svrmgrl> alter database open resetlogs;
 
  6. 关闭数据库并做一次全库冷备份。

  数据文件和控制文件同时丢失或损坏:

  条件和假设:Archivelog Mode; 有同步的datafile(s) 和control file(s) 的冷拷贝;archive log(s) 可用

恢复步骤:

  1. 将冷拷贝的datafiles(s) 和control file(s) 抄送回原始地点:

  $ cp /backup/good_one.dbf /orig_loc/bad_one.dbf

  $ cp /backup/control1.ctl /disk1/control1.ctl

  2. 以mount 选项启动数据库:

  $ svrmgrl

  svrmgrl> connect internal

  svrmgrl> startup mount
  
  3. 以旧的control file 来恢复数据库:

  svrmgrl> recover database until cancel using backup controlfile;

  *** 介质恢复完成

  (须在应用完最后一个archive log 后cancel )

  4. Reset the logfiles (对启动而言不可省略):

  svrmgrl> alter database open resetlogs;

  重作日志和控制文件同时丢失或损坏时:

  条件和假设:Control Files 全部丢失或损坏;Archivelog Mode; 有Control Files 的镜像(冷)拷贝。
  
  恢复步骤:

  1. 如果数据库尚未关闭,则首先把它关闭:

  $ svrmgrl

  svrmgrl> connect internal

  svrmgrl> shutdown abort

  svrmgrl>exit

  2. 以Control File 的镜像(冷)拷贝覆盖损坏了的Control File:

  $ cp /backup/control1.ctl /disk1/control1.ctl

  3. 启动数据库然而并不打开:

  $ svrmgrl

  svrmgrl> connect internal

  svrmgrl> startup mount

  4. Drop 坏掉的redo log (排除硬件故障):

  svrmgrl> alter database drop logfile group 2;

  5. 重新创建redo log:

  svrmgrl> alter database add logfile group 2 ‘/orig_loc/log2.dbf’ size 10M;
  
  6. 以旧的control file 来恢复数据库:
  
  svrmgrl> recover database until cancel using backup controlfile;

  (必须马上cancel )

  7. Reset the logfiles (对启动而言不可省略):

  svrmgrl> alter database open resetlogs;

  8. 关闭数据库并做一次全库冷备份

  只发生归档重作日志丢失或损坏时:

  根据不同环境和情况,选择下述手段之一:

  a. 马上backup 全部datafiles (如果系统采用一般热备份或RMAN 热备份)

  b. 马上正常关闭数据库并进行冷备份(如果系统采用冷备份)

  c. 冒险前进!不做备份而让数据库接着跑,直等到下一个备份周期再做备份。这是在赌数据库在下一个备份周期到来之前不会有需要恢复的错误发生。

  注意:冒险前进的选择:如果发生错误而需要数据库恢复,则最多只能恢复到出问题archive log 之前的操作现场。从另一个角度讲,archive log(s) 出现问题时,数据库若不需要恢复则其本身并没有任何问题。

  Oracle逻辑结构故障的处理方法:

  逻辑结构的故障一般指由于人为的误操作而导致重要数据丢失的情况。在这种情况下数据库物理结构是完整的也是一致的。对于这种情况采取对原来数据库的全恢复是不合适的,我们一般采用三种方法来恢复用户数据。
   
  采用exp/imp工具来恢复用户数据:

  如果丢失的数据存在一个以前用exp命令的备份,则可以才用这种方式。

  1. 在数据库内创建一个临时用户:

  svrmgrl>create user test_user identified by test;

  svrmgrl>grant connect,resource to test_user;

  2. 从以前exp命令备份的文件中把丢失数据的表按照用户方式倒入测试用户:

$imp system/manager file=export_file_name tables=(lost_data_table_name…) fromuser=lost_data_table_owner touser=test_user constraint=n;

  3. 用相应的DML语句将丢失的数据从测试用户恢复到原用户。

  4. 将测试用户删除:

  svrmgrl>drop user test_user cascede;
  
  采用logminer来恢复用户数据:

  Logminer是oracle提供的一个日志分析工具。它可以根据数据字典对在线联机日志、归档日志进行分析,从而可以获得数据库的各种DML操作的历史记录以及各种DML操作的回退信息。根据这些用户就可以将由于误操作而丢失的数据重新加入数据库内。

  1. 确认数据库的utl_file_dir参数已经设置,如果没有则需要把这个参数加入oracle的初始化参数文件,然后重新启动数据库。下面例子中假设utl_file_dir=’/opt/oracle/db01’;

  2. 创建logminer所需要的数据字典信息,假设生成的数据字典文本文件为dict.ora:

svrmgrl>execute dbms_logmnr_d.build(dictionary_filename=>’dict.ora’, dictionary_location=>’/opt/oracle/db01’);

  3. 确定所需要分析的日志或者归档日志的范围。这可以根据用户误操作的时间来确定大概的日志范围。假设用户误操作时可能的日志文件为/opt/oracle/db02/oradata/ORCL/redo3.log和归档日志’/opt/oracle/arch/orcl/orclarc_1_113.ora’。

  4. 创建要分析的日志文件列表,按日志文件的先后顺序依次加入:

  svrmgrl>execute dbms_logmnr.add_logfile(logfilename=>’/opt/oracle/arch/orcl/orclarc_1_113.ora’,options=>dbms_logmnr.NEW);

svrmgrl> execute dbms_logmnr.add_logfile(logfilename=>’ /opt/oracle/db02/oradata/ORCL/redo3.log’,options=>dbms_logmnr.ADDFILE);

  5. 开始日志分析,假设需要分析的时间在’2003-06-28 12:00:00’和’2003-06-28 13:00:00’之间:

  svrmgrl>execute dbms_logmnr.start_logmnr(dictfilename=>’ /opt/oracle/db01/dict.ora’,starttime=>to_date(’ 2003-06-28 12:00:00’,’YYYY-MM-DD HH:MI:SS’),endtime=>to_date(to_date(‘2003-06-28 13:00:00’,’YYYY-MM-DD HH:MI:SS’));

  6. 获取分析结果:

  svrmgrl>select operation,sql_redo,sql_undo from v$logmnr_contents;
 
  7. 根据分析结果修复数据。

  8.结束logmnr:

  svrmgrl>dbms_logmnr.end_logmnr;

  9. 用适当的方法对原数据库进行数据库全备份。利用备份恢复用户数据:

  采用这种方法时并不是在原数据库进行恢复,而是利用数据库备份在新的机器上重新建立一个新的数据库。通过备份恢复在新机器上将数据库恢复到用户误操作前,这样就可以获得丢失的数据将其恢复到原数据库。
                                 
  1. 在新的机器上安装数据库软件。

  2.  对于采用带库备份的现场,需要在新的数据库服务器上安装调试相应的备份管软件。

  3. 根据用户误操作的时间点进行基于时间点的数据库恢复操作。对于没有采用带库备份的现场,可以选取用户误操作前最近的备份磁带进行恢复;对于才用带库备份的点可以通过基于时间恢复点恢复的rman脚本来进行恢复。

  4.重新打开数据库:

  svrmgrl>alter database open resetlogs;

  5. 从新的数据库中获取丢失的用户数据,通过DML操作将其恢复到原数据库中。

  6. 用适当的方法对原数据库进行数据库全备份。

 

数据库管理员(DBA)的主要工作


启动和关闭数据库

一)     启动数据库
$ svrmgrl
SVRMGR> connect internal     (实例启动)
SVRMGR> startup

二)     关闭数据库
$ svrmgrl
SVRMGR> connect internal    
SVRMGR> shutdown [immediate/abort]
immediate:正在访问数据库的会话被完全终止、资源有序释放后才关闭       数据库。
abort: 会话立即中止,数据库立即关闭。
备份与恢复

一)     逻辑备份与恢复(即卸库与装库)
1.     卸库:export
不带参数:
$ cd $ORACLE_HOME/bin
$ exp

Username: cwadmin
Password:
Connected to: Oracle8 Enterprise Edition Release 8.0.4.0.0 – Production
PL/SQL Release 8.0.4.0.0 – Production
Enter array fetch buffer size: 4096 >
Export file: expdat.dmp > pzexdat.dmp

(1)     E(ntire database), (2)U(sers), or (3)T(ables): (2)U > 1
    Export grants (yes/no): yes > y
    Export table data (yes/no): yes > y
    Compress extents (yes/no): yes >y
    export 工作开始自动进行最终出现:
    Export terminated successfully without warnings.
   

    带参数,可选参数如下(可用exp help=y 得到):

    Keyword Description (Default)     Keyword     Description (Default)
—————————————————————————————————
USERID   username/password       FULL       export entire file (N)
BUFFER   size of data buffer       OWNER     list of owner usernames
FILE   output file (EXPDAT.DMP)   TABLES     list of table names
COMPRESS import into one extent (Y)   RECORDLENGTH length of IO record
GRANTS   export grants (Y)         INCTYPE     incremental export type
INDEXES export indexes (Y)       RECORD     track incr. export (Y)
ROWS   export data rows (Y)       PARFILE     parameter filename
CONSTRAINTS export constraints (Y)   CONSISTENT   cross-table consistency
LOG     log file of screen output   STATISTICS   analyze objects (ESTIMATE)
DIRECT   direct path (N)
FEEDBACK display progress every x rows (0)
POINT_IN_TIME_RECOVER   Tablespace Point-in-time Recovery (N)
RECOVERY_TABLESPACES   List of tablespace names to recover
VOLSIZE number of bytes to write to each tape volume

例:$exp userid=cwadmin/cwadmin tables=’(sys_cwxx,sys_menu)’ file=pzexport.dmp

2.     装库:

不带参数
$ cd $ORACLE_HOME/bin
$ imp

Username: cwadmin
Password:
Connected to: Oracle8 Enterprise Edition Release 8.0.4.0.0 – Production
PL/SQL Release 8.0.4.0.0 – Production
Import file: expdat.dmp > pzexdat.dmp
Enter insert buffer size (minimum is 4096) 30720> 10240

Export file created by EXPORT:V08.00.04 via conventional path
List contents of import file only (yes/no): no >

Ignore create error due to object existence (yes/no): no > y
Import grants (yes/no):yes > y
Import table data (yes/no):yes >y
Import entire export file (yes/no):no >y
    import 工作开始自动进行最终出现:
    Import terminated successfully with warnings.

带参数,可选参数如下(可用imp help=y 得到):

Keyword Description (Default)     Keyword     Description (Default)
—————————————————————————————————
USERID   username/password       FULL     import entire file (N)
BUFFER   size of data buffer       FROMUSER   list of owner usernames
FILE   input file (EXPDAT.DMP)   TOUSER     list of usernames
SHOW   just list file contents (N)   TABLES     list of table names
IGNORE   ignore create errors (N)   RECORDLENGTH   length of IO record
GRANTS   import grants (Y)       INCTYPE     incremental import type
INDEXES import indexes (Y)       COMMIT     commit array insert (N)
ROWS   import data rows (Y)     PARFILE     parameter filename
LOG     log file of screen output
DESTROY overwrite tablespace data file (N)
INDEXFILE write table/index info to specified file
CHARSET character set of export file (NLS_LANG)
POINT_IN_TIME_RECOVER Tablespace Point-in-time Recovery (N)
SKIP_UNUSABLE_INDEXES skip maintenance of unusable indexes (N)
ANALYZE execute ANALYZE statements in dump file (Y)
FEEDBACK display progress every x rows(0)
VOLSIZE number of bytes in file on each volume of a file on tape  

例:$imp userid=cwadmin/cwadmin tables=’(sys_dwxx, sys_menu)’ file=pzexdat.dmp

二)     物理备份与恢复
1.     冷备份与热备份
冷备份
在数据库关闭状态与进行。将所有的数据文件、重演日志文件及控制文件拷贝到磁盘。空闲的时间再将备份移到磁带上。
    (1)可通过:SVRMGR> select * from v$logfile;
              select * from v$dbfile;
              select * from v$control.file;
    这些语句来了解数据文件、重演日志文件及控制文件的相应位置及名称。
(2)利用$cp 命令来拷贝:
  例:$cp /u01/u02/pz_ts.ora /dbfile_b/

热备份
数据库必须工作在“ARCHIVELOG”方式下
可利用SVRMGR> archive log list 语句来查归档日志状态

  若在“NOARCHIVELOG”方式下,进行转换
  SVRMGR> connect internal      
  SVRMGR> shutdown immediate     —关闭数据库—
  SVRMGR> startup mount   —为暂停日志方式转换准备数据库—
  SVRMGR> alter database archivelog; —转换—
  SVRMGR> alter database open;     —打开数据库—
 
  拷贝
  1> 将一个表空间置为备份方式
    SVRMGR> alter tablespace pzts begin backup;
  2> 拷贝
    SVRMGR>$cp /u01/u02/pz_ts.ora /dbfile_b/
  3> 取消该表备份方式
      SVRMGR>alter tablespace pzts end backup;
  利用以上3步,将所有表空间下的数据文件进行备份
  4> 拷贝控制文件
  5> 拷贝归档重演日志

2.     恢复
        磁盘出现故障,数据库自行关闭。
(1)     将驻留在磁盘上的备份拷贝到其他磁盘或磁带上
(2)     执行  
        SVRMGR> connect internal
        SVRMGR> startup mount
        SVRMGR> alter database open;
  会出现错误信息,提示需要恢复
(3)     执行
            SVRMGR> recover database
        根据提示,自动恢复
(4)     执行
            SVRMGR>alter database open
        恢复完成,数据库打开。
Oracle DBA的工作列表

作为数据库技术人员,相信没有一个人愿意永远在底层编写程序或做简单的系统维护。经过一段时间的技术和经验的积累,很多人都向往更高层的职位,但如何能成为一个专业的数据库管理人才,并不是每一个人都清晰、明了。
  如果你真想成为一名成功、成熟的数据库专家,你需要不断地扩展你的技能与知识——有些知识领域可能对你很陌生,本文阐述了可以帮助你提高职业素质的重要能力。作为一名数据库专业人士,要想有一个成功的职业生涯并不是很容易的事情。你有可能每一种技术都懂一些,但又都不精通,也有可能是一名专才。无论如何,一旦你想成为数据库专家,想在你的游戏地盘里成为楚翘,你需要不断扩展的、跨领域的素质。但是,大部分的素质能力存在于传统数据库技能范畴之外,它们可能适用于其他的功能学科。我们与其他人的差异越来越小,这超出了我们的习惯思维,恐怕对很多想迅速成功的数据库专业人士也是一个不小的打击。

  理解现有的和新兴的技术

  所有数据库专业人士需要的一个最基本的能力便是对他们的基本技术技能进行深度和广度的拓展。如果用马斯洛的需求层次来比喻,那么这种能力应该属于食物和水的层次,你必须有这些才能满足基本的生存。上课、阅读文章、研究产品,参加一个专业性质的组织,你需要掌握你正在使用的技术领域的所有信息,而且你还需要有实践机会去应用这些知识。

  如果你参加一些技术资格或职称的考试,你应该经常提醒自己,你的目标并不单纯是为了在自己的名字后面加上许多的头衔,而是实现你所受教育的价值最大化。

  西方有句谚语,赢得游戏胜利不仅仅需要你将眼睛盯在正在击打的球上,而且也要能预计到下一个球的方向。历史经验已经证明,任何系统的平均生命周期大约为16个月,因此为未来做好规划很有必要。当你充分了解你正在做的事情后,实施的效率会更高。

  设计技术性架构

  任何自己修建的一个系统作为个体的功能都是自以为精妙和可执行的。但如果将它放进一个大一点的系统,它可能就会出现问题,也许你的技能还不是很高妙。无论你是负责全面的应用与网络设计,还是部分营建一个系统部件,支持一个企业架构,你都需要知道什么是良好的、扎实的架构设计法则。

  一套有效率的技术性架构设计将零件拼接在一起,它应该就像一台容易操控、价格合理的机器一样。我已经发现,架构设计如果基于“奥卡姆剃刀原理”(Occam’s Razor),那么它往往是最棒的,奥卡姆剃刀原理这个词语源于拉丁语,意为“如无必要,勿增实体”(Ent数据库ies should not be multiplied unnecessarily),即简单就是最好的。当考虑设计之时,要记住每个组织都有一些独特的程序,大部分的组织性程序都相当的普通,它们能够用可配置的通用解决方案来解决问题。很多架构可以利用购买以及将一些很小数量的部件组合在一起的方式来完成,而不是要重新发明一种结构。通过这种方法,你能够在很短的时间内,利用更少的成本,为你的客户提供一种优质、容易操控的产品。同样理念还适用于个体应用与架构的设计与开发。

系统集成

  技术为很多的目的服务,最重要的能力便是使程序的自动化。不是使用传统的供应商订单、库存管理以及产品市场推销手段,而是使用供应链程序,流程通过允许供应商和生产者来进行复杂地沟通控制,从而完成原材料进入生产流程到产品抵达消费者手中的整个过程。

  Sarbanes-Oxley和其他监管法则都要求企业达到内部控制的标准,它们在系统设计领域相当常见。随着产品和平台继续地增生扩散,随着企业日渐将自己的系统和其他的系统相连,高质量的协同工作能力是必须的。

  了解企业

  企业实体是复杂的组织,没有哪个企业是与别的企业完全相同的,就像雪花一样,没有两片雪花是完全相同。这种推动特定业务运转的灵活性不太容易被掌握。很多时候,尤其是在大型企业当中,多种文化是并存的——有一个文化是企业层面的,而别的存在于部门层面。当你认为是安全下水的时候,你对企业运行的细微直觉会因为合并或者管理性质的巨变失去灵光,一切都发生了改变。

  当我们认为自己能够在企业文化的风浪当中驾轻就熟,而无需在乎浪潮或者风向之时,我们不可以自鸣得意。同样的,尽管企业灵活性的东西当中,很多是普通的,可以传授的知识,那种认为在一个企业环境当中取得成功的做法同样适用于另外一个企业的想法是愚蠢的。我们必须学习我们身处的每个新环境的特质。

  规划管理项目

  Joe Torre被视为是一位非常优秀的经理。很难想像,如果他没有一套相当周全的比赛规划,这位纽约人能够在10次比赛中9次取得胜利,并且获得6个AL锦标赛以及4个世界性系列比赛的冠军。这种计划不是针对年度比赛的,而是每一场比赛。

  无论你是一位经理或者是一位选手,一名超级明星或者是一位业余玩家,你都要为自己近期和远期的比赛制定规划。你如何为今天进行规划?为这周?为今年?你如何完成这些目标?你应该问自己很多“做什么”以及“如何做”的问题。如果你是一名开发人员或者是一名网络管理员,你现在就需要培养自己的规划能力。如果你无法管理自己,你当然就会在管理别人或者复杂项目之时捉襟见肘。

  注重沟通与倾听

  任何东西都可以平庸,除了一种能力你不能不做到完美:沟通。这是两个最重要能力当中的一种,沟通对数据库专业人士尤显重要。良好的沟通是双向性的事情,你来我往同等重要。数据库行业是锻炼你雅量的完美地方,因为这一行业需要沟通的时刻太多了。

  无论你怎样看待工作和生活,每个数据库专业人士实际上都是一名顾问。作为顾问,你有责任去为你的客户提供最大的价值。这样做意味着你至少了解你客户的业务,客户业务运转的情况,这意味着你要去倾听。你的客户有资格知道他们付给你的钱获得了怎样的回报,这意味着你必须主动的、有规律的让他们知道你正在为他们的利益而奔忙。

  这一点对传统的数据库人员来讲很难。我们大部分进入这一行业的人认为自己接触代码和电线的机会大于与人的接触。我们以为最好的方法便是坐在我们的桌子面前,埋头苦干。这些都是致命的错误,尽管沟通做起来很不容易,也或许会和我们的个性背道而驰,但你别无选择,只能培养这些能力。幸好人人都能够学习,经过一定时间的锻炼,沟通将会变得容易一些。

专注结果

  另外一个绝对重要的能力便是执行的能力。计划再棒,也只是空谈而已。归根结底,你需要用东西来证明你的努力。

  最好的方法是了解你客户的一些重要信息,比如他们是谁,他们想做什么?作为一名数据库专业运营顾问,你有责任向你的客户提供建议,这种建议建立在你的知识与经验之上。

  但别忘了,最终是你的老板或同事、团队领导、你工作的最终客户进行决策。有时候,这些决策并不是你推荐的。你需要认真思考其中的缘由,但不要让任何分析将你麻痹,也不要让自己陷入唐吉柯德式的盲动之中。80-20定律在这里起作用:80%的结果能够通过20%的努力来完成,超出这一范畴的多余价值经常不值得耗费成本。

  进行战略性的思考

  这是一个竞争日渐激烈的世界,今天的数据库专业人士必须每天去证明,他们能够增加战术与战略价值;他们要在自己组织的任何一次会议上,成为受欢迎的人。在过去十几年的时间里,企业已经开始意识到数据库的战略重要性,企业认为数据库不仅仅是会计账目上的死水一潭,而是能够给企业带来价值的部门。

  大部分的数据库部门是被动式的进行工作,他们等待自己的业务客户。高性能、高度成功的数据库部门是积极的,在完成公司总体目标的过程当中,他们以咨询式的态度与自己的业务客户共事。

  影响和说服

  上个世纪50年代那种命令式、军队式的组织管理模式已经让位于更加平行的组织管理模式。直接管理和影响管理已经相辅相成。我们不再命令别人做事情。我们会用说服、协商、沟通等等方式去解决问题。这是你训练沟通能力的好机会。有了沟通能力,其他的能力问题才能迎刃而解,像战略性思维、业绩挂钩等等。能够影响他人的数据库专业人士总是代表着高效、富有能力、受人尊敬的人士。不要错误地认为这只是经理们该具备的能力。影响和说服是推动协同性工作环境完成的重要技能。

  有适应能力

  一名技术专业人士意味着具有某个特殊开发环境的专长或者有能力开发、支持一个网络,但是在现在,别以为你仍然能够靠这些东西过好日子,如果你和其他提供某一类数据库服务的专家一样,你就是一个没有优势的普通职员。你应该成为一个真正的数据库多面手,需要不断地进行技能扩展工作。这样才能在众多的技术人员当中显示出你的优秀。

  有些能力,比如技术技能与知识,相对来说比较容易掌握。但类似业务知识一类的知识,则需要你花更多的时间掌握。个人和团队的管理、领导艺术以及和同事、用户共事的能力,这些能力需要你调整自己的个人态度以及个性才能获得。

  如果你选择在数据库行业就业,你也选择了让自己成为变化的适应者。我们的专业变化很快也很深刻,我们必须认真地对待这种变化。无论你喜欢与否,都要尽快适应业务变化。竞争的压力、新手的进入、管理的变革、战略的调整、产品的开发,任何这些因素都会导致变化。现在,几乎没有一个行业没有被数据库技术所影响,作为一个可以信赖的专业人士,我们必须让我们的企业适应这种变化。

2006年05月31日

做数据仓库系统,ETL是关键的一环。说大了,ETL是数据整合解决方案,说小了,就是倒数据的工具。回忆一下工作这么些年来,处理数据迁移、转换的工作倒还真的不少。但是那些工作基本上是一次性工作或者很小数据量,使用 access、DTS或是自己编个小程序搞定。可是在数据仓库系统中,ETL上升到了一定的理论高度,和原来小打小闹的工具使用不同了。究竟什么不同,从名字上就可以看到,人家已经将倒数据的过程分成3个步骤,E、T、L分别代表抽取、转换和装载。

其实ETL过程就是数据流动的过程,从不同的数据源流向不同的目标数据。但在数据仓库中,ETL有几个特点,一是数据同步,它不是一次性倒完数据就拉到,它是经常性的活动,按照固定周期运行的,甚至现在还有人提出了实时ETL的概念。二是数据量,一般都是巨大的,值得你将数据流动的过程拆分成E、T和L

现在有很多成熟的工具提供ETL功能,例如datastage、 powermart等,且不说他们的好坏。从应用角度来说,ETL的过程其实不是非常复杂,这些工具给数据仓库工程带来和很大的便利性,特别是开发的便利和维护的便利。但另一方面,开发人员容易迷失在这些工具中。举个例子,VB是一种非常简单的语言并且也是非常易用的编程工具,上手特别快,但是真正VB的高手有多少?微软设计的产品通常有个原则是“将使用者当作傻瓜”,在这个原则下,微软的东西确实非常好用,但是对于开发者,如果你自己也将自己当作傻瓜,那就真的傻了。ETL工具也是一样,这些工具为我们提供图形化界面,让我们将主要的精力放在规则上,以期提高开发效率。从使用效果来说,确实使用这些工具能够非常快速地构建一个job来处理某个数据,不过从整体来看,并不见得他的整体效率会高多少。问题主要不是出在工具上,而是在设计、开发人员上。他们迷失在工具中,没有去探求ETL的本质。

可以说这些工具应用了这么长时间,在这么多项目、环境中应用,它必然有它成功之处,它必定体现了ETL的本质。如果我们不透过表面这些工具的简单使用去看它背后蕴涵的思想,最终我们作出来的东西也就是一个个独立的job,将他们整合起来仍然有巨大的工作量。大家都知道“理论与实践相结合”,如果在一个领域有所超越,必须要在理论水平上达到一定的高度

探求ETL本质之一

 

ETL的过程就是数据流动的过程,从不同异构数据源流向统一的目标数据。其间,数据的抽取、清洗、转换和装载形成串行或并行的过程。ETL的核心还是在于T这个过程,也就是转换,而抽取和装载一般可以作为转换的输入和输出,或者,它们作为一个单独的部件,其复杂度没有转换部件高。和OLTP系统中不同,那里充满这单条记录的insert、update和select等操作,ETL过程一般都是批量操作,例如它的装载多采用批量装载工具,一般都是DBMS系统自身附带的工具,例如Oracle SQLLoader和DB2的autoloader等。

ETL本身有一些特点,在一些工具中都有体现,下面以datastage和powermart举例来说。

1、静态的ETL单元和动态的ETL单元实例;一次转换指明了某种格式的数据如何格式化成另一种格式的数据,对于数据源的物理形式在设计时可以不用指定,它可以在运行时,当这个ETL单元创建一个实例时才指定。对于静态和动态的 ETL单元,Datastage没有严格区分,它的一个Job就是实现这个功能,在早期版本,一个Job同时不能运行两次,所以一个Job相当于一个实例,在后期版本,它支持multiple instances,而且还不是默认选项。Powermart中将这两个概念加以区分,静态的叫做Mapping,动态运行时叫做Session。

2、ETL元数据;元数据是描述数据的数据,他的含义非常广泛,这里仅指ETL的元数据。主要包括每次转换前后的数据结构和转换的规则。ETL元数据还包括形式参数的管理,形式参数的ETL单元定义的参数,相对还有实参,它是运行时指定的参数,实参不在元数据管理范围之内。

 


3、数据流程的控制;要有可视化的流程编辑工具,提供流程定义和流程监控功能。流程调度的最小单位是ETL单元实例,ETL单元是不能在细分的ETL过程,当然这由开发者来控制,例如可以将抽取、转换放在一个ETL单元中,那样这个抽取和转换只能同时运行,而如果将他们分作两个单元,可以分别运行,这有利于错误恢复操作。当然,ETL单元究竟应该细分到什么程度应该依据具体应用来看,目前还没有找到很好的细分策略。比如,我们可以规定将装载一个表的功能作为一个ETL单元,但是不可否认,这样的ETL单元之间会有很多共同的操作,例如两个单元共用一个Hash表,要将这个Hash表装入内存两次。


4、转换规则的定义方法;提供函数集提供常用规则方法,提供规则定义语言描述规则。

5、对数据的快速索引;一般都是利用Hash技术,将参照关系表提前装入内存,在转换时查找这个hash表。Datastage中有Hash文件技术,Powermart也有类似的Lookup功能。

探求ETL本质之二(分类)

 

昨在IT-Director上阅读一篇报告,关于ETL产品分类的。一般来说,我们眼中的ETL工具都是价格昂贵,能够处理海量数据的家伙,但是这是其中的一种。它可以分成4种,针对不同的需求,主要是从转换规则的复杂度和数据量大小来看。它们包括

1、交互式运行环境,你可以指定数据源、目标数据,指定规则,立马ETL。这种交互式的操作无疑非常方便,但是只能适合小数据量和复杂度不高的ETL过程,因为一旦规则复杂了,可能需要语言级的描述,不能简简单单拖拖拽拽就可以的。还有数据量的问题,这种交互式必然建立在解释型语言基础上,另外他的灵活性必然要牺牲一定的性能为代价。所以如果要处理海量数据的话,每次读取一条记录,每次对规则进行解释执行,每次在写入一条记录,这对性能影响是非常大的。

2、专门编码型的,它提供了一个基于某种语言的程序框架,你可以不必将编程精力放在一些周边的功能上,例如读文件功能、写数据库的功能,而将精力主要放在规则的实现上面。这种近似手工代码的性能肯定是没话说,除非你的编程技巧不过关(这也是不可忽视的因素之一)。对于处理大数据量,处理复杂转换逻辑,这种方式的ETL实现是非常直观的。

3、代码生成器型的,它就像是一个ETL代码生成器,提供简单的图形化界面操作,让你拖拖拽拽将转换规则都设定好,其实他的后台都是生成基于某种语言的程序,要运行这个ETL过程,必须要编译才行。Datastage就是类似这样的产品,设计好的job必须要编译,这避免了每次转换的解释执行,但是不知道它生成的中间语言是什么。以前我设计的ETL工具大挪移其实也是归属于这一类,它提供了界面让用户编写规则,最后生成C++语言,编译后即可运行。这类工具的特点就是要在界面上下狠功夫,必须让用户轻松定义一个ETL过程,提供丰富的插件来完成读、写和转换函数。大挪移在这方面就太弱了,规则必须手写,而且要写成标准c++语法,这未免还是有点难为最终用户了,还不如做成一个专业编码型的产品呢。另外一点,这类工具必须提供面向专家应用的功能,因为它不可能考虑到所有的转换规则和所有的读写,一方面提供插件接口来让第三方编写特定的插件,另一方面还有提供特定语言来实现高级功能。例如Datastage提供一种类Basic的语言,不过他的Job的脚本化实现好像就做的不太好,只能手工绘制job,而不能编程实现Job

4、最后还有一种类型叫做数据集线器,顾名思义,他就是像Hub一样地工作。将这种类型分出来和上面几种分类在标准上有所差异,上面三种更多指ETL实现的方法,此类主要从数据处理角度。目前有一些产品属于EAI (Enterprise Application Integration),它的数据集成主要是一种准实时性。所以这类产品就像Hub一样,不断接收各种异构数据源来的数据,经过处理,在实施发送到不同的目标数据中去。

虽然,这些类看似各又千秋,特别在BI项目中,面对海量数据的ETL时,中间两种的选择就开始了,在选择过程中,必须要考虑到开发效率、维护方面、性能、学习曲线、人员技能等各方面因素,当然还有最重要也是最现实的因素就是客户的意象。

探求ETL本质之三(转换)

 

ETL探求之一中提到,ETL过程最复杂的部分就是T,这个转换过程,T过程究竟有哪些类型呢?

一、宏观输入输出

从对数据源的整个宏观处理分,看看一个ETL过程的输入输出,可以分成下面几类:

1、大小交,这种处理在数据清洗过程是常见了,例如从数据源到ODS阶段,如果数据仓库采用维度建模,而且维度基本采用代理键的话,必然存在代码到此键值的转换。如果用SQL实现,必然需要将一个大表和一堆小表都Join起来,当然如果使用ETL工具的话,一般都是先将小表读入内存中再处理。这种情况,输出数据的粒度和大表一样。

2、大大交,大表和大表之间关联也是一个重要的课题,当然其中要有一个主表,在逻辑上,应当是主表Left Join辅表。大表之间的关联存在最大的问题就是性能和稳定性,对于海量数据来说,必须有优化的方法来处理他们的关联,另外,对于大数据的处理无疑会占用太多的系统资源,出错的几率非常大,如何做到有效错误恢复也是个问题。对于这种情况,我们建议还是尽量将大表拆分成适度的稍小一点的表,形成大小交的类型。这类情况的输出数据粒度和主表一样。

3、站着进来,躺着出去。事务系统中为了提高系统灵活性和扩展性,很多信息放在代码表中维护,所以它的“事实表”就是一种窄表,而在数据仓库中,通常要进行宽化,从行变成列,所以称这种处理情况叫做“站着进来,躺着出去”。大家对Decode肯定不陌生,这是进行宽表化常见的手段之一。窄表变宽表的过程主要体现在对窄表中那个代码字段的操作。这种情况,窄表是输入,宽表是输出,宽表的粒度必定要比窄表粗一些,就粗在那个代码字段上。

4、聚集。数据仓库中重要的任务就是沉淀数据,聚集是必不可少的操作,它是粗化数据粒度的过程。聚集本身其实很简单,就是类似SQL中Group by的操作,选取特定字段(维度),对度量字段再使用某种聚集函数。但是对于大数据量情况下,聚集算法的优化仍是探究的一个课题。例如是直接使用SQL的 Group by,还是先排序,在处理。

二、微观规则

从数据的转换的微观细节分,可以分成下面的几个基本类型,当然还有一些复杂的组合情况,例如先运算,在参照转换的规则,这种基于基本类型组合的情况就不在此列了。ETL的规则是依赖目标数据的,目标数据有多少字段,就有多少条规则。

1、直接映射,原来是什么就是什么,原封不动照搬过来,对这样的规则,如果数据源字段和目标字段长度或精度不符,需要特别注意看是否真的可以直接映射还是需要做一些简单运算。

2、字段运算,数据源的一个或多个字段进行数学运算得到的目标字段,这种规则一般对数值型字段而言。

3、参照转换,在转换中通常要用数据源的一个或多个字段作为Key

探求ETL本质之四(数据质量)

 

“不要绝对的数据准确,但要知道为什么不准确。”

这是我们在构建BI系统是对数据准确性的要求。确实,对绝对的数据准确谁也没有把握,不仅是系统集成商,包括客户也是无法确定。准确的东西需要一个标准,但首先要保证这个标准是准确的,至少现在还没有这样一个标准。客户会提出一个相对标准,例如将你的OLAP数据结果和报表结果对比。虽然这是一种不太公平的比较,你也只好认了吧。

首先在数据源那里,已经很难保证数据质量了,这一点也是事实。在这一层有哪些可能原因导致数据质量问题?可以分为下面几类:

1、数据格式错误,例如缺失数据、数据值超出范围或是数据格式非法等。要知道对于同样处理大数据量的数据源系统,他们通常会舍弃一些数据库自身的检查机制,例如字段约束等。他们尽可能将数据检查在入库前保证,但是这一点是很难确保的。这类情况诸如身份证号码、手机号、非日期类型的日期字段等。

2、数据一致性,同样,数据源系统为了性能的考虑,会在一定程度上舍弃外键约束,这通常会导致数据不一致。例如在帐务表中会出现一个用户表中没有的用户ID,在例如有些代码在代码表中找不到等。

3、业务逻辑的合理性,这一点很难说对与错。通常,数据源系统的设计并不是非常严谨,例如让用户开户日期晚于用户销户日期都是有可能发生的,一个用户表中存在多个用户ID也是有可能发生的。对这种情况,有什么办法吗?

构建一个BI系统,要做到完全理解数据源系统根本就是不可能的。特别是数据源系统在交付后,有更多维护人员的即兴发挥,那更是要花大量的时间去寻找原因。以前曾经争辩过设计人员对规则描述的问题,有人提出要在ETL开始之前务必将所有的规则弄得一清二楚。我并不同意这样的意见,倒是认为在ETL过程要有处理这些质量有问题数据的保证。一定要正面这些脏数据,是丢弃还是处理,无法逃避。如果没有质量保证,那么在这个过程中,错误会逐渐放大,抛开数据源质量问题,我们再来看看ETL过程中哪些因素对数据准确性产生重大影响。

1、规则描述错误。上面提到对设计人员对数据源系统理解的不充分,导致规则理解错误,这是一方面。另一方面,是规则的描述,如果无二义性地描述规则也是要探求的一个课题。规则是依附于目标字段的,在探求之三中,提到规则的分类。但是规则总不能总是用文字描述,必须有严格的数学表达方式。我甚至想过,如果设计人员能够使用某种规则语言来描述,那么我们的ETL单元就可以自动生成、同步,省去很多手工操作了。

2、ETL开发错误。即时规则很明确,ETL开发的过程中也会发生一些错误,例如逻辑错误、书写错误等。例如对于一个分段值,开区间闭区间是需要指定的,但是常常开发人员没注意,一个大于等于号写成大于号就导致数据错误。

3、人为处理错误。在整体ETL流程没有完成之前,为了图省事,通常会手工运行ETL过程,这其中一个重大的问题就是你不会按照正常流程去运行了,而是按照自己的理解去运行,发生的错误可能是误删了数据、重复装载数据等。

探求ETL本质之五(质量保证)

 

上回提到ETL数据质量问题,这是无法根治的,只能采取特定的手段去尽量避免,而且必须要定义出度量方法来衡量数据的质量是好还是坏。对于数据源的质量,客户对此应该更加关心,如果在这个源头不能保证比较干净的数据,那么后面的分析功能的可信度也都成问题。数据源系统也在不断进化过程中,客户的操作也在逐渐规范中,BI系统也同样如此。本文探讨一下对数据源质量和ETL处理质量的应对方法。

如何应对数据源的质量问题?记得在onteldatastage列表中也讨论过一个话题-"-1的处理",在数据仓库模型维表中,通常有一条-1记录,表示“未知”,这个未知含义可广了,任何可能出错的数据,NULL数据甚至是规则没有涵盖到的数据,都转成-1。这是一种处理脏数据的方法,但这也是一种掩盖事实的方法。就好像写一个函数FileOpen (filename),返回一个错误码,当然,你可以只返回一种错误码,如-1,但这是一种不好的设计,对于调用者来说,他需要依据这个错误码进行某些判断,例如是文件不存在,还是读取权限不够,都有相应的处理逻辑。数据仓库中也是一样,所以,建议将不同的数据质量类型处理结果分别转换成不同的值,譬如,在转换后,-1表示参照不上,-2表示NULL数据等。不过这仅仅对付了上回提到的第一类错误,数据格式错误。对于数据一致性和业务逻辑合理性问题,这仍有待探求。但这里有一个原则就是“必须在数据仓库中反应数据源的质量”。

对于ETL过程中产生的质量问题,必须有保障手段。从以往的经验看,没有保障手段给实施人员带来麻烦重重。实施人员对于反复装载数据一定不会陌生,甚至是最后数据留到最后的Cube,才发现了第一步ETL其实已经错了。这个保障手段就是数据验证机制,当然,它的目的是能够在ETL过程中监控数据质量,产生报警。这个模块要将实施人员当作是最终用户,可以说他们是数据验证机制的直接收益者。

首先,必须有一个对质量的度量方法,什么是高质什么是低质,不能靠感官感觉,但这却是在没有度量方法条件下通常的做法。那经营分析系统来说,联通总部曾提出测试规范,这其实就是一种度量方法,例如指标的误差范围不能高于 5%等,对系统本身来说其实必须要有这样的度量方法,先不要说这个度量方法是否科学。对于ETL数据处理质量,他的度量方法应该比联通总部测试规范定义的方法更要严格,因为他更多将BI系统看作一个黑盒子,从数据源到展现的数据误差允许一定的误差。而ETL数据处理质量度量是一种白盒的度量,要注重每一步过程。因此理论上,要求输入输出的指标应该完全一致。但是我们必须正面完全一致只是理想,对于有误差的数据,必须找到原因。

在质量度量方法的前提下,就可以建立一个数据验证框架。此框架依据总量、分量数据稽核方法,该方法在高的《数据仓库中的数据稽核技术》一文中已经指出。作为补充,下面提出几点功能上的建议:
1、提供前端。将开发实施人员当作用户,同样也要为之提供友好的用户界面。《稽核技术》一文中指出测试报告的形式,这种形式还是要依赖人为判断,在一堆数据中去找规律。到不如用OLAP的方式提供界面,不光是加上测试统计出来的指标结果,并且配合度量方法的计算。例如误差率,对于误差率为大于0
的指标,就要好好查一下原因了。

2、提供框架。数据验证不是一次性工作,而是每次ETL过程中都必须做的。因此,必须有一个框架,自动化验证过程,并提供扩展手段,让实施人员能够增加验证范围。有了这样一个框架,其实它起到规范化操作的作用,开发实施人员可以将主要精力放在验证脚本的编写上,而不必过多关注验证如何融合到流程中,如何展现等工作。为此,要设计一套表,类似于DM表,每次验证结果数据都记录其中,并且自动触发多维分析的数据装载、发布等。这样,实施人员可以在每次装载,甚至在流程过程中就可以观察数据的误差率。特别是,如果数据仓库的模型能够统一起来,甚至数据验证脚本都可以确定下来,剩下的就是规范流程了。

3、规范流程。上回提到有一种ETL数据质量问题是由于人工处理导致的,其中最主要原因还是流程不规范。开发实施人员运行单独一个ETL单元是很方便的,虽然以前曾建议一个ETL单元必须是“可重入”的,这能够解决误删数据,重复装载数据问题。但要记住数据验证也是在流程当中,要让数据验证能够日常运作,就不要让实施者感觉到他的存在。总的来说,规范流程是提高实施效率的关键工作,这也是以后要继续探求的。

探求ETL本质之六(元数据漫谈)

 

对于元数据(Metadata)的定义到目前为止没有什么特别精彩的,这个概念非常广,一般都是这样定义,“元数据是描述数据的数据(Data about Data)”,这造成一种递归定义,就像问小强住在哪里,答,在旺财隔壁。按照这样的定义,元数据所描述的数据是什么呢?还是元数据。这样就可能有元元元…元数据。我还听说过一种对元数据,如果说数据是一抽屉档案,那么元数据就是分类标签。那它和索引有什么区别?

元数据体现是一种抽象,哲学家从古至今都在抽象这个世界,力图找到世界的本质。抽象不是一层关系,它是一种逐步由具体到一般的过程。例如我->男人->人->哺乳动物->生物这就是一个抽象过程,你要是在软件业混会发现这个例子很常见,面向对象方法就是这样一种抽象过程。它对世界中的事物、过程进行抽象,使用面向对象方法,构建一套对象模型。同样在面向对象方法中,类是对象的抽象,接口又是对类的抽象。因此,我认为可以将“元”和“抽象”换一下,叫抽象数据是不是好理解一些。

常听到这样的话,“xx领导的讲话高屋建瓴,给我们后面的工作指引的清晰的方向”,这个成语“高屋建瓴”,站在10楼往下到水,居高临下,能砸死人,这是指站在一定的高度看待事物,这个一定的高度就是指他有够“元”。在设计模式中,强调要对接口编程,就是说你不要处理这类对象和那类对象的交互,而要处理这个接口和那个接口的交互,先别管他们内部是怎么干的。

元数据存在的意义也在于此,虽然上面说了一通都撤到哲学上去,但这个词必须还是要结合软件设计中看,我不知道在别的领域是不是存在Metadata这样的叫法,虽然我相信别的领域必然有类似的东东。元数据的存在就是要做到在更高抽象一层设计软件。这肯定有好处,什么灵活性啊,扩展性啊,可维护性啊,都能得到提高,而且架构清晰,只是弯弯太多,要是从下往上看,太复杂了。很早以前,我曾看过backorifice的代码,我靠,一个简单的功能,从这个类转到父类,又转到父类,很不理解,为什么一个简单的功能不在一个类的方法中实现就拉到了呢?现在想想,还真不能这样,这虽然使代码容易看懂了,但是结构确实混乱的,那他只能干现在的事,如果有什么功能扩展,这些代码就废了。

我从98年刚工作时就开始接触元数据的概念,当时叫做元数据驱动的系统架构,后来在QiDSS中也用到这个概念构建QiNavigator,但是现在觉得元数据也没啥,不就是建一堆表描述界面的元素,再利用这些数据自动生成界面吗。到了数据仓库系统中,这个概念更强了,是数据仓库中一个重要的部分。但是至今,我还是认为这个概念过于玄乎,看不到实际的东西,市面上有一些元数据管理的东西,但是从应用情况就得知,用的不多。之所以玄乎,就是因为抽象层次没有分清楚,关键就是对于元数据的分类(这种分类就是一种抽象过程)和元数据的使用。你可以将元数据抽象成0和1,但是那样对你的业务有用吗?必须还得抽象到适合的程度,最后问题还是“度”。

数据仓库系统的元数据作用如何?还不就是使系统自动运转,易于管理吗?要做到这一步,可没必要将系统抽象到太极、两仪、八卦之类的,业界也曾定义过一些元数据规范,向CWM、XMI等等,可以借鉴,不过俺对此也是不精通的说,以后再说

2006年03月01日

ROW_NUMBER() OVER (PARTITION BY COL1 ORDER BY COL2)

表示根据COL1分组,在分组内部根据 COL2排序
而这个值就表示每组内部排序后的顺序编号(组内连续的唯一的)

RANK() 类似,不过RANK 排序的时候跟派名次一样,可以并列2个第一名之后 是第3名

LAG 表示 分组排序后 ,组内后面一条记录减前面一条记录的差,第一条可返回 NULL

BTW: EXPERT ONE ON ONE 上讲的最详细,还有很多相关特性,文档看起来比较费劲

row_number()和rownum差不多,功能更强一点(可以在各个分组内从1开时排序)
rank()是跳跃排序,有两个第二名时接下来就是第四名(同样是在各个分组内)
dense_rank()l是连续排序,有两个第二名时仍然跟着第三名。
相比之下row_number是没有重复值的
lag(arg1,arg2,arg3):
arg1是从其他行返回的表达式
arg2是希望检索的当前行分区的偏移量。是一个正的偏移量,时一个往回检索以前的行的数目。
arg3是在arg2表示的数目超出了分组的范围时返回的值。


SQL> set pagesize 100;
SQL> select rownum from emp;

ROWNUM
———-
1
2
3
4
5
6
7
8
9
10
11
12
13
14

已选择14行。

已用时间: 00: 00: 00.10
SQL> select deptno,row_number() over(partition by deptno order by sal) from emp order by deptno;


DEPTNO ROW_NUMBER()OVER(PARTITIONBYDEPTNOORDERBYSAL)
———- ———————————————
10 1
2
3

20 1
2
3
4
5

30 1
2
3
4
5
6


已选择14行。

已用时间: 00: 00: 00.41
SQL> select deptno,rank() over (partition by deptno order by sal) from emp order by deptno;

DEPTNO RANK()OVER(PARTITIONBYDEPTNOORDERBYSAL)
———- —————————————
10 1
2
3

20 1
2
3
4
4

30 1
2
2
4
5
6


已选择14行。

已用时间: 00: 00: 00.21
SQL> select deptno,dense_rank() over(partition by deptno order by sal) from emp order by deptno;

DEPTNO DENSE_RANK()OVER(PARTITIONBYDEPTNOORDERBYSAL)
———- ———————————————
10 1
2
3

20 1
2
3
4
4

30 1
2
2
3
4
5


已选择14行。

已用时间: 00: 00: 00.20
SQL> select deptno,ename,sal,lag(ename,1,null) over(partition by deptno order by ename) from emp ord
er by deptno;

DEPTNO ENAME SAL LAG(ENAME,
———- ———- ———- ———-
10 CLARK 2450
KING 5000 CLARK
MILLER 1300 KING

20 ADAMS 1100
FORD 3000 ADAMS
JONES 2975 FORD
SCOTT 3000 JONES
SMITH 800 SCOTT

30 ALLEN 1600
BLAKE 2850 ALLEN
JAMES 950 BLAKE
MARTIN 1250 JAMES
TURNER 1500 MARTIN
WARD 1250 TURNER


已选择14行。

已用时间: 00: 00: 00.31
SQL> select deptno,ename,sal,lag(ename,2,’example’) over(partition by deptno order by ename) from em
p order by deptno;

DEPTNO ENAME SAL LAG(ENAME,
———- ———- ———- ———-
10 CLARK 2450 example
KING 5000 example
MILLER 1300 CLARK

20 ADAMS 1100 example
FORD 3000 example
JONES 2975 ADAMS
SCOTT 3000 FORD
SMITH 800 JONES

30 ALLEN 1600 example
BLAKE 2850 example
JAMES 950 ALLEN
MARTIN 1250 BLAKE
TURNER 1500 JAMES
WARD 1250 MARTIN

已选择14行。  

2006年02月18日
日志文件满而造成SQL数据库无法写入文件时,可用两种方法:
一种方法:清空日志。
1.打开查询分析器,输入命令
DUMP TRANSACTION 数据库名 WITH NO_LOG
2.再打开企业管理器–右键你要压缩的数据库–所有任务–收缩数据库–收缩文件–选择日志文件–在收缩方式里选择收缩至XXM,这里会给出一个允许收缩到的最小M数,直接输入这个数,确定就可以了。

另一种方法有一定的风险性,因为SQL SERVER的日志文件不是即时写入数据库主文件的,如处理不当,会造成数据的损失。
1: 删除LOG
分离数据库 企业管理器->服务器->数据库->右键->分离数据库
2:删除LOG文件
附加数据库 企业管理器->服务器->数据库->右键->附加数据库
此法生成新的LOG,大小只有500多K。

注意:建议使用第一种方法。

如果以后,不想要它变大。
SQL2000下使用:
在数据库上点右键->属性->选项->故障恢复-模型-选择-简单模型。
或用SQL语句:
alter database 数据库名 set recovery simple

另外,Truncate log on checkpoint(此选项用于SQL7.0,SQL 2000中即故障恢复模型选择为简单模型)当执行CHECKPOINT 命令时如果事务日志文件超过其大小的70% 则将其内容清除在开发数据库时时常将此选项设置为True Auto shrink定期对数据库进行检查当数据库文件或日志文件的未用空间超过其大小的25%时,系统将会自动缩减文件使其未用空间等于25% 当文件大小没有超过其建立时的初始大小时不会缩减文件缩减后的文件也必须大于或等于其初始大小对事务日志文件的缩减只有在对其作备份时或将Truncate log on checkpoint 选项设为True 时才能进行。

注意:一般立成建立的数据库默认属性已设好,但碰到意外情况使数据库属性被更改,请用户清空日志后,检查数据库的以上属性,以防事务日志再次充满。
2006年02月07日

–语 句 功 能
–数据操作
SELECT –从数据库表中检索数据行和列
INSERT –向数据库表添加新数据行
DELETE –从数据库表中删除数据行
UPDATE –更新数据库表中的数据
–数据定义
CREATE TABLE –创建一个数据库表
DROP TABLE –从数据库中删除表
ALTER TABLE –修改数据库表结构
CREATE VIEW –创建一个视图
DROP VIEW –从数据库中删除视图
CREATE INDEX –为数据库表创建一个索引
DROP INDEX –从数据库中删除索引
CREATE PROCEDURE –创建一个存储过程
DROP PROCEDURE –从数据库中删除存储过程
CREATE TRIGGER –创建一个触发器
DROP TRIGGER –从数据库中删除触发器
CREATE SCHEMA –向数据库添加一个新模式
DROP SCHEMA –从数据库中删除一个模式
CREATE DOMAIN –创建一个数据值域
ALTER DOMAIN –改变域定义
DROP DOMAIN –从数据库中删除一个域
–数据控制
GRANT –授予用户访问权限
DENY –拒绝用户访问
REVOKE –解除用户访问权限
–事务控制
COMMIT –结束当前事务
ROLLBACK –中止当前事务
SET TRANSACTION –定义当前事务数据访问特征
–程序化SQL
DECLARE –为查询设定游标
EXPLAN –为查询描述数据访问计划
OPEN –检索查询结果打开一个游标
FETCH –检索一行查询结果
CLOSE –关闭游标
PREPARE –为动态执行准备SQL 语句
EXECUTE –动态地执行SQL 语句
DESCRIBE –描述准备好的查询
—局部变量
declare @id char(10)
–set @id = ‘10010001′
select @id = ‘10010001′

—全局变量
—必须以@@开头



–IF ELSE
declare @x int @y int @z int
select @x = 1 @y = 2 @z=3
if @x > @y
print ‘x > y’ –打印字符串’x > y’
else if @y > @z
print ‘y > z’
else print ‘z > y’



–CASE
use pangu
update employee
set e_wage =
case
when job_level = ’1’ then e_wage*1.08
when job_level = ’2’ then e_wage*1.07
when job_level = ’3’ then e_wage*1.06
else e_wage*1.05
end



–WHILE CONTINUE BREAK
declare @x int @y int @c int
select @x = 1 @y=1
while @x < 3
begin
print @x –打印变量x 的值
while @y < 3
begin
select @c = 100*@x + @y
print @c –打印变量c 的值
select @y = @y + 1
end
select @x = @x + 1
select @y = 1
end



–WAITFOR
–例 等待1 小时2 分零3 秒后才执行SELECT 语句
waitfor delay ’01:02:03’
select * from employee
–例 等到晚上11 点零8 分后才执行SELECT 语句
waitfor time ’23:08:00’
select * from employee




***SELECT***



select *(列名) from table_name(表名) where column_name operator value
ex:(宿主)
select * from stock_information where stockid = str(nid)
stockname = ’str_name’
stockname like ‘% find this %’
stockname like ‘[a-zA-Z]%’ ——— ([]指定值的范围)
stockname like ‘[^F-M]%’ ——— (^排除指定范围)
——— 只能在使用like关键字的where子句中使用通配符)
or stockpath = ’stock_path’
or stocknumber < 1000
and stockindex = 24
not stock*** = ‘man’
stocknumber between 20 and 100
stocknumber in(10,20,30)
order by stockid desc(asc) ——— 排序,desc-降序,asc-升序
order by 1,2 ——— by列号
stockname = (select stockname from stock_information where stockid = 4)
——— 子查询
——— 除非能确保内层select只返回一个行的值,
——— 否则应在外层where子句中用一个in限定符
select distinct column_name form table_name ——— distinct指定检索独有的列值,不重复
select stocknumber ,"stocknumber + 10" = stocknumber + 10 from table_name
select stockname , "stocknumber" = count(*) from table_name group by stockname
——— group by 将表按行分组,指定列中有相同的值
having count(*) = 2 ——— having选定指定的组



select *
from table1, table2
where table1.id *= table2.id ——– 左外部连接,table1中有的而table2中没有得以null表示
table1.id =* table2.id ——– 右外部连接



select stockname from table1
union [all] —– union合并查询结果集,all-保留重复行
select stockname from table2



***insert***



insert into table_name (Stock_name,Stock_number) value ("xxx","xxxx")
value (select Stockname , Stocknumber from Stock_table2)—value为select语句



***update***



update table_name set Stockname = "xxx" [where Stockid = 3]
Stockname = default
Stockname = null
Stocknumber = Stockname + 4



***delete***



delete from table_name where Stockid = 3
truncate table_name ———– 删除表中所有行,仍保持表的完整性
drop table table_name ————— 完全删除表



***alter table*** — 修改数据库表结构



alter table database.owner.table_name add column_name char(2) null …..
sp_help table_name —- 显示表已有特征
create table table_name (name char(20), age smallint, lname varchar(30))
insert into table_name select ……… —– 实现删除列的方法(创建新表)
alter table table_name drop constraint Stockname_default —- 删除Stockname的default约束



***function(/*常用函数*/)***



—-统计函数—-
AVG –求平均值
COUNT –统计数目
MAX –求最大值
MIN –求最小值
SUM –求和



–AVG
use pangu
select avg(e_wage) as dept_avgWage
from employee
group by dept_id

–MAX
–求工资最高的员工姓名
use pangu
select e_name
from employee
where e_wage =
(select max(e_wage)
from employee)



–STDEV()
–STDEV()函数返回表达式中所有数据的标准差



–STDEVP()
–STDEVP()函数返回总体标准差



–VAR()
–VAR()函数返回表达式中所有值的统计变异数



–VARP()
–VARP()函数返回总体变异数



—-算术函数—-



/***三角函数***/
SIN(float_expression) –返回以弧度表示的角的正弦
COS(float_expression) –返回以弧度表示的角的余弦
TAN(float_expression) –返回以弧度表示的角的正切
COT(float_expression) –返回以弧度表示的角的余切
/***反三角函数***/
ASIN(float_expression) –返回正弦是FLOAT 值的以弧度表示的角
ACOS(float_expression) –返回余弦是FLOAT 值的以弧度表示的角
ATAN(float_expression) –返回正切是FLOAT 值的以弧度表示的角
ATAN2(float_expression1,float_expression2)
–返回正切是float_expression1 /float_expres-sion2的以弧度表示的角
DEGREES(numeric_expression)
–把弧度转换为角度返回与表达式相同的数据类型可为
–INTEGER/MONEY/REAL/FLOAT 类型
RADIANS(numeric_expression) –把角度转换为弧度返回与表达式相同的数据类型可为
–INTEGER/MONEY/REAL/FLOAT 类型
EXP(float_expression) –返回表达式的指数值
LOG(float_expression) –返回表达式的自然对数值
LOG10(float_expression)–返回表达式的以10 为底的对数值
SQRT(float_expression) –返回表达式的平方根
/***取近似值函数***/
CEILING(numeric_expression) –返回>=表达式的最小整数返回的数据类型与表达式相同可为
–INTEGER/MONEY/REAL/FLOAT 类型
FLOOR(numeric_expression) –返回<=表达式的最小整数返回的数据类型与表达式相同可为
–INTEGER/MONEY/REAL/FLOAT 类型
ROUND(numeric_expression) –返回以integer_expression 为精度的四舍五入值返回的数据
–类型与表达式相同可为INTEGER/MONEY/REAL/FLOAT 类型
ABS(numeric_expression) –返回表达式的绝对值返回的数据类型与表达式相同可为
–INTEGER/MONEY/REAL/FLOAT 类型
SIGN(numeric_expression) –测试参数的正负号返回0 零值1 正数或-1 负数返回的数据类型
–与表达式相同可为INTEGER/MONEY/REAL/FLOAT 类型
PI() –返回值为π 即3.1415926535897936
RAND([integer_expression]) –用任选的[integer_expression]做种子值得出0-1 间的随机浮点数




—-字符串函数—-
ASCII() –函数返回字符表达式最左端字符的ASCII 码值
CHAR() –函数用于将ASCII 码转换为字符
–如果没有输入0 ~ 255 之间的ASCII 码值CHAR 函数会返回一个NULL 值
LOWER() –函数把字符串全部转换为小写
UPPER() –函数把字符串全部转换为大写
STR() –函数把数值型数据转换为字符型数据
LTRIM() –函数把字符串头部的空格去掉
RTRIM() –函数把字符串尾部的空格去掉
LEFT(),RIGHT(),SUBSTRING() –函数返回部分字符串
CHARINDEX(),PATINDEX() –函数返回字符串中某个指定的子串出现的开始位置
SOUNDEX() –函数返回一个四位字符码
–SOUNDEX函数可用来查找声音相似的字符串但SOUNDEX函数对数字和汉字均只返回0 值
DIFFERENCE() –函数返回由SOUNDEX 函数返回的两个字符表达式的值的差异
–0 两个SOUNDEX 函数返回值的第一个字符不同
–1 两个SOUNDEX 函数返回值的第一个字符相同
–2 两个SOUNDEX 函数返回值的第一二个字符相同
–3 两个SOUNDEX 函数返回值的第一二三个字符相同
–4 两个SOUNDEX 函数返回值完全相同




QUOTENAME() –函数返回被特定字符括起来的字符串
/*select quotename(‘abc’, ‘{‘) quotename(‘abc’)
运行结果如下
———————————-{
{abc} [abc]*/



REPLICATE() –函数返回一个重复character_expression 指定次数的字符串
/*select replicate(‘abc’, 3) replicate( ‘abc’, -2)
运行结果如下
———– ———–
abcabcabc NULL*/



REVERSE() –函数将指定的字符串的字符排列顺序颠倒
REPLACE() –函数返回被替换了指定子串的字符串
/*select replace(‘abc123g’, ‘123′, ‘def’)
运行结果如下
———– ———–
abcdefg*/



SPACE() –函数返回一个有指定长度的空白字符串
STUFF() –函数用另一子串替换字符串指定位置长度的子串




—-数据类型转换函数—-
CAST() 函数语法如下
CAST() (<expression> AS <data_ type>[ length ])
CONVERT() 函数语法如下
CONVERT() (<data_ type>[ length ], <expression> [, style])



select cast(100+99 as char) convert(varchar(12), getdate())
运行结果如下
—————————— ————
199 Jan 15 2000



—-日期函数—-
DAY() –函数返回date_expression 中的日期值
MONTH() –函数返回date_expression 中的月份值
YEAR() –函数返回date_expression 中的年份值
DATEADD(<datepart> ,<number> ,<date>)
–函数返回指定日期date 加上指定的额外日期间隔number 产生的新日期
DATEDIFF(<datepart> ,<number> ,<date>)
–函数返回两个指定日期在datepart 方面的不同之处
DATENAME(<datepart> , <date>) –函数以字符串的形式返回日期的指定部分
DATEPART(<datepart> , <date>) –函数以整数值的形式返回日期的指定部分
GETDATE() –函数以DATETIME 的缺省格式返回系统当前的日期和时间



—-系统函数—-
APP_NAME() –函数返回当前执行的应用程序的名称
COALESCE() –函数返回众多表达式中第一个非NULL 表达式的值
COL_LENGTH(<’table_name’>, <’column_name’>) –函数返回表中指定字段的长度值
COL_NAME(<table_id>, <column_id>) –函数返回表中指定字段的名称即列名
DATALENGTH() –函数返回数据表达式的数据的实际长度
DB_ID(['database_name']) –函数返回数据库的编号
DB_NAME(database_id) –函数返回数据库的名称
HOST_ID() –函数返回服务器端计算机的名称
HOST_NAME() –函数返回服务器端计算机的名称
IDENTITY(<data_type>[, seed increment]) [AS column_name])
–IDENTITY() 函数只在SELECT INTO 语句中使用用于插入一个identity column列到新表中
/*select identity(int, 1, 1) as column_name
into newtable
from oldtable*/
ISDATE() –函数判断所给定的表达式是否为合理日期
ISNULL(<check_expression>, <replacement_value>) –函数将表达式中的NULL 值用指定值替换
ISNUMERIC() –函数判断所给定的表达式是否为合理的数值
NEWID() –函数返回一个UNIQUEIDENTIFIER 类型的数值
NULLIF(<expression1>, <expression2>)
–NULLIF 函数在expression1 与expression2 相等时返回NULL 值若不相等时则返回expression1 的值







sql中的保留字



action add aggregate all
alter after and as
asc avg avg_row_length auto_increment
between bigint bit binary
blob bool both by
cascade case char character
change check checksum column
columns comment constraint create
cross current_date current_time current_timestamp
data database databases date
datetime day day_hour day_minute
day_second dayofmonth dayofweek dayofyear
dec decimal default delayed
delay_key_write delete desc describe
distinct distinctrow double drop
end else escape escaped
enclosed enum explain exists
fields file first float
float4 float8 flush foreign
from for full function
global grant grants group
having heap high_priority hour
hour_minute hour_second hosts identified
ignore in index infile
inner insert insert_id int
integer interval int1 int2
int3 int4 int8 into
if is isam join
key keys kill last_insert_id
leading left length like
lines limit load local
lock logs long longblob
longtext low_priority max max_rows
match mediumblob mediumtext mediumint
middleint min_rows minute minute_second
modify month monthname myisam
natural numeric no not
null on optimize option
optionally or order outer
outfile pack_keys partial password
precision primary procedure process
processlist privileges read real
references reload regexp rename
replace restrict returns revoke
rlike row rows second
select set show shutdown
smallint soname sql_big_tables sql_big_selects
sql_low_priority_updates sql_log_off sql_log_update sql_select_limit
sql_small_result sql_big_result sql_warnings straight_join
starting status string table
tables temporary terminated text
then time timestamp tinyblob
tinytext tinyint trailing to
type use using unique
unlock unsigned update usage
values varchar variables varying
varbinary with write when
where year year_month zerofill