同城约会| 杂志期刊| 小说| 两性论坛| 军事电影| 两性知识| 电脑知识| 汽车| 旅游| 收藏

使用 Informix 系统目录(1)

来源: 作者: 出处:综艺读书 2005-11-29 
关 键 词:邮件  数据库  数据仓库  设计  解决方案  

针对 stores_demo 数据库中的 sysdistrib 表运行该查询,我们将看到:

tabname colname grantor grantee colauth
Sysdistrib tabid informix public s--
Sysdistrib colno informix public s--
Sysdistrib seqno informix public s--
Sysdistrib constructed informix public s--
Sysdistrib mode informix public s--
Sysdistrib resolution informix public s--
Sysdistrib confidence informix public s--
Sysdistrib encdat
Sysdistrib type informix public s--

ublic 仅被授予了选择任何列的权限。没有为 encdat 列指定任何许可权。colauth 可能会在第二个位置包含“u”(表示更新特权),并且/或者在第三个位置包含“r”(表示引用特权)。

存储过程

最好使用 dbschema 抽取存储过程。但是,在用来定义存储过程的结构中,还有一些重要的信息。

过程本身是在 sysprocedures 表中描述的。过程的主体(文本形式和已编译形式)存储在 sysprocbody表中。

因此,可以用如下语句访问存储过程的文本:


SELECT data, seqno 
  FROM sysprocbody a, sysprocedures b
 WHERE a.procid = b.procid
   AND b.procname = ?
   AND datakey = 'T'
 ORDER BY seqno

该过程的优化方案存储在 sysprocplan 中。在创建过程时创建该方案,而且每当执行 update statistics for procedure <procedure> 时则会更新该方案。因为存储过程所用的表的内容可能会随时间变化而更改,所以定期地更新这个优化方案是明智的。sysprocplan 表中有一个名为 created的列,它表明方案的最近一次更新时间。用于过程的更新统计信息例程可能会从选择过程的名称开始,这些过程的统计信息应当进行更新:


SELECT procname 
  FROM sysprocedures a, sysprocplan b
 WHERE a.procid = b.procid
   AND created < today - 7;

ysprocauth 维护着针对过程的许可权。对于确定谁有权访问某个过程,这可能很有用。请记住,过程是用创建该过程的用户的许可权运行的。

引用完整性和其它链接

引用完整性的问题之一是:在重新组织关系中的某个表之前,我们可能需要删除或禁用某个外键约束。附录中的 depend.sh 脚本将有助于我们对这方面的理解。

ysconstraints 表拥有数据库中每个约束的纪录。每种约束都有不同的类型(constrtype):

C
检查(Check)
P
主键(Primary key)
R
引用(外键)(Reference,Foreign Key)
U
唯一性(Unique)
N
非空(Not Null)

通过 sysreferences 表,这些约束又将源表和引用表联系到一起(用于引用键)。


SELECT a.tabname, constrname, d.tabname
  FROM systables a, sysconstraints b, sysreferences c,
       systables d
 WHERE b.constrtype = 'R'
   AND a.tabid = b.tabid
   AND b.constrid = c.constrid
   AND c.ptabid = d.tabid
   AND a.tabname = ?;

这会显示第一个表,以及引用约束和被引用的表。

我们可能还希望将对象状态附加到上述查询,这样就可以确定是否禁用了某个约束。此处, sysobjstate 表会帮助我们实现这一点。它按名称跟踪约束、触发器和索引。要抽取该信息,我们可以将查询更改为:


SELECT a.tabname, constrname, d.tabname, e.state
  FROM systables a, sysconstraints b, sysreferences c,
       systables d, sysobjstate e
 WHERE b.constrtype = 'R'
   AND a.tabid = b.tabid
   AND b.constrid = c.constrid
   AND b.constrname = e.name
   AND c.ptabid = d.tabid
   AND a.tabname = ?;

syschecks表也很重要,它标识了检查约束。它有一个匹配的表 syscoldepend,该表标识了从属表和列。这里有一个有用的查询:


SELECT a.constrname, a.constrtype, b.tabname, c.colname,
       d.checktext
  FROM sysconstraints a, systables b, syscolumns c, 
       syschecks d, syscoldepend e
 WHERE a.constrid = d.constrid
   AND a.constrid = e.constrid
   AND e.tabid = b.tabid
   AND e.colno = c.colno
   AND b.tabid = c.tabid
   AND d.type = 'C'

对我们友好的 stores 数据库进行查询,产生了如下结果:

Constrname c104_15
Constrtype C
Tabname items
Colname quantity
Checktext (quantity >= 1)

这表明对于 items 表中的 quantity 列有检查约束(quantity >=1)。约束名可以任取。

结束语

系统目录不仅对于数据仓库的元数据需求或逆向工程需求而言是有用的帮手,而且对于数据库的日常维护也是如此。还有其它几个系统目录以及 sysutil 和 sysmaster 数据库,它们恰好是另一篇文章所讨论的主题。这些目录和数据库的数量和内容都随着产品的发展而发展,尽管原始目录仍然存在着。当我们确定数据库中的元数据需求时,应该检查这些目录 — 也许我们所需要的东西已经在那里了。

附录

也可以从下列地址下载本文中所讨论代码的电子版本:

4gl 函数(dbdiff2) http://www.iiug.org/software/index_DBA.html
analyse_idx http://www.iiug.org/software/index_DBA.html
findcol 和 depend.sh http://www.artentech.com/downloads.htm

这个附录中复制了这些代码,以提供进一步的示例。

清单 1. 4gl 函数


#############################################################
# Convert coltype/length into an SQL descriptor string
#############################################################
FUNCTION col_cnvrt(coltype, collength)

   DEFINE coltype, collength, NONULL SMALLINT,
          SQL_strg CHAR(40),
  tmp_strg CHAR(4)

   LET coltype = coltype + 1  # datatype[] is offset by one
   LET NONULL  = coltype/256  # if > 256 then is NO NULLS
   LET coltype = coltype MOD 256  # lose the NO NULLS determinator

   LET SQL_strg = datatype[coltype] # basic datatype

   CASE coltype

      WHEN 1# char
       LET tmp_strg = collength using "<<<<"
       LET SQL_strg = SQL_strg clipped, " (", tmp_strg clipped, ")"

# SQL syntax supports float(n) - Informix ignores this
# WHEN 4    # float
#  LET SQL_strg = SQL_strg clipped, " (", ")"

  WHEN 6    # decimal
   LET SQL_strg = SQL_strg clipped, " (", fix_nm(collength,0) clipped, ")"

# Syntax supports serial(starting_no) - starting_no is unavaliable
#  WHEN 7    # serial
#  LET SQL_strg = SQL_strg clipped, " (", ")"

   WHEN 9    # money
   LET SQL_strg = SQL_strg clipped, " (", fix_nm(collength,0) clipped, ")"

  WHEN 11 # datetime
   LET SQL_strg = SQL_strg clipped, " ", fix_dt(collength) clipped 

  WHEN 14 # varchar
   LET SQL_strg = SQL_strg clipped, " (", fix_nm(collength,1) clipped, ")"

  WHEN 15 # interval
   LET SQL_strg = SQL_strg clipped, " ", fix_dt(collength) clipped

   END CASE

 IF NONULL THEN
  LET SQL_strg = SQL_strg clipped, " NOT NULL"
 END IF
      
 RETURN SQL_strg

END FUNCTION

##############################################################
# Turn collength into two numbers - return as string
##############################################################
FUNCTION fix_nm(num,tp)

DEFINE num integer,
       tp smallint,
       strg CHAR(8),
       i, j   SMALLINT,
       strg1, strg2 char(3)

   LET i = num / 256
   LET j = num MOD 256
   LET strg1 = i using "<<&"
   LET strg2 = j using "<<&"
   IF tp = 0 THEN
      IF j > i THEN
         LET strg = strg1 clipped
      ELSE
         LET strg = strg1 clipped, ", ", strg2 clipped
      END IF
   ELSE# varchar is just the opposite
      IF i = 0 THEN
         LET strg = strg2 clipped
      ELSE
         LET strg = strg2 clipped, ", ", strg1 clipped
      END IF
   END IF

   RETURN strg

END FUNCTION
##############################################################
# Turn collength into meaningful date info - return as string
##############################################################
FUNCTION fix_dt(num)
DEFINE num integer,
       i, j, k, len   SMALLINT,
       strg CHAR(30)

   LET i   = (num mod 16) + 1# offset again
   LET j   = ((num mod 256) / 16) + 1# offset again
   LET k   = num / 256# length of value

# If this is an interval then life gets interesting, 'k' is 
# the length of the entire string.  So a YEAR TO DAY is 
# YYYYMMDD or 8.  A DAY(3) TO MINUTE is DDDHHMM or 7.  
# We don't know how long the first one is, but 
# we can work it out by computing the 'should 
# be length' of the string and then adding/subtracting 
# the result from the 'should be length' of 
# the major element.
#
# Keep in mind --->    YYYYMMDDHHMMSSFFFFF
#     vs.         j =    1  2 3 4 5 678901
#
# I was just working an algorithm to do this, 4 
# notepads, 90 minutes, and 50 lines into it I realized
# that I was creating something impossible to test or 
# maintain.  Therefore I am opting for something a lot simpler.
#
# In the globals I have created an ARRAY of RECORD with 
# start and end points for the major and minor pieces.  
# By subtracting the START point of the 
# major element from the END point of the minor element
#  I get the 'should be length'
#

LET len = intvray[i].end_point - intvray[j].start_point

# len should match k.e.g.:
#DAY(5) TO MINUTE  ==> k = 9, len = 6
#YEAR(6) TO HOUR   ==> k = 12, len = 14

   LET len = k - len    # add len to the major

   IF len = 0 OR j > 11 THEN   # is the default
# 12 on have the precision already coded

    LET strg = datetype[j] clipped, " TO ", datetype[i] clipped

   ELSE# isn't the default

# uh-oh, how long IS the default major?
   LET k = intvray[j].end_point - intvray[j].start_point 

# add in the extra
   LET k = k + len

   LET strg = datetype[j] clipped, "(", k using "<<", ")", " TO ", 
                 datetype[i] clipped
   
   END IF

   RETURN strg

END FUNCTION
#############################################
Required global definitions:
   DEFINE  datatype ARRAY[40] OF CHAR(20), # for coltype conversions
           datetype ARRAY[16] OF CHAR(11), 
           intvray  ARRAY[16] OF RECORD
              start_point SMALLINT,
              end_point SMALLINT
           END RECORD

   LET datatype[1]  = "CHAR"
   LET datatype[2]  = "SMALLINT"
   LET datatype[3]  = "INTEGER"
   LET datatype[4]  = "FLOAT"
   LET datatype[5]  = "SMALLFLOAT"
   LET datatype[6]  = "DECIMAL"
   LET datatype[7]  = "SERIAL"
   LET datatype[8]  = "DATE"
   LET datatype[9]  = "MONEY"
   LET datatype[10] = "UNKNOWN"
   LET datatype[11] = "DATETIME"
   LET datatype[12] = "BYTE"
   LET datatype[13] = "TEXT"
   LET datatype[14] = "VARCHAR"
   LET datatype[15] = "INTERVAL"
   LET datatype[16] = "NCHAR"
   LET datatype[17] = "NVARCHAR"
   LET datatype[18] = "UNKNOWN"# little room for growth
   LET datatype[19] = "UNKNOWN"
   LET datatype[20] = "UNKNOWN"

   LET datetype[1] = "YEAR"
   LET intvray[1].start_point = 1
   LET intvray[1].end_point = 5# offset by one for easy math

   LET datetype[3] = "MONTH"
   LET intvray[3].start_point = 5
   LET intvray[3].end_point = 7

   LET datetype[5] = "DAY"
   LET intvray[5].start_point = 7
   LET intvray[5].end_point = 9

   LET datetype[7] = "HOUR"
   LET intvray[7].start_point = 9
   LET intvray[7].end_point = 11

   LET datetype[9] = "MINUTE"
   LET intvray[9].start_point = 11
   LET intvray[9].end_point = 13

   LET datetype[11] = "SECOND"
   LET intvray[11].start_point = 13
   LET intvray[11].end_point = 15

   LET datetype[12] = "FRACTION(1)"
   LET intvray[12].start_point = 15
   LET intvray[12].end_point = 16

   LET datetype[13] = "FRACTION(2)"
   LET intvray[13].start_point = 16
   LET intvray[13].end_point = 17

   LET datetype[14] = "FRACTION(3)"
   LET intvray[14].start_point = 17
   LET intvray[14].end_point = 18

   LET datetype[15] = "FRACTION(4)"
   LET intvray[15].start_point = 18
   LET intvray[15].end_point = 19

   LET datetype[16] = "FRACTION(5)"
   LET intvray[16].start_point = 19
   LET intvray[16].end_point = 20


更多文章 更多内容请看informix  系统安全设置  系统安装手册专题,或进入讨论组讨论。

收藏此文】【 】【打印】【关闭
较早的文章:
较新的文章:IBM Informix Dynamic数据库服务器介绍
相关图文阅读
频道图文推荐
综艺读书宗旨
相关专题
·系统优化大全 (13888篇文章)
·系统安全设置 (18678篇文章)
·系统安装手册 (16366篇文章)
·系统备份专题 (13499篇文章)
·informix (193篇文章)
·系统维护手册 (13037篇文章)
热点标签: 邮件  数据库  数据仓库  设计  解决方案  
最新技术文档
站内各频道最新更新文档
站内最新制作专题
热门关键字导读
Photoshop教 程照片处理 照片制作 PS快捷键 抠图
计 算 机 故 障XP系统修复
艺 术 与 设 计设计 流媒体 设计欣赏 边框
计 算 机 安 全ARP
站内频道文章精选
百度推荐,商机无限
搜索您感兴趣的内容
Web 全站
综艺电脑频道编辑信箱  告诉我们您想看的专题或文章

Google

友情互链 | 收藏本站 | 联系我们 | 在线留言 | 京ICP备08008424号|