??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲精品视频在线观看免费,亚洲精品永久在线观看,亚洲精品一级无码鲁丝片http://www.tkk7.com/nbtymm/archive/2006/08/07/62144.htmlnbtnbtMon, 07 Aug 2006 04:09:00 GMThttp://www.tkk7.com/nbtymm/archive/2006/08/07/62144.htmlhttp://www.tkk7.com/nbtymm/comments/62144.htmlhttp://www.tkk7.com/nbtymm/archive/2006/08/07/62144.html#Feedback0http://www.tkk7.com/nbtymm/comments/commentRss/62144.htmlhttp://www.tkk7.com/nbtymm/services/trackbacks/62144.html     在数据库设计中,有两U方法可讑֮自动化的资料处理规则Q一U是条gU束Q?br />一U是触发?一般而言Q条件约束比触发器较Ҏ(gu)讑֮及维护,且执行效率较
好,但条件约束只能对资料q行单的栏位核,当涉及到多表操作{复杂操
作时Q就要用到触发器?
      一个数据库pȝ中有两个虚拟表用于存储在表中记录改动的信息,分别
 是:
                 虚拟表Inserted                    虚拟表Deleted

在表记录新增时 ?存放新增的记录                      ?不存储记?br />        修改时 ?存放用来更新的新记录                  存放更新前的记录
        删除时 ?不存储记录                          ?存放被删除的记录
 
      触发器的U类及触发时?br /> After触发器:触发时机在资料已变动完成后,它将对变动资料进行必要的
              善后与处理,若发现有错误Q则用事务回滚(Rollback Transaction)
              此ơ操作所更动的资料全部回复?br /> Istead of 触发器:触发时机在资料变动前发生Q且资料如何变动取决于触发器

现在介绍一下创发器的编写格式:

Aftercd:
    Create Trigger  触发器名U?br />    on 表名
    after 操作(insert,update)
    as 
      Sql语句

Insteadcd
    Create Trigger 触发器名U?br />    on 表名
    Instead of 操作(update,delete)
    as
      Sql语句

实例1:
     在订?表orders)中的订购数量(列名为num)有变动时Q触发器会先到客?表Customer)?br />取得该用L(fng)信用{(列名为Level),然后再到信用额度(Creit)中取{
许可的订购数量上下限Q最后比较订单中的订购数量是否符合限制?/p>

代码Q        ?
           Create  Trigger num_check
           on orders
           after insert,update
           as
           if update(num)
             begin
               if exists(select a.* from orders a join customer b on a.customerid=b.customerid
                                                  join creit c on b.level=c.level
                                                  where a.num between c.up and c.down)
               begin
                  rollback transaction
                  exec master..xp_sendmail 'administrator','客户的订购数量不W合限制'
               end  
             end 
实例2:
      有工资管理系l中Q当公司Ҏ(gu)员工甲的月薪q行调整Ӟ通常会先在表员工中修改薪资列,然后?br />      表员工记录中修改薪资调整旉与薪?br />           
          Create trigger compensation
          on 员工
          after update
          as
            if @@rowcount=0 return
            if update(薪资)
               begin
                 insert 员工记录
                 select 员工遍号,薪资,getdate()
                 from inserted
               end



nbt 2006-08-07 12:09 发表评论
]]>
收藏几段SQL Server语句和存储过E?http://www.tkk7.com/nbtymm/archive/2006/08/07/62143.htmlnbtnbtMon, 07 Aug 2006 04:05:00 GMThttp://www.tkk7.com/nbtymm/archive/2006/08/07/62143.htmlhttp://www.tkk7.com/nbtymm/comments/62143.htmlhttp://www.tkk7.com/nbtymm/archive/2006/08/07/62143.html#Feedback0http://www.tkk7.com/nbtymm/comments/commentRss/62143.htmlhttp://www.tkk7.com/nbtymm/services/trackbacks/62143.html(转蝲?-http://www.cnblogs.com/qiubole/articles/157309.html)


-- ======================================================

--列出SQL SERVER 所有表Q字D名Q主键,cdQ长度,数位数{信?/p>

--在查询分析器里运行即?可以生成一个表Q导出到EXCEL?/p>

-- ======================================================

SELECT

       (case when a.colorder=1 then d.name else '' end)表名,

       a.colorder 字段序号,

       a.name 字段?

       (case when COLUMNPROPERTY( a.id,a.name,'IsIdentity')=1 then '?else '' end) 标识,

       (case when (SELECT count(*)

       FROM sysobjects

       WHERE (name in

                 (SELECT name

                FROM sysindexes

                WHERE (id = a.id) AND (indid in

                          (SELECT indid

                         FROM sysindexkeys

                         WHERE (id = a.id) AND (colid in

                                   (SELECT colid

                                  FROM syscolumns

                                  WHERE (id = a.id) AND (name = a.name))))))) AND

              (xtype = 'PK'))>0 then '? else '' end) 主键,

       b.name cd,

       a.length 占用字节?

       COLUMNPROPERTY(a.id,a.name,'PRECISION') as 长度,

       isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0) as 数位数,

       (case when a.isnullable=1 then '?else '' end) 允许I?

       isnull(e.text,'') 默认?

       isnull(g.[value],'') AS 字段说明   

 

FROM  syscolumns  a left join systypes b

on  a.xtype=b.xusertype

inner join sysobjects d

on a.id=d.id  and  d.xtype='U' and  d.name<>'dtproperties'

left join syscomments e

on a.cdefault=e.id

left join sysproperties g

on a.id=g.id AND a.colid = g.smallid 

order by a.id,a.colorder

-------------------------------------------------------------------------------------------------

 

 

 

 

 

 

列出SQL SERVER 所有表、字D定义,cdQ长度,一个值等信息

q导出到Excel ?/p>

-- ======================================================

-- Export all user tables definition and one sample value

-- jan-13-2003,Dr.Zhang

-- ======================================================

在查询分析器里运行:

SET ANSI_NULLS OFF

GO

SET NOCOUNT ON

GO

 

SET LANGUAGE 'Simplified Chinese'

go

DECLARE @tbl nvarchar(200),@fld nvarchar(200),@sql nvarchar(4000),@maxlen int,@sample nvarchar(40)

 

SELECT d.name TableName,a.name FieldName,b.name TypeName,a.length Length,a.isnullable IS_NULL INTO #t

FROM  syscolumns  a,  systypes b,sysobjects d 

WHERE  a.xtype=b.xusertype  and  a.id=d.id  and  d.xtype='U'

 

DECLARE read_cursor CURSOR

FOR SELECT TableName,FieldName FROM #t

 

SELECT TOP 1 '_TableName                     ' TableName,

            'FieldName                      ' FieldName,'TypeName             ' TypeName,

            'Length' Length,'IS_NULL' IS_NULL,

            'MaxLenUsed' AS MaxLenUsed,'Sample Value          ' Sample,

             'Comment   ' Comment INTO #tc FROM #t

 

OPEN read_cursor

 

FETCH NEXT FROM read_cursor INTO @tbl,@fld

WHILE (@@fetch_status <> -1)  --- failes

BEGIN

       IF (@@fetch_status <> -2) -- Missing

       BEGIN

              SET @sql=N'SET @maxlen=(SELECT max(len(cast('+@fld+' as nvarchar))) FROM '+@tbl+')'

              --PRINT @sql

              EXEC SP_EXECUTESQL @sql,N'@maxlen int OUTPUT',@maxlen OUTPUT

              --print @maxlen

              SET @sql=N'SET @sample=(SELECT TOP 1 cast('+@fld+' as nvarchar) FROM '+@tbl+' WHERE len(cast('+@fld+' as nvarchar))='+convert(nvarchar(5),@maxlen)+')'

              EXEC SP_EXECUTESQL @sql,N'@sample varchar(30) OUTPUT',@sample OUTPUT

              --for quickly  

              --SET @sql=N'SET @sample=convert(varchar(20),(SELECT TOP 1 '+@fld+' FROM '+

                     --@tbl+' order by 1 desc ))' 

              PRINT @sql

              print @sample

              print @tbl

              EXEC SP_EXECUTESQL @sql,N'@sample nvarchar(30) OUTPUT',@sample OUTPUT

              INSERT INTO #tc SELECT *,ltrim(ISNULL(@maxlen,0)) as MaxLenUsed,

                     convert(nchar(20),ltrim(ISNULL(@sample,' '))) as Sample,' ' Comment FROM #t where TableName=@tbl and FieldName=@fld

       END

       FETCH NEXT FROM read_cursor INTO @tbl,@fld

END

 

CLOSE read_cursor

DEALLOCATE read_cursor

GO

 

SET ANSI_NULLS ON

GO

SET NOCOUNT OFF

GO

select count(*)  from #t

DROP TABLE #t

GO

 

select count(*)-1  from #tc

 

select * into ##tx from #tc order by tablename

DROP TABLE #tc

 

--select * from ##tx

 

declare @db nvarchar(60),@sql nvarchar(3000)

set @db=db_name()

--请修改用户名和口?导出到Excel ?/p>

set @sql='exec master.dbo.xp_cmdshell ''bcp ..dbo.##tx out c:\'+@db+'_exp.xls -w -C936 -Usa -Psa '''

print @sql

exec(@sql)

GO

DROP TABLE ##tx

GO

 

 

 

-- ======================================================

--Ҏ(gu)表中数据生成insert语句的存储过E?/p>

--建立存储q程Q执?spGenInsertSQL 表名

--感谢playyuer

-- ======================================================

CREATE   proc spGenInsertSQL (@tablename varchar(256))

 

as

begin

  declare @sql varchar(8000)

  declare @sqlValues varchar(8000)

  set @sql =' ('

  set @sqlValues = 'values (''+'

  select @sqlValues = @sqlValues + cols + ' + '','' + ' ,@sql = @sql + '[' + name + '],'

    from

        (select case

                  when xtype in (48,52,56,59,60,62,104,106,108,122,127)                               

                       then 'case when '+ name +' is null then ''NULL'' else ' + 'cast('+ name + ' as varchar)'+' end'

                  when xtype in (58,61)

                       then 'case when '+ name +' is null then ''NULL'' else '+''''''''' + ' + 'cast('+ name +' as varchar)'+ '+'''''''''+' end'

                 when xtype in (167)

                       then 'case when '+ name +' is null then ''NULL'' else '+''''''''' + ' + 'replace('+ name+','''''''','''''''''''')' + '+'''''''''+' end'

                  when xtype in (231)

                       then 'case when '+ name +' is null then ''NULL'' else '+'''N'''''' + ' + 'replace('+ name+','''''''','''''''''''')' + '+'''''''''+' end'

                  when xtype in (175)

                       then 'case when '+ name +' is null then ''NULL'' else '+''''''''' + ' + 'cast(replace('+ name+','''''''','''''''''''') as Char(' + cast(length as varchar)  + '))+'''''''''+' end'

                  when xtype in (239)

                       then 'case when '+ name +' is null then ''NULL'' else '+'''N'''''' + ' + 'cast(replace('+ name+','''''''','''''''''''') as Char(' + cast(length as varchar)  + '))+'''''''''+' end'

                  else '''NULL'''

                end as Cols,name

           from syscolumns 

          where id = object_id(@tablename)

        ) T

  set @sql ='select ''INSERT INTO ['+ @tablename + ']' + left(@sql,len(@sql)-1)+') ' + left(@sqlValues,len(@sqlValues)-4) + ')'' from '+@tablename

  --print @sql

  exec (@sql)

end

 

GO

 

 

 

-- ======================================================

--Ҏ(gu)表中数据生成insert语句的存储过E?/p>

--建立存储q程Q执?proc_insert 表名

--感谢Sky_blue

-- ======================================================

 

CREATE proc proc_insert (@tablename varchar(256))

as

begin

       set nocount on

       declare @sqlstr varchar(4000)

       declare @sqlstr1 varchar(4000)

       declare @sqlstr2 varchar(4000)

       select @sqlstr='select ''insert '+@tablename

       select @sqlstr1=''

       select @sqlstr2=' ('

       select @sqlstr1= ' values ( ''+'

       select @sqlstr1=@sqlstr1+col+'+'',''+' ,@sqlstr2=@sqlstr2+name +',' from (select case

--     when a.xtype =173 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar('+convert(varchar(4),a.length*2+2)+'),'+a.name +')'+' end'

       when a.xtype =104 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(1),'+a.name +')'+' end'

       when a.xtype =175 then 'case when '+a.name+' is null then ''NULL'' else '+'''''''''+'+'replace('+a.name+','''''''','''''''''''')' + '+'''''''''+' end'

       when a.xtype =61  then 'case when '+a.name+' is null then ''NULL'' else '+'''''''''+'+'convert(varchar(23),'+a.name +',121)'+ '+'''''''''+' end'

       when a.xtype =106 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar('+convert(varchar(4),a.xprec+2)+'),'+a.name +')'+' end'

       when a.xtype =62  then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(23),'+a.name +',2)'+' end'

       when a.xtype =56  then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(11),'+a.name +')'+' end'

       when a.xtype =60  then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(22),'+a.name +')'+' end'

       when a.xtype =239 then 'case when '+a.name+' is null then ''NULL'' else '+'''''''''+'+'replace('+a.name+','''''''','''''''''''')' + '+'''''''''+' end'

       when a.xtype =108 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar('+convert(varchar(4),a.xprec+2)+'),'+a.name +')'+' end'

       when a.xtype =231 then 'case when '+a.name+' is null then ''NULL'' else '+'''''''''+'+'replace('+a.name+','''''''','''''''''''')' + '+'''''''''+' end'

       when a.xtype =59  then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(23),'+a.name +',2)'+' end'

       when a.xtype =58  then 'case when '+a.name+' is null then ''NULL'' else '+'''''''''+'+'convert(varchar(23),'+a.name +',121)'+ '+'''''''''+' end'

       when a.xtype =52  then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(12),'+a.name +')'+' end'

       when a.xtype =122 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(22),'+a.name +')'+' end'

       when a.xtype =48  then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar(6),'+a.name +')'+' end'

--     when a.xtype =165 then 'case when '+a.name+' is null then ''NULL'' else '+'convert(varchar('+convert(varchar(4),a.length*2+2)+'),'+a.name +')'+' end'

       when a.xtype =167 then 'case when '+a.name+' is null then ''NULL'' else '+'''''''''+'+'replace('+a.name+','''''''','''''''''''')' + '+'''''''''+' end'

       else '''NULL'''

       end as col,a.colid,a.name

       from syscolumns a where a.id = object_id(@tablename) and a.xtype <>189 and a.xtype <>34 and a.xtype <>35 and  a.xtype <>36

       )t order by colid

      

       select @sqlstr=@sqlstr+left(@sqlstr2,len(@sqlstr2)-1)+') '+left(@sqlstr1,len(@sqlstr1)-3)+')'' from '+@tablename

--  print @sqlstr

       exec( @sqlstr)

       set nocount off

end

GO



nbt 2006-08-07 12:05 发表评论
]]>
Transact SQL 常用语句以及函数易说?含示? http://www.tkk7.com/nbtymm/archive/2006/08/07/62141.htmlnbtnbtMon, 07 Aug 2006 03:58:00 GMThttp://www.tkk7.com/nbtymm/archive/2006/08/07/62141.htmlhttp://www.tkk7.com/nbtymm/comments/62141.htmlhttp://www.tkk7.com/nbtymm/archive/2006/08/07/62141.html#Feedback0http://www.tkk7.com/nbtymm/comments/commentRss/62141.htmlhttp://www.tkk7.com/nbtymm/services/trackbacks/62141.html阅读全文

nbt 2006-08-07 11:58 发表评论
]]>
整理了一些t-sql技?转自csdn)http://www.tkk7.com/nbtymm/archive/2006/08/07/62137.htmlnbtnbtMon, 07 Aug 2006 03:51:00 GMThttp://www.tkk7.com/nbtymm/archive/2006/08/07/62137.htmlhttp://www.tkk7.com/nbtymm/comments/62137.htmlhttp://www.tkk7.com/nbtymm/archive/2006/08/07/62137.html#Feedback0http://www.tkk7.com/nbtymm/comments/commentRss/62137.htmlhttp://www.tkk7.com/nbtymm/services/trackbacks/62137.html阅读全文

nbt 2006-08-07 11:51 发表评论
]]>
数据库设计方法、规范与技??http://www.tkk7.com/nbtymm/archive/2006/08/07/62136.htmlnbtnbtMon, 07 Aug 2006 03:46:00 GMThttp://www.tkk7.com/nbtymm/archive/2006/08/07/62136.htmlhttp://www.tkk7.com/nbtymm/comments/62136.htmlhttp://www.tkk7.com/nbtymm/archive/2006/08/07/62136.html#Feedback0http://www.tkk7.com/nbtymm/comments/commentRss/62136.htmlhttp://www.tkk7.com/nbtymm/services/trackbacks/62136.html一、数据库设计q程
  数据库技术是信息资源理最有效的手Dc数据库设计是指对于一个给定的应用环境Q构造最优的数据库模式,建立数据库及其应用系l,有效存储数据Q满用户信息要求和处理要求?br />  数据库设计中需求分析阶D늻合各个用L(fng)应用需求(现实世界的需求)Q在概念设计阶段形成独立于机器特炏V独立于各个DBMS产品的概忉|式(信息世界模型Q,用E-R图来描述。在逻辑设计阶段E-R图{换成具体的数据库产品支持的数据模型如关系模型QŞ成数据库逻辑模式。然后根据用户处理的要求Q安全性的考虑Q在基本表的基础上再建立必要的视图(VIEWQŞ成数据的外模式。在物理设计阶段Ҏ(gu)DBMS特点和处理的需要,q行物理存储安排Q设计烦引,形成数据库内模式?br />  1. 需求分析阶D?
  需求收集和分析Q结果得到数据字典描q的数据需求(和数据流图描q的处理需求)?
  需求分析的重点是调查、收集与分析用户在数据管理中的信息要求、处理要求、安全性与完整性要求?br />  需求分析的Ҏ(gu)Q调查组l机构情c调查各部门的业务活动情c协助用h对新系l的各种要求、确定新pȝ的边界?
  常用的调查方法有Q?跟班作业、开调查会、请专h介绍、询问、设计调查表L(fng)户填写、查阅记录?br />  分析和表辄户需求的Ҏ(gu)主要包括自顶向下和自底向上两cL法。自向下的l构化分析方法(Structured AnalysisQ简USAҎ(gu)Q从最上层的系l组l机构入手,采用逐层分解的方式分析系l,q把每一层用数据图和数据字典描q?br />  数据图表达了数据和处理q程的关pR系l中的数据则借助数据字典QData DictionaryQ简UDDQ来描述?br />  数据字典是各cL据描q的集合Q它是关于数据库中数据的描述Q即元数据,而不是数据本w。数据字兔R常包括数据V数据结构、数据流、数据存储和处理q程五个部分(臛_应该包含每个字段的数据类型和在每个表内的d??br />  数据Ҏ(gu)qͼ?jng)数据项名,数据含义说明,别名Q数据类型,长度Q?
         取D_取值含义,与其他数据项的逻辑关系?
  数据l构描述Q{(jng)数据l构名,含义说明Q组??jng)数据项或数据结构}?
  数据描qͼ?jng)数据流名,说明Q数据流来源Q数据流dQ?
         l成:?jng)数据结构}Q^均流量,高峰期流量}
  数据存储描述Q{(jng)数据存储名,说明Q编P入的数据流Q流出的数据,   
          l成:?jng)数据结构}Q数据量Q存取方式}
  处理q程描述Q{(jng)处理q程名,说明Q输??jng)数据流},输??jng)数据流?
          处理:?jng)简要说明}?
  2. 概念l构设计阶段
  通过对用户需求进行综合、归U与抽象QŞ成一个独立于具体DBMS的概忉|型,可以用E-R图表C?
  概念模型用于信息世界的徏模。概忉|型不依赖于某一个DBMS支持的数据模型。概忉|型可以{换ؓ计算Z某一DBMS支持的特定数据模型?
  概念模型特点Q?br />  (1) h较强的语义表达能力,能够方便、直接地表达应用中的各种语义知识?
  (2) 应该单、清晰、易于用L(fng)解,是用户与数据库设计h员之间进行交的语言?br />  概念模型设计的一U常用方法ؓIDEF1XҎ(gu)Q它?yu)是把实?联系Ҏ(gu)应用到语义数据模型中的一U语义模型化技术,用于建立pȝ信息模型?br />  使用IDEF1XҎ(gu)创徏E-R模型的步骤如下所C?
  2.1 W零步——初始化工程
  q个阶段的Q务是从目的描q和范围描述开始,定建模目标Q开发徏模计划,l织建模队伍Q收集源材料Q制定约束和规范。收集源材料是这阶段的重炏V通过调查和观察结果,业务程Q原有系l的输入输出Q各U报表,攉原始数据QŞ成了基本数据资料表?br />  2.2 W一步——定义实?br />  实体集成员都有一个共同的特征和属性集Q可以从攉的源材料——基本数据资料表中直接或间接标识出大部分实体。根据源材料名字表中表示物的术语以及h“代码”结术语Q如客户代码、代理商代码、品代码等其名词部分代表的实体标识出来,从而初步找出潜在的实体QŞ成初步实体表?br />  2.3 W二步——定义联p?br />  IDEF1X模型中只允许二元联系Qn元联pdd义ؓn个二元联pR根据实际的业务需求和规则Q用实体联pȝ阉|标识实体间的二元关系Q然后根据实际情늡定出q接关系的势、关pd和说明,定关系cdQ是标识关系、非标识关系Q强制的或可选的Q还是非定关系、分cdpR如果子实体的每个实例都需要通过和父实体的关pL标识Q则为标识关p,否则为非标识关系。非标识关系中,如果每个子实体的实例都与而且只与一个父实体兌Q则为强制的Q否则ؓ非强制的。如果父实体与子实体代表的是同一现实对象Q那么它们ؓ分类关系?br />  2.4 W三步——定义码
  通过引入交叉实体除去上一阶段产生的非定关系Q然后从非交叉实体和独立实体开始标识侯选码属性,以便唯一识别每个实体的实例,再从侯选码中确定主码。ؓ了确定主码和关系的有效性,通过非空规则和非多D则来保证Q即一个实体实例的一个属性不能是I|也不能在同一个时L一个以上的倹{找认的定关系Q将实体q一步分解,最后构造出IDEF1X模型的键图(KB图)?br />  2.5 W四步——定义属?br />  从源数据表中抽取说明性的名词开发出属性表Q确定属性的所有者。定义非ȝ属性,查属性的非空及非多D则。此外,q要查完全依赖函数规则和非传递依赖规则,保证一个非ȝ属性必M赖于ȝ、整个主码、仅仅是ȝ。以此得C臛_W合关系理论W三范式的改q的IDEF1X模型的全属性视图?br />  2.6 W五步——定义其他对象和规则
  定义属性的数据cd、长度、精度、非I、缺省倹{约束规则等。定义触发器、存储过E、视图、角艌Ӏ同义词、序列等对象信息?br />  3. 逻辑l构设计阶段
  概늻构{换ؓ某个DBMS所支持的数据模型(例如关系模型Q,q对其进行优化。设计逻辑l构应该选择最适于描述与表辄应概늻构的数据模型Q然后选择最合适的DBMS?br />  E-R图{换ؓ关系模型实际上就是要实体、实体的属性和实体之间的联p{化ؓ关系模式,q种转换一般遵循如下原则:
  1Q一个实体型转换Z个关pL式。实体的属性就是关pȝ属性。实体的码就是关pȝ码?
  2Q一个m:n联系转换Z个关pL式。与该联pȝq的各实体的码以及联pLw的属性均转换为关pȝ属性。而关pȝ码ؓ各实体码的组合?
  3Q一?:n联系可以转换Z个独立的关系模式Q也可以与n端对应的关系模式合ƈ。如果{换ؓ一个独立的关系模式Q则与该联系相连的各实体的码以及联系本n的属性均转换为关pȝ属性,而关pȝ码ؓn端实体的码?
  4Q一?:1联系可以转换Z个独立的关系模式Q也可以与Q意一端对应的关系模式合ƈ?br />  5Q三个或三个以上实体间的一个多元联p{换ؓ一个关pL式。与该多元联pȝq的各实体的码以及联pLw的属性均转换为关pȝ属性。而关pȝ码ؓ各实体码的组合?
  6Q同一实体集的实体间的联系Q即自联p,也可按上q?:1?:n和m:n三种情况分别处理?
  7Q具有相同码的关pL式可合ƈ?
  Zq一步提高数据库应用pȝ的性能Q通常以规范化理论为指|q应该适当C攏V调整数据模型的l构Q这是数据模型的优化。确定数据依赖。消除冗余的联系。确定各关系模式分别属于W几范式。确定是否要对它们进行合q或分解。一般来说将关系分解?NF的标准,卻I
  表内的每一个值都只能被表达一ơ?br />  表内的每一行都应该被唯一的标识(有唯一键)?br />  表内不应该存储依赖于其他键的非键信息?
  4. 数据库物理设计阶D?
  为逻辑数据模型选取一个最适合应用环境的物理结构(包括存储l构和存取方法)。根据DBMS特点和处理的需要,q行物理存储安排Q设计烦引,形成数据库内模式?br />  5. 数据库实施阶D?
  q用DBMS提供的数据语aQ例如SQLQ及其宿主语aQ例如CQ,Ҏ(gu)逻辑设计和物理设计的l果建立数据库,~制与调试应用程序,l织数据入库Qƈq行试运行?数据库实施主要包括以下工作:用DDL定义数据库结构、组l数据入?、编制与调试应用E序、数据库试运?
  6. 数据库运行和l护阶段
  数据库应用系l经q试q行后即可投入正式运行。在数据库系l运行过E中必须不断地对其进行评仗调整与修改。包括:数据库的转储和恢复、数据库的安全性、完整性控制、数据库性能的监督、分析和改进、数据库的重l织和重构造?br />
  建模工具的?br />  为加快数据库设计速度Q目前有很多数据库辅助工PCASE工具Q,如Rational公司的Rational RoseQCA公司的Erwin和BpwinQSybase公司的PowerDesigner以及Oracle公司的Oracle Designer{?br />  ERwin主要用来建立数据库的概念模型和物理模型。它能用囑Ş化的方式Q描q出实体、联pd实体的属性。ERwin支持IDEF1XҎ(gu)。通过使用ERwin建模工具自动生成、更改和分析IDEF1X模型Q不仅能得到优秀的业务功能和数据需求模型,而且可以实现从IDEF1X模型到数据库物理设计的{变。ERwin工具l制的模型对应于逻辑模型和物理模型两U。在逻辑模型中,IDEF1X工具可以方便地用图形化的方式构建和l制实体联系及实体的属性。在物理模型中,ERwin可以定义对应的表、列Qƈ可针对各U数据库理pȝ自动转换为适当的类型?br />  设计人员可根据需要选用相应的数据库设计建模工具。例如需求分析完成之后,设计人员可以使用Erwin画ER图,ER图{换ؓ关系数据模型Q生成数据库l构Q画数据图Q生成应用程序?br />  二、数据库设计技?br />  1. 设计数据库之前(需求分析阶D)
  1) 理解客户需求,询问用户如何看待未来需求变化。让客户解释光求,而且随着开发的l箋Q还要经常询问客户保证其需求仍然在开发的目的之中?br />  2) 了解企业业务可以在以后的开发阶D节U大量的旉?br />  3) 重视输入输出?br />  在定义数据库表和字段需求(输入Q时Q首先应查现有的或者已l设计出的报表、查询和视图Q输出)以决定ؓ了支持这些输出哪些是必要的表和字Dc?br />  举例Q假如客户需要一个报表按照邮政编码排序、分D和求和Q你要保证其中包括了单独的邮政编码字D而不要把邮政~码p进地址字段里?br />  4) 创徏数据字典和ER 图表
  ER 图表和数据字典可以让M了解数据库的人都明确如何从数据库中获得数据。ER囑֯表明表之间关pd有用Q而数据字典则说明了每个字D늚用途以及Q何可能存在的别名。对SQL 表达式的文化来说这是完全必要的?br />  5) 定义标准的对象命名规?br />  数据库各U对象的命名必须规范?br />  2. 表和字段的设计(数据库逻辑设计Q?br />  表设计原?br />  1) 标准化和规范?br />  数据的标准化有助于消除数据库中的数据冗余。标准化有好几种形式Q但Third Normal FormQ?NFQ通常被认为在性能、扩展性和数据完整性方面达C最好^衡。简单来_遵守3NF 标准的数据库的表设计原则是:“One Fact in One Place”即某个表只包括其本w基本的属性,当不是它们本w所h的属性时需q行分解。表之间的关p通过外键相连接。它h以下特点Q有一l表专门存放通过键连接v来的兌数据?br />  举例Q某个存攑֮户及其有兛_单的3NF 数据库就可能有两个表QCustomer 和Order。Order 表不包含定单兌客户的Q何信息,但表?br />
  会存放一个键|该键指向Customer 表里包含该客户信息的那一行?br />  事实上,Z效率的缘故,对表不进行标准化有时也是必要的?br />  2) 数据驱动
  采用数据驱动而非编码的方式Q许多策略变更和l护都会方便得多Q大大增强系l的灉|性和扩展性?br />  举例Q假如用L(fng)面要讉K外部数据源(文g、XML 文、其他数据库{)Q不妨把相应的连接和路径信息存储在用L(fng)面支持表里。还有,如果用户界面执行工作之cȝdQ发送邮件、打CW、修改记录状态等Q,那么产生工作的数据也可以存攑֜数据库里。角色权限管理也可以通过数据驱动来完成。事实上Q如果过E是数据驱动的,你就可以把相当大的责Ll用Pqhl护自己的工作流q程?br />  3) 考虑各种变化
  在设计数据库的时候考虑到哪些数据字D将来可能会发生变更?br />  举例Q姓氏就是如此(注意是西方h的姓氏,比如x结婚后从夫姓等Q。所以,在徏立系l存储客户信息时Q在单独的一个数据表里存储姓氏字D,而且q附加v始日和终止日{字D,q样可以跟t这一数据条目的变化?br />
  字段设计原则
  4) 每个表中都应该添加的3 个有用的字段
  ?dRecordCreationDateQ在VB 下默认是Now()Q而在SQL Server 下默认ؓGETDATE()
  ?sRecordCreatorQ在SQL Server 下默认ؓNOT NULL DEFAULT USER
  ?nRecordVersionQ记录的版本标记Q有助于准确说明记录中出现null 数据或者丢失数据的原因
  5) 对地址和电(sh)话采用多个字D?br />  描述街道地址q短一行记录是不够的。Address_Line1、Address_Line2 和Address_Line3 可以提供更大的灵zL。还有,?sh)话L(fng)和邮件地址最好拥有自q数据表,光h自n的类型和标记cd?br />  6) 使用角色实体定义属于某类别的?br />  在需要对属于特定cd或者具有特定角色的事物做定义时Q可以用角色实体来创建特定的旉兌关系Q从而可以实现自我文化?br />  举例Q用PERSON 实体和PERSON_TYPE 实体来描qCh员。比方说Q当John Smith, Engineer 提升为John Smith, Director 乃至最后爬到John Smith, CIO 的高位,而所有你要做的不q是改变两个表PERSON 和PERSON_TYPE 之间关系的键|同时增加一个日?旉字段来知道变化是何时发生的。这P你的PERSON_TYPE 表就包含了所有PERSON 的可能类型,比如Associate、Engineer、Director、CIO 或者CEO {。还有个替代办法是改变PERSON 记录来反映新头衔的变化,不过q样一来在旉上无法跟t个人所处位|的具体旉?br />  7) 选择数字cd和文本类型尽量充?br />  在SQL 中用smallint 和tinyint cd要特别小心。比如,假如想看看月销售总额Q总额字段cd是smallintQ那么,如果总额过?32,767 ׃能进行计操作了?br />  而ID cd的文本字D,比如客户ID 或定单号{等都应该设|得比一般想象更大。假讑֮户ID ?0 位数ѝ那你应该把数据库表字段的长度设?2 或?3 个字W长。但q额外占据的I间却无需来重构整个数据库就可以实现数据库规模的增长了?br />  8) 增加删除标记字段
  在表中包含一个“删除标记”字D,q样可以把行标Cؓ删除。在关系数据库里不要单独删除某一行;最好采用清除数据程序而且要仔l维护烦引整体性?
  3. 选择键和索引Q数据库逻辑设计Q?br />  键选择原则Q?br />  1) 键设? 原则
  ?为关联字D创建外键?br />  ?所有的键都必须唯一?br />  ?避免使用复合键?br />  ?外键L兌唯一的键字段?br />  2) 使用pȝ生成的主?br />  设计数据库的时候采用系l生成的键作Z键,那么实际控制了数据库的烦引完整性。这P数据库和非h工机制就有效地控制了对存储数据中每一行的讉K。采用系l生成键作ؓ主键q有一个优点:当拥有一致的键结构时Q找到逻辑~陷很容易?br />  3) 不要用用L(fng)?不让主键h可更新?
  在确定采用什么字D作的键的时候,可一定要心用户要~辑的字Dc通常的情况下不要选择用户可编辑的字段作ؓ键?br />  4) 可选键有时可做主键
  把可选键q一步用做主键,可以拥有建立强大索引的能力?br />
  索引使用原则Q?br />  索引是从数据库中获取数据的最高效方式之一?5%的数据库性能问题都可以采用烦引技术得到解冟?br />  1) 逻辑主键使用唯一的成l烦引,对系l键Q作为存储过E)采用唯一的非成组索引Q对M外键列采用非成组索引。考虑数据库的I间有多大,表如何进行访问,q有q些讉K是否主要用作d?br />  2) 大多数数据库都烦引自动创建的主键字段Q但是可别忘了烦引外键,它们也是l常使用的键Q比如运行查询显CZ表和所有关联表的某条记录就用得上?br />  3) 不要索引memo/note 字段Q不要烦引大型字D(有很多字W)Q这样作会让索引占用太多的存储空间?br />  4) 不要索引常用的小型表
  不要为小型数据表讄M键,假如它们l常有插入和删除操作更别这样作了。对q些插入和删除操作的索引l护可能比扫描表I间消耗更多的旉?br />
  4. 数据完整性设计(数据库逻辑设计Q?br />  1) 完整性实现机Ӟ
  实体完整性:主键
  参照完整性:
  父表中删除数据:U联删除Q受限删除;|空?br />  父表中插入数据:受限插入Q递归插入
  父表中更新数据:U联更新Q受限更斎ͼ|空?br />  DBMS对参照完整性可以有两种Ҏ(gu)实现Q外键实现机ӞU束规则Q和触发器实现机?br />  用户定义完整性:
  NOT NULLQCHECKQ触发器
  2) 用约束而非商务规则强制数据完整?br />  采用数据库系l实现数据的完整性。这不但包括通过标准化实现的完整性而且q包括数据的功能性。在写数据的时候还可以增加触发器来保证数据的正性。不要依赖于商务层保证数据完整性;它不能保证表之间Q外键)的完整性所以不能强加于其他完整性规则之上?br />  3) 强制指示完整?br />  在有x据进入数据库之前其剔除。激zL据库pȝ的指C完整性特性。这样可以保持数据的清洁而能q开发h员投入更多的旉处理错误条g?br />  4) 使用查找控制数据完整?br />  控制数据完整性的最x式就是限制用L(fng)选择。只要有可能都应该提供给用户一个清晰的价值列表供光择。这样将减少键入代码的错误和误解同时提供数据的一致性。某些公共数据特别适合查找Q国家代码、状态代码等?br />  5) 采用视图
  Z在数据库和应用程序代码之间提供另一层抽象,可以为应用程序徏立专门的视图而不必非要应用程序直接访问数据表。这样做q等于在处理数据库变更时l你提供了更多的自由?br />  5. 其他设计技?br />  1) 避免使用触发?br />  触发器的功能通常可以用其他方式实现。在调试E序时触发器可能成ؓq扰。假如你实需要采用触发器Q你最好集中对它文化?br />  2) 使用常用pQ或者其他Q何语aQ而不要用编?br />  在创Z拉菜单、列表、报表时最好按照英语名排序。假如需要编码,可以在编码旁附上用户知道的英语?br />  3) 保存常用信息
  让一个表专门存放一般数据库信息非常有用。在q个表里存放数据库当前版本、最q检?修复Q对AccessQ、关联设计文的名称、客L(fng)信息。这样可以实CU简单机制跟t数据库Q当客户抱怨他们的数据库没有达到希望的要求而与你联pLQ这样做寚w客户?服务器环境特别有用?br />  4) 包含版本机制
  在数据库中引入版本控制机制来定使用中的数据库的版本。时间一长,用户的需求L会改变的。最l可能会要求修改数据库结构。把版本信息直接存放到数据库中更为方ѝ?
  5) ~制文
  Ҏ(gu)有的快捷方式、命名规范、限制和函数都要~制文?br />  采用l表、列、触发器{加注释的数据库工具。对开发、支持和跟踪修改非常有用?br />  Ҏ(gu)据库文化,或者在数据库自w的内部或者单独徏立文。这P当过了一q多旉后再回过头来做第2 个版本,犯错的机会将大大减少?br />  6) 试、测试、反复测?br />  建立或者修订数据库之后Q必ȝ用户新输入的数据试数据字段。最重要的是Q让用户q行试q且同用户一道保证选择的数据类型满_业要求。测试需要在把新数据库投入实际服务之前完成?br />  7) 查设?br />  在开发期间检查数据库设计的常用技术是通过其所支持的应用程序原型检查数据库。换句话_针对每一U最l表达数据的原型应用Q保证你查了数据模型q且查看如何取出数据?br />  三、数据库命名规范
  1. 实体Q表Q的命名
  1) 表以名词或名词短语命名,定表名是采用复数还是单数Ş式,此外l表的别名定义简单规则(比方_如果表名是一个单词,别名取单词的前4 个字母;如果表名是两个单词,各取两个单词的前两个字母组? 个字母长的别名;如果表的名字? 个单词组成,从头两个单词中各取一个然后从最后一个单词中再取Z个字母,l果q是l成4 字母长的别名Q其余依ơ类推)
  对工作用表来_表名可以加上前缀WORK_ 后面附上采用该表的应用程序的名字。在命名q程当中Q根据语义拼凑羃写即可。注意,׃ORCLE会将字段名称l一成大写或者小写中的一U,所以要求加上下划线?br />  举例Q?br />  定义的羃?Sales: Sal 销售;
  Order: Ord 订单Q?br />  Detail: Dtl 明细Q?br />  则销售订单明l表命名为:Sal_Ord_Dtl;
  2) 如果表或者是字段的名UC有一个单词,那么不用羃写,而是用完整的单词?br />  举例Q?br />  定义的羃?Material Ma 物品Q?br />  物品表名为:Material, 而不?Ma.
  但是字段物品~码则是QMa_ID;而不是Material_ID
  3) 所有的存储值列表的表前面加上前~Z
  目的是将q些值列表类排序在数据库最后?br />  4) 所有的冗余cȝ命名(主要是篏计表)前面加上前缀X
  冗余cLZ提高数据库效率,非规范化数据库的时候加入的字段或者表
  5) 兌c通过用下划线q接两个基本cM后,再加前缀R的方式命?后面按照字母序|列两个表名或者表名的~写?br />  兌表用于保存多对多关系?br />  如果被关联的表名大于10个字母,必须原来的表名的进行羃写。如果没有其他原因,都用羃写?br />  举例Q表Object与自w存在多对多的关p?则保存多对多关系的表命名为:R_ObjectQ?br />  ?Depart和Employee;存在多对多的关系Q则兌表命名ؓR_Dept_Emp
  2. 属性(列)的命?br />  1) 采用有意义的列名Q表内的列要针对键采用一整套设计规则。每一个表都将有一个自动ID作ؓd,逻辑上的d作ؓW一l候选主健来定义,如果是数据库自动生成的编码,l一命名为:ID;如果是自定义的逻辑上的~码则用~写加“ID”的Ҏ(gu)命名。如果键是数字类型,你可以用_NO 作ؓ后缀Q如果是字符cd则可以采用_CODE 后缀。对列名应该采用标准的前~和后~?br />  举例Q销售订单的~号字段命名QSal_Ord_IDQ如果还存在一个数据库生成的自动编P则命名ؓQID?br />  2) 所有的属性加上有关类型的后缀Q注意,如果q需要其它的后缀Q都攑֜cd后缀之前?br />  ? 数据cd是文本的字段Q类型后~TX可以不写。有些类型比较明昄字段Q可以不写类型后~?br />  3) 采用前缀命名
  l每个表的列名都采用l一的前~Q那么在~写SQL表达式的时候会得到大大的简化。这样做也确实有~点Q比如破坏了自动表连接工L(fng)作用Q后者把公共列名同某些数据库联系h?br />  3. 视图的命?br />  1) 视图以V作ؓ前缀Q其他命名规则和表的命名cMQ?br />  2) 命名应尽量体现各视图的功能?br />  4. 触发器的命名
  触发器以TR作ؓ前缀Q触发器名ؓ相应的表名加上后~QInsert触发器加"_I"QDelete触发器加"_D"QUpdate触发器加"_U"Q如Q?br />
  TR_Customer_IQTR_Customer_DQTR_Customer_U?br />  5. 存储q程?br />  存储q程应以"UP_"开_和系l的存储q程区分Q后l部分主要以动宾形式构成Qƈ用下划线分割各个l成部分。如增加代理商的帐户的存储过Eؓ"UP_Ins_Agent_Account"?br />  6. 变量?br />  变量名采用小写,若属于词lŞ式,用下划线分隔每个单词Q如@my_err_no?br />  7. 命名中其他注意事?br />  1) 以上命名都不得超q?0个字W的pȝ限制。变量名的长度限制ؓ29Q不包括标识字符@Q?br />  2) 数据对象、变量的命名都采用英文字W,止使用中文命名。绝对不要在对象名的字符之间留空根{?br />  3) 心保留词,要保证你的字D名没有和保留词、数据库pȝ或者常用访问方法冲H?br />  5) 保持字段名和cd的一致性,在命名字Dƈ为其指定数据cd的时候一定要保证一致性。假如数据类型在一个表里是整数Q那在另一个表里可别变成字符型了?/font>


nbt 2006-08-07 11:46 发表评论
]]>
PowerDesigner设计数据库经?/title><link>http://www.tkk7.com/nbtymm/archive/2006/08/07/62133.html</link><dc:creator>nbt</dc:creator><author>nbt</author><pubDate>Mon, 07 Aug 2006 03:42:00 GMT</pubDate><guid>http://www.tkk7.com/nbtymm/archive/2006/08/07/62133.html</guid><wfw:comment>http://www.tkk7.com/nbtymm/comments/62133.html</wfw:comment><comments>http://www.tkk7.com/nbtymm/archive/2006/08/07/62133.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/nbtymm/comments/commentRss/62133.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/nbtymm/services/trackbacks/62133.html</trackback:ping><description><![CDATA[     摘要: (转蝲?-http://www.cnblogs.com/qiubole/articles/116152.html) 采用 PowerDesigner 设计数据? ...  <a href='http://www.tkk7.com/nbtymm/archive/2006/08/07/62133.html'>阅读全文</a><img src ="http://www.tkk7.com/nbtymm/aggbug/62133.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/nbtymm/" target="_blank">nbt</a> 2006-08-07 11:42 <a href="http://www.tkk7.com/nbtymm/archive/2006/08/07/62133.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据库设计经?http://www.tkk7.com/nbtymm/archive/2006/08/07/62128.htmlnbtnbtMon, 07 Aug 2006 03:14:00 GMThttp://www.tkk7.com/nbtymm/archive/2006/08/07/62128.htmlhttp://www.tkk7.com/nbtymm/comments/62128.htmlhttp://www.tkk7.com/nbtymm/archive/2006/08/07/62128.html#Feedback0http://www.tkk7.com/nbtymm/comments/commentRss/62128.htmlhttp://www.tkk7.com/nbtymm/services/trackbacks/62128.html(转自--http://www.cnblogs.com/qiubole/articles/157312.html)
一个成功的理pȝQ是由:[50% 的业?+ 50% 的Y件] 所l成Q?50% 的成功Y件又?[25% 的数据库 + 25% 的程序] 所l成Q数据库设计的好坏是一个关键。如果把企业的数据比做生命所必需的血Ԍ那么数据库的设计是应用中最重要的一部分。有x据库设计的材料汗牛充栋,大学学位评里也有专门的讲述。不q,如我们反复的那P再好的老师也比不过l验的教诌Ӏ所以我归纳历年来所走的弯\及体会,q在|上找了些对数据库设计颇有造诣的专业h士给大家传授一些设计数据库的技巧和l验。精选了其中?60 个最x巧,q把q些技巧编写成了本文,Z方便索引其内容划分ؓ 5 个部分:

W?1 部分 - 设计数据库之?br />q一部分|列?12 个基本技巧,包括命名规范和明业务需求等?
W?2 部分 - 设计数据库表
d 24 个指南性技巧,늛表内字段设计以及应该避免的常见问题等?
W?3 部分 - 选择?br />怎么选择键呢Q这里有 10 个技巧专门涉及系l生成的主键的正用法,q有?时以及如何烦引字D以获得最x能{?
W?4 部分 - 保证数据完整?br />讨论如何保持数据库的清晰和健壮,如何把有x据降低到最程度?
W?5 部分 - 各种技?br />不包括在以上 4 个部分中的其他技巧,五花八门Q有了它们希望你的数据库开发工作会更轻松一些?
W?1 部分 - 设计数据库之?br />考察现有环境
在设计一个新数据库时Q你不但应该仔细研究业务需求而且q要考察现有的系l。大多数数据库项目都不是从头开始徏立的Q通常Q机构内M存在用来满特定需求的现有pȝQ可能没有实现自动计)。显Ӟ现有pȝq不完美Q否则你׃必再建立新系l了。但是对旧系l的研究可以让你发现一些可能会忽略的细微问题。一般来_考察现有pȝ对你l对有好处?
定义标准的对象命名规?br />一定要定义数据库对象的命名规范。对数据库表来说Q从目一开始就要确定表名是采用复数q是单数形式。此外还要给表的别名定义单规则(比方_如果表名是一个单词,别名取单词的前 4 个字母;如果表名是两个单词,各取两个单词的前两个字母组?4 个字母长的别名;如果表的名字?3 个单词组成,你不妨从头两个单词中各取一个然后从最后一个单词中再取Z个字母,l果q是l成 4 字母长的别名Q其余依ơ类推)对工作用表来_表名可以加上前缀 WORK_ 后面附上采用该表的应用程序的名字。表内的列[字段]要针寚w采用一整套设计规则。比如,如果键是数字cdQ你可以?_N 作ؓ后缀Q如果是字符cd则可以采?_C 后缀。对列[字段]名应该采用标准的前缀和后~。再如,假如你的表里有好多“money”字D,你不妨给每个列[字段]增加一?_M 后缀。还有,日期列[字段]最好以 D_ 作ؓ名字打头?/p>

查表名、报表名和查询名之间的命名规范。你可能会很快就被这些不同的数据库要素的名称搞糊涂了。假如你坚持l一地命名这些数据库的不同组成部分,臛_你应该在q些对象名字的开头用 Table、Query 或?Report {前~加以区别?/p>

如果采用?Microsoft AccessQ你可以?qry、rpt、tbl ?mod {符h标识对象Q比?tbl_EmployeesQ。我在和 SQL Server 打交道的时候还用过 tbl 来烦引表Q但我用 sp_company Q现在用 sp_feft_Q标识存储过E,因ؓ在有的时候如果我发现了更好的处理办法往往会保存好几个拯。我在实?SQL Server 2000 时用 udf_ Q或者类似的标记Q标识我~写的函数?
工欲善其? 必先利其?br />采用理想的数据库设计工具Q比如:SyBase 公司?PowerDesignQ她支持 PB、VB、Delphe {语aQ通过 ODBC 可以q接市面上流行的 30 多个数据库,包括 dBase、FoxPro、VFP、SQL Server {,今后有机会我着重介l?PowerDesign 的用?
获取数据模式资源手册
正在LCZ模式的h可以阅读《数据模式资源手册》一书,该书?Len Silverston、W. H. Inmon ?Kent Graziano ~写Q是一本值得拥有的最x据徏模图书。该书包括的章节늛多种数据领域Q比如h员、机构和工作效能{。其他的你还可以参考:[1]萨师煊 王珊著 数据库系l概?W二?高等教育出版C?1991、[2][] Steven M.Bobrowski ?Oracle 7 与客P服务器计技术从入门到精通 刘徏元等译 ?sh)子工业出版C,1996、[3]周中元 信息pȝ建模Ҏ(gu)(? ?sh)子与信息化 1999q第3期,1999
畅想未来Q但不可忘了q去的教?br />我发现询问用户如何看待未来需求变化非常有用。这样做可以辑ֈ两个目的Q首先,你可以清楚地了解应用设计在哪个地方应该更L(fng)zL以及如何避免性能瓉Q其ơ,你知道发生事先没有确定的需求变更时用户和你一h到吃惊?/p>

一定要Cq去的经验教训!我们开发h员还应该通过分n自己的体会和l验互相帮助。即使用戯Z们再也不需要什么支持了Q我们也应该对他们进行这斚w的教Ԍ我们都曾l面临过q样的时删Z当初要是这么做了该多好..”?
在物理实践之前进行逻辑设计
在深入物理设计之前要先进行逻辑设计。随着大量?CASE 工具不断涌现出来Q你的设计也可以辑ֈ相当高的逻辑水准Q你通常可以从整体上更好C解数据库设计所需要的Ҏ(gu)面面?
了解你的业务
在你癑ֈ癑֜定pȝ从客戯度满_需求之前不要在你的 ERQ实体关p)模式中加入哪怕一个数据表Q怎么Q你q没有模式?那请你参看技?9Q。了解你的企业业务可以在以后的开发阶D节U大量的旉。一旦你明确了业务需求,你就可以自己做出许多决策了?/p>

一旦你认ؓ你已l明了业务内容Q你最好同客户q行一ơ系l的交流。采用客L(fng)术语q且向他们解释你所惛_的和你所听到的。同时还应该用可能、将会和必须{词汇表辑ևpȝ的关pd数。这样你可以让你的客户U正你自q理解然后做好下一步的 ER 设计?
创徏数据字典?ER 图表
一定要q旉创徏 ER 图表和数据字典。其中至应该包含每个字D늚数据cd和在每个表内的主外键。创?ER 图表和数据字典确实有点费时但对其他开发h员要了解整个设计却是完全必要的。越早创能有助于避免今后面(f)的可能؜乱,从而可以让M了解数据库的人都明确如何从数据库中获得数据?/p>

有一份诸?ER 图表{最新文其重要性如何强调都不过分,q对表明表之间关pd有用Q而数据字典则说明了每个字D늚用途以及Q何可能存在的别名。对 SQL 表达式的文化来说这是完全必要的?
创徏模式
一张图表胜q千a万语Q开发h员不仅要阅读和实现它Q而且q要用它来帮助自己和用户对话。模式有助于提高协作效能Q这样在先期的数据库设计中几乎不可能出现大的问题。模式不必弄的很复杂Q甚臛_以简单到手写在一张纸上就可以了。只是要保证其上的逻辑关系今后能生效益?
从输入输Z?br />在定义数据库表和字段需求(输入Q时Q首先应查现有的或者已l设计出的报表、查询和视图Q输出)以决定ؓ了支持这些输出哪些是必要的表和字DcD个简单的例子Q假如客户需要一个报表按照邮政编码排序、分D和求和Q你要保证其中包括了单独的邮政编码字D而不要把邮政~码p进地址字段里?
报表技?br />要了解用户通常是如何报告数据的Q批处理q是在线提交报表Q时间间隔是每天、每周、每月、每个季度还是每q_如果需要的话还可以考虑创徏ȝ表。系l生成的主键在报表中很难理。用户在hpȝ生成主键的表内用副键q行索往往会返回许多重复数据。这L(fng)索性能比较低而且Ҏ(gu)引v混ؕ?
理解客户需?br />看v来这应该是显而易见的事,但需求就是来自客Pq里要从内部和外部客L(fng)角度考虑Q。不要依赖用户写下来的需求,真正的需求在客户的脑袋里。你要让客户解释光求,而且随着开发的l箋Q还要经常询问客户保证其需求仍然在开发的目的之中。一个不变的真理是:“只有我看见了我才知道我惌的是什么”必然会D大量的返工,因ؓ数据库没有达到客户从来没有写下来的需求标准。而更p的是你对他们需求的解释只属于你自己Q而且可能是完全错误的?
W?2 部分 - 设计表和字段
查各U变?br />我在设计数据库的时候会考虑到哪些数据字D将来可能会发生变更。比方说Q姓氏就是如此(注意是西方h的姓氏,比如x结婚后从夫姓等Q。所以,在徏立系l存储客户信息时Q我們֐于在单独的一个数据表里存储姓氏字D,而且q附加v始日和终止日{字D,q样可以跟t这一数据条目的变化?
采用有意义的字段?br />有一回我参加开发过一个项目,其中有从其他E序员那里承的E序Q那个程序员喜欢用屏q上昄数据指示用语命名字段Q这也不赖,但不q的是,她还喜欢用一些奇怪的命名法,其命名采用了匈牙利命名和控制序号的组合Ş式,比如 cbo1、txt2、txt2_b {等?br />除非你在使用只面向你的羃写字D名的系l,否则请尽可能地把字段描述的清楚些。当Ӟ也别做过头了Q比?Customer_Shipping_Address_Street_Line_1Q虽然很富有说明性,但没人愿意键入这么长的名字,具体度在你的把握中?
采用前缀命名
如果多个表里有好多同一cd的字D(比如 FirstNameQ,你不妨用特定表的前缀Q比?CusLastNameQ来帮助你标识字Dc?/p>

时效性数据应包括“最q更新日?旉”字Dc时间标记对查找数据问题的原因、按日期重新处理/重蝲数据和清除旧数据特别有用?
标准化和数据驱动
数据的标准化不仅方便了自p且也方便了其他人。比方说Q假如你的用L(fng)面要讉K外部数据源(文g、XML 文、其他数据库{)Q你不妨把相应的q接和\径信息存储在用户界面支持表里。还有,如果用户界面执行工作之cȝdQ发送邮件、打CW、修改记录状态等Q,那么产生工作的数据也可以存攑֜数据库里。预先安排总需要付出努力,但如果这些过E采用数据驱动而非编码的方式Q那么策略变更和l护都会方便得多。事实上Q如果过E是数据驱动的,你就可以把相当大的责Ll用Pqhl护自己的工作流q程?
标准化不能过?br />寚w些不熟?zhn)标准化一词(normalizationQ的言Q标准化可以保证表内的字D都是最基础的要素,而这一措施有助于消除数据库中的数据冗余。标准化有好几种形式Q但 Third Normal FormQ?NFQ通常被认为在性能、扩展性和数据完整性方面达C最好^衡。简单来_3NF 规定Q?br />* 表内的每一个值都只能被表达一ơ?br />* 表内的每一行都应该被唯一的标识(有唯一键)?br />* 表内不应该存储依赖于其他键的非键信息?br />遵守 3NF 标准的数据库h以下特点Q有一l表专门存放通过键连接v来的兌数据。比方说Q某个存攑֮户及其有兛_单的 3NF 数据库就可能有两个表QCustomer ?Order。Order 表不包含定单兌客户的Q何信息,但表内会存放一个键|该键指向 Customer 表里包含该客户信息的那一行?br />更高层次的标准化也有Q但更标准是否就一定更好呢Q答案是不一定。事实上Q对某些目来说Q甚臛_q?3NF 都可能给数据库引入太高的复杂性?/p>

Z效率的缘故,对表不进行标准化有时也是必要的,q样的例子很多。曾l有个开发餐饮分析Y件的zd是用非标准化表把查询旉从^?40 U降低到了两U左叟뀂虽然我不得不这么做Q但我绝不把数据表的非标准化当作当然的设计理c而具体的操作不过是一U派生。所以如果表Z问题重新产生非标准化的表是完全可能的?
Microsoft Visual FoxPro 报表技?br />如果你正在?Microsoft Visual FoxProQ你可以用对用户友好的字D名来代替编L(fng)名称Q比如用 Customer Name 代替 txtCNaM。这P当你用向导程?[WizardsQ台湾hUCؓ‘精灵’] 创徏表单和报表时Q其名字会让那些不是E序员的人更Ҏ(gu)阅读?
不活跃或者不采用的指C符
增加一个字D表C所在记录是否在业务中不再活跃挺有用的。不是客户、员工还是其他什么hQ这样做都能有助于再q行查询的时候过滤活跃或者不z跃状态。同时还消除了新用户在采用数据时所面(f)的一些问题,比如Q某些记录可能不再ؓ他们所用,再删除的时候可以vC定的防范作用?
使用角色实体定义属于某类别的列[字段]
在需要对属于特定cd或者具有特定角色的事物做定义时Q可以用角色实体来创建特定的旉兌关系Q从而可以实现自我文化?br />q里的含义不是让 PERSON 实体带有 Title 字段Q而是_Z么不?PERSON 实体?PERSON_TYPE 实体来描qCh员呢Q比方说Q当 John Smith, Engineer 提升?John Smith, Director 乃至最后爬?John Smith, CIO 的高位,而所有你要做的不q是改变两个?PERSON ?PERSON_TYPE 之间关系的键|同时增加一个日?旉字段来知道变化是何时发生的。这P你的 PERSON_TYPE 表就包含了所?PERSON 的可能类型,比如 Associate、Engineer、Director、CIO 或?CEO {?br />q有个替代办法就是改?PERSON 记录来反映新头衔的变化,不过q样一来在旉上无法跟t个人所处位|的具体旉?
采用常用实体命名机构数据
l织数据的最单办法就是采用常用名字,比如QPERSON、ORGANIZATION、ADDRESS ?PHONE {等。当你把q些常用的一般名字组合v来或者创建特定的相应副实体时Q你得C自己用的Ҏ(gu)版本。开始的时候采用一般术语的主要原因在于所有的具体用户都能Ҏ(gu)象事物具体化?br />有了q些抽象表示Q你可以在W?2 U标识中采用自己的特D名Uͼ比如QPERSON 可能?Employee、Spouse、Patient、Client、Customer、Vendor 或?Teacher {。同L(fng)QORGANIZATION 也可能是 MyCompany、MyDepartment、Competitor、Hospital、Warehouse、Government {。最?ADDRESS 可以具体?Site、Location、Home、Work、Client、Vendor、Corporate ?FieldOffice {?br />采用一般抽象术语来标识“事物”的cd可以让你在关联数据以满业务要求斚w获得巨大的灵zL,同时q样做还可以显著降低数据存储所需的冗余量?
用户来自世界各地
在设计用到网l或者具有其他国际特性的数据库时Q一定要C大多数国安有不同的字段格式Q比如邮政编码等Q有些国Ӟ比如新西兰就没有邮政~码一说?
数据重复需要采用分立的数据?br />如果你发现自己在重复输入数据Q请创徏新表和新的关pR?
每个表中都应该添加的 3 个有用的字段
* dRecordCreationDateQ在 VB 下默认是 Now()Q而在 SQL Server 下默认ؓ GETDATE()
* sRecordCreatorQ在 SQL Server 下默认ؓ NOT NULL DEFAULT USER
* nRecordVersionQ记录的版本标记Q有助于准确说明记录中出?null 数据或者丢失数据的原因
对地址和电(sh)话采用多个字D?br />描述街道地址q短一行记录是不够的。Address_Line1、Address_Line2 ?Address_Line3 可以提供更大的灵zL。还有,?sh)话L(fng)和邮件地址最好拥有自q数据表,光h自n的类型和标记cd?/p>

q分标准化可要小心,q样做可能会D性能上出现问题。虽然地址和电(sh)话表分离通常可以辑ֈ最佳状态,但是如果需要经常访问这cM息,或许在其父表中存䏀首选”信息(比如 Customer {)更ؓ妥当些。非标准化和加速访问之间的妥协是有一定意义的?
使用多个名称字段
我觉得很吃惊Q许多h在数据库里就l?name 留一个字Dc我觉得只有刚入门的开发h员才会这么做Q但实际上网上这U做法非常普遍。我应该把姓氏和名字当作两个字段来处理,然后在查询的时候再把他们组合v来?/p>

我最常用的是在同一表中创徏一个计列[字段]Q通过它可以自动地q接标准化后的字D,q样数据变动的时候它也跟着变。不q,q样做在采用建模软g时得很机灉|行。MQ采用连接字D늚方式可以有效的隔ȝ户应用和开发h员界面?
提防大小写؜用的对象名和Ҏ(gu)字符
q去最令我恼火的事情之一是数据库里有大写L(fng)的对象名Q比?CustomerData。这一问题?Access ?Oracle 数据库都存在。我不喜Ƣ采用这U大写L(fng)的对象命名方法,l果q不得不手工修改名字。想想看Q这U数据库/应用E序能؜到采用更强大数据库的那一天吗Q采用全部大写而且包含下划W的名字h更好的可L(CUSTOMER_DATAQ,l对不要在对象名的字W之间留I格?
心保留?br />要保证你的字D名没有和保留词、数据库pȝ或者常用访问方法冲H,比如Q最q我~写的一?ODBC q接E序里有个表Q其中就用了 DESC 作ؓ说明字段名。后果可惌知QDESC ?DESCENDING ~写后的保留词。表里的一?SELECT * 语句倒是能用Q但我得到的却是一大堆毫无用处的信息?
保持字段名和cd的一致?br />在命名字Dƈ为其指定数据cd的时候一定要保证一致性。假如字D在某个表中叫做“agreement_number”,你就别在另一个表里把名字Ҏ(gu)“ref1”。假如数据类型在一个表里是整数Q那在另一个表里可别变成字符型了。记住,你干完自qzMQ其他hq要用你的数据库呢?
仔细选择数字cd
?SQL 中?smallint ?tinyint cd要特别小心,比如Q假如你想看看月销售总额Q你的总额字段cd?smallintQ那么,如果总额过?$32,767 你就不能q行计算操作了?
删除标记
在表中包含一个“删除标记”字D,q样可以把行标Cؓ删除。在关系数据库里不要单独删除某一行;最好采用清除数据程序而且要仔l维护烦引整体性?
避免使用触发?br />触发器的功能通常可以用其他方式实现。在调试E序时触发器可能成ؓq扰。假如你实需要采用触发器Q你最好集中对它文化?
包含版本机制
你在数据库中引入版本控制机制来确定用中的数据库的版本。无论如何你都要实现q一要求。时间一长,用户的需求L会改变的。最l可能会要求修改数据库结构。虽然你可以通过查新字段或者烦引来定数据库结构的版本Q但我发现把版本信息直接存放到数据库中不更ؓ方便吗??
l文本字D늕余?br />ID cd的文本字D,比如客户 ID 或定单号{等都应该设|得比一般想象更大,因ؓ旉不长你多半就会因d额外的字W而难堪不巌Ӏ比方说Q假设你的客?ID ?10 位数ѝ那你应该把数据库表字段的长度设?12 或?13 个字W长。这浪费空间吗Q是有一点,但也没你惌的那么多Q一个字D加?3 个字W在?1 百万条记录,再加上一点烦引的情况下才不过让整个数据库多占?3MB 的空间。但q额外占据的I间却无需来重构整个数据库就可以实现数据库规模的增长了。n份证的号码从 15 位变?18 位就是最好和最惨痛的例子?
列[字段]命名技?br />我们发现Q假如你l每个表的列[字段]名都采用l一的前~Q那么在~写 SQL 表达式的时候会得到大大的简化。这样做也确实有~点Q比如破坏了自动表连接工L(fng)作用Q后者把公共列[字段]名同某些数据库联pv来,不过pq些工具有时不也q接错误嘛。D个简单的例子Q假设有两个表:
Customer ?Order。Customer 表的前缀?cu_Q所以该表内的子D名如下Qcu_name_id、cu_surname、cu_initials 和cu_address {。Order 表的前缀?or_Q所以子D名是:
or_order_id、or_cust_name_id、or_quantity ?or_description {?br />q样从数据库中选出全部数据?SQL 语句可以写成如下所C:
Select * From Customer, Order Where cu_surname = "MYNAME" ;
and cu_name_id = or_cust_name_id and or_quantity = 1
在没有这些前~的情况下则写成这个样子(用别名来区分Q:
Select * From Customer, Order Where Customer.surname = "MYNAME" ;
and Customer.name_id = Order.cust_name_id and Order.quantity = 1
W?1 ?SQL 语句没少键入多少字符。但如果查询涉及?5 个表乃至更多的列[字段]你就知道q个技巧多有用了?
W?3 部分 - 选择键和索引
数据采掘要预先计?br />我所在的某一客户部门一度要处理 8 万多份联pL式,同时填写每个客户的必要数据(q绝对不是小z)。我从中q要定Zl客户作为市场目标。当我从最开始设计表和字D늚时候,我试图不在主索引里增加太多的字段以便加快数据库的q行速度。然后我意识到特定的l查询和信息采掘既不准确速度也不快。结果只好在ȝ引中重徏而且合ƈ了数据字Dc我发现有一个指C划相当关键——当我想创徏pȝcd查找时ؓ什么要采用L(fng)作ؓȝ引字D呢Q我可以用传真号码进行检索,但是它几乎就象系l类型一样对我来说ƈ不重要。采用后者作Z字段Q数据库更新后重新烦引和索就快多了?/p>

可操作数据仓库(ODSQ和数据仓库QDWQ这两种环境下的数据索引是有差别的。在 DW 环境下,你要考虑销售部门是如何l织销售活动的。他们ƈ不是数据库管理员Q但是他们确定表内的键信息。这里设计h员或者数据库工作人员应该分析数据库结构从而确定出性能和正输Z间的最x件?
使用pȝ生成的主?br />q类同技?1Q但我觉得有必要在这里重复提醒大家。假如你L在设计数据库的时候采用系l生成的键作Z键,那么你实际控制了数据库的索引完整性。这P数据库和非h工机制就有效地控制了对存储数据中每一行的讉K?br />采用pȝ生成键作Z键还有一个优点:当你拥有一致的键结构时Q找到逻辑~陷很容易?
分解字段用于索引
Z分离命名字段和包含字D以支持用户定义的报表,误虑分解其他字段Q甚至主键)为其l成要素以便用户可以对其q行索引。烦引将加快 SQL 和报表生成器脚本的执行速度。比方说Q我通常在必M?SQL LIKE 表达式的情况下创建报表,因ؓ case number 字段无法分解?year、serial number、case type ?defendant code {要素。性能也会变坏。假如年度和cd字段可以分解为烦引字D那么这些报表运行v来就会快多了?
键设?4 原则
* 为关联字D创建外键?br />* 所有的键都必须唯一?br />* 避免使用复合键?br />* 外键L兌唯一的键字段?
别忘了烦?br />索引是从数据库中获取数据的最高效方式之一?5% 的数据库性能问题都可以采用烦引技术得到解冟뀂作Z条规则,我通常寚w辑主键使用唯一的成l烦引,对系l键Q作为存储过E)采用唯一的非成组索引Q对M外键列[字段]采用非成l烦引。不q,索引p是盐Q太多了菜就怺。你得考虑数据库的I间有多大,表如何进行访问,q有q些讉K是否主要用作d?/p>

大多数数据库都烦引自动创建的主键字段Q但是可别忘了烦引外键,它们也是l常使用的键Q比如运行查询显CZ表和所有关联表的某条记录就用得上。还有,不要索引 memo/note 字段Q不要烦引大型字D(有很多字W)Q这样作会让索引占用太多的存储空间?
不要索引常用的小型表
不要为小型数据表讄M键,假如它们l常有插入和删除操作更别这样作了。对q些插入和删除操作的索引l护可能比扫描表I间消耗更多的旉?
不要把社会保障号码(SSNQ或w䆾证号码(IDQ选作?br />永远都不要?SSN ?ID 作ؓ数据库的键。除了隐U原因以外,ȝ政府来趋向于不准许把 SSN ?ID 用作除收入相关以外的其他目的QSSN ?ID 需要手工输入。永q不要用手工输入的键作Z键,因ؓ一旦你输入错误Q你唯一能做的就是删除整个记录然后从头开始?/p>

我在破解他h的程序时候,我看到很多h?SSN ?ID q曾被用做系列号Q当然尽这么做是非法的。而且Z也都知道q是非法的,但他们已l习惯了。后来,随着盗取w䆾犯罪案g的增加,我现在的同行正痛苦地从一大摊子数据中?SSN ?ID 删除?
不要用用L(fng)?br />在确定采用什么字D作的键的时候,可一定要心用户要~辑的字Dc通常的情况下不要选择用户可编辑的字段作ؓ键。这样做会迫使你采取以下两个措施Q?br />* 在创录之后对用户~辑字段的行为施加限制。假如你q么做了Q你可能会发C的应用程序在商务需求突然发生变化,而用户需要编辑那些不可编辑的字段时缺乏够的灉|性。当用户在输入数据之后直C存记录才发现pȝZ问题他们该怎么惻I删除重徏Q假如记录不可重建是否让用户走开Q?br />* 提出一些检和U正键冲H的Ҏ(gu)。通常Q费点精力也搞定了Q但是从性能上来看这样做的代价就比较大了。还有,键的U正可能会迫使你H破你的数据和商?用户界面层之间的隔离?br />所以还是重提一句老话Q你的设计要适应用户而不是让用户来适应你的设计?/p>

不让主键h可更新性的原因是在关系模式下,主键实现了不同表之间的关联。比如,Customer 表有一个主?CustomerIDQ而客L(fng)定单则存攑֜另一个表里。Order 表的主键可能?OrderNo 或?OrderNo、CustomerID 和日期的l合。不你选择哪种键设|,你都需要在 Order 表中存放 CustomerID 来保证你可以l下定单的用h到其定单记录?br />假如你在 Customer 表里修改?CustomerIDQ那么你必须扑և Order 表中的所有相兌录对其进行修攏V否则,有些定单׃不属于Q何客户——数据库的完整性就完蛋了?br />如果索引完整性规则施加到表一U,那么在不~写大量代码和附加删除记录的情况下几乎不可能改变某一条记录的键和数据库内所有关联的记录。而这一q程往往错误丛生所以应该尽量避免?
可选键(候选键)有时可做主键
CQ查询数据的不是机器而是人?br />假如你有可选键Q你可能q一步把它用做主键。那L(fng)话,你就拥有了徏立强大烦引的能力。这样可以阻止用数据库的h不得不连接数据库从而恰当的qo数据。在严格控制域表的数据库上,q种负蝲是比较醒目的。如果可选键真正有用Q那是辑ֈ了主键的水准?br />我的看法是,假如你有可选键Q比如国家表内的 state_codeQ你不要在现有不能变动的唯一键上创徏后箋的键。你要做的无非是创徏毫无价值的数据。如你因度用表的后l键[别名]建立q种表的兌Q操作负载真得需要考虑一下了?
别忘了外?br />大多数数据库索引自动创徏的主键字Dc但别忘了烦引外键字D,它们在你x询主表中的记录及其关联记录时每次都会用到。还有,不要索引 memo/notes 字段而且不要索引大型文本字段Q许多字W)Q这样做会让你的索引占据大量的数据库I间?
W?4 部分 - 保证数据的完整?br />用约束而非商务规则强制数据完整?br />如果你按照商务规则来处理需求,那么你应当检查商务层?用户界面Q如果商务规则以后发生变化,那么只需要进行更新即可。假如需求源于维护数据完整性的需要,那么在数据库层面上需要施加限制条件。如果你在数据层实采用了约束,你要保证有办法把更新不能通过U束查的原因采用用户理解的语a通知用户界面。除非你的字D命名很冗长Q否则字D名本nq不够?/p>

只要有可能,请采用数据库pȝ实现数据的完整性。这不但包括通过标准化实现的完整性而且q包括数据的功能性。在写数据的时候还可以增加触发器来保证数据的正性。不要依赖于商务层保证数据完整性;它不能保证表之间Q外键)的完整性所以不能强加于其他完整性规则之上?
分布式数据系l?br />对分布式pȝ而言Q在你决定是否在各个站点复制所有数据还是把数据保存在一个地方之前应该估计一下未?5 q或?10 q的数据量。当你把数据传送到其他站点的时候,最好在数据库字D中讄一些标记。在目的站点收到你的数据之后更新你的标记。ؓ了进行这U数据传输,请写下你自己的批处理或者调度程序以特定旉间隔q行而不要让用户在每天的工作后传输数据。本地拷贝你的维护数据,比如计算常数和利息率{,讄版本号保证数据在每个站点都完全一致?
强制指示完整?参照完整?)
没有好办法能在有x据进入数据库之后消除它,所以你应该在它q入数据库之前将其剔除。激zL据库pȝ的指C完整性特性。这样可以保持数据的清洁而能q开发h员投入更多的旉处理错误条g?
关系
如果两个实体之间存在多对一关系Q而且q有可能转化为多对多关系Q那么你最好一开始就讄成多对多关系。从现有的多对一关系转变为多对多关系比一开始就是多对多关系要难得多?
采用视图
Z在你的数据库和你的应用程序代码之间提供另一层抽象,你可以ؓ你的应用E序建立专门的视图而不必非要应用程序直接访问数据表。这样做q等于在处理数据库变更时l你提供了更多的自由?
l数据保有和恢复制定计划
考虑数据保有{略q包含在设计q程中,预先设计你的数据恢复q程。采用可以发布给用户/开发h员的数据字典实现方便的数据识别同时保证对数据源文档化。编写在U更新来“更新查询”供以后万一数据丢失可以重新处理更新?
用存储过E让pȝ做重z?br />解决了许多麻烦来产生一个具有高度完整性的数据库解x案之后,我决定封装一些关联表的功能组Q提供一整套常规的存储过E来讉K各组以便加快速度和简化客L(fng)序代码的开发。数据库不只是一个存放数据的地方Q它也是化编码之地?
使用查找
控制数据完整性的最x式就是限制用L(fng)选择。只要有可能都应该提供给用户一个清晰的价值列表供光择。这样将减少键入代码的错误和误解同时提供数据的一致性。某些公共数据特别适合查找Q国家代码、状态代码等?
W?5 部分 - 各种技?br />文、文档、文?br />Ҏ(gu)有的快捷方式、命名规范、限制和函数都要~制文?/p>

采用l表、列[字段]、触发器{加注释的数据库工具。是的,q有点费事,但从长远来看Q这样做对开发、支持和跟踪修改非常有用?/p>

取决于你使用的数据库pȝQ可能有一些Y件会l你一些供你很快上手的文档。你可能希望先开始在_然后获得来多的细节。或者你可能希望周期性的预排Q在输入新数据同旉着你的q展Ҏ(gu)一部分l节化。不你选择哪种方式Q总要对你的数据库文档化,或者在数据库自w的内部或者单独徏立文档。这P当你q了一q多旉后再回过头来做第 2 个版本,你犯错的Z大大减?
使用常用pQ或者其他Q何语aQ而不要用编?br />Z么我们经帔R用编码(比如 9935A 可能是‘青岛啤酒’的供应代码Q?XF788-Q 可能是帐目编码)Q理由很多。但是用户通常都用pq行思考而不是编码。工?5 q的会计或许知道 4XF788-Q 是什么东西,但新来的可就不一定了。在创徏下拉菜单、列表、报表时最好按照英语名排序。假如你需要编码,那你可以在编码旁附上用户知道的英语?
保存常用信息
让一个表专门存放一般数据库信息非常有用。我常在q个表里存放数据库当前版本、最q检?修复Q对 FoxProQ、关联设计文的名称、客L(fng)信息。这样可以实CU简单机制跟t数据库Q当客户抱怨他们的数据库没有达到希望的要求而与你联pLQ这样做寚w客户?服务器环境特别有用?
试、测试、反复测?br />建立或者修订数据库之后Q必ȝ用户新输入的数据试数据字段。最重要的是Q让用户q行试q且同用户一道保证你选择的数据类型满_业要求。测试需要在把新数据库投入实际服务之前完成?
查设?br />在开发期间检查数据库设计的常用技术是通过其所支持的应用程序原型检查数据库。换句话_针对每一U最l表达数据的原型应用Q保证你查了数据模型q且查看如何取出数据?
Microsoft Visual FoxPro 设计技?br />对复杂的 Microsoft Visual FoxPro 数据库应用程序而言Q可以把所有的主表攑֜一个数据库容器文g里,然后增加其他数据库表文g和装载同原有数据库有关的Ҏ(gu)文g。根据需要用q些文gq接C文g中的主表。比如数据输入、数据烦引、统计分析、向理层或者政府部门提供报表以及各cdL询等。这一措施化了用户和组权限的分配,而且有利于应用程序函敎ͼ存储q程Q的分组和划分,从而在E序必须修改的时候易于管理?




nbt 2006-08-07 11:14 发表评论
]]>
数据库设计三大范式应用实例剖?转蝲)http://www.tkk7.com/nbtymm/archive/2006/06/15/52958.htmlnbtnbtThu, 15 Jun 2006 03:40:00 GMThttp://www.tkk7.com/nbtymm/archive/2006/06/15/52958.htmlhttp://www.tkk7.com/nbtymm/comments/52958.htmlhttp://www.tkk7.com/nbtymm/archive/2006/06/15/52958.html#Feedback0http://www.tkk7.com/nbtymm/comments/commentRss/52958.htmlhttp://www.tkk7.com/nbtymm/services/trackbacks/52958.html 引言

  数据?/font>的设计范式是数据?/font>设计所需要满的规范Q满些规范的数据?/font>是简z的、结构明晰的Q同Ӟ不会发生插入QinsertQ、删除(deleteQ和更新QupdateQ操作异常。反之则是ؕ七八p,不仅l?a target="_blank">数据?/font>的编Eh员制造麻烦,而且面目可憎Q可能存储了大量不需要的冗余信息?br />
  设计范式是不是很难懂呢?非也Q大学教材上l我们一堆数学公式我们当然看不懂Q也C住。所以我们很多h根本不按照范式来设?a target="_blank">数据?/font>?br />
  实质上,设计范式用很形象、很z的话语p说清楚,道明白。本文将对范式进行通俗地说明,q以W者曾l设计的一个简单论坛的数据?/font>Z来讲解怎样这些范式应用于实际工程?br />
  范式说明

  W一范式Q?NFQ:数据?/font>表中的字D都是单一属性的Q不可再分。这个单一属性由基本cd构成Q包括整型、实数、字W型、逻辑型、日期型{?br />
  例如Q如下的数据?/font>表是W合W一范式的:

字段1 字段2 字段3 字段4
    

  而这L(fng)数据?/font>表是不符合第一范式的:

字段1 字段2
字段3
字段4
  字段3.1字段3.2  


  很显Ӟ在当前的M关系数据?/font>理pȝQDBMSQ中Q傻瓜也不可能做ZW合W一范式?a target="_blank">数据?/font>Q因些DBMS不允怽?a target="_blank">数据?/font>表的一列再分成二列或多列。因此,你想在现有的DBMS中设计出不符合第一范式?a target="_blank">数据?/font>都是不可能的?br />
  W二范式Q?NFQ:数据?/font>表中不存在非关键字段对Q一候选关键字D늚部分函数依赖Q部分函C赖指的是存在l合关键字中的某些字D决定非关键字段的情况)Q也x有非关键字段都完全依赖于L一l候选关键字。假定选课关系表ؓSelectCourse(学号, 姓名, q龄, 评名称, 成W, 学分)Q关键字为组合关键字(学号, 评名称)Q因为存在如下决定关p:

  (学号, 评名称) ?(姓名, q龄, 成W, 学分)

  q个数据?/font>表不满W二范式Q因为存在如下决定关p:

  (评名称) ?(学分)

  (学号) ?(姓名, q龄)

  卛_在组合关键字中的字段军_非关键字的情c?br />
  ׃不符?NFQ这个选课关系表会存在如下问题Q?br />
  (1) 数据冗余Q?br />
  同一门课E由n个学生选修Q?学分"重复n-1ơ;同一个学生选修了m门课E,姓名和年龄就重复了m-1ơ?br />
  (2) 更新异常Q?br />
  若调整了某门评的学分,数据表中所有行?学分"值都要更斎ͼ否则会出现同一门课E学分不同的情况?br />
  (3) 插入异常Q?br />
  假设要开设一门新的课E,暂时q没有h选修。这P׃q没?学号"关键字,评名称和学分也无法记录?a target="_blank">数据?/font>?br />
  (4) 删除异常Q?br />
  假设一批学生已l完成课E的选修Q这些选修记录应该从数据?/font>表中删除。但是,与此同时Q课E名U和学分信息也被删除了。很昄Q这也会D插入异常?

  把选课关系表SelectCourse改ؓ如下三个表:

  学生QStudent(学号, 姓名, q龄)Q?br />
  评QCourse(评名称, 学分)Q?br />
  选课关系QSelectCourse(学号, 评名称, 成W)?br />
  q样?a target="_blank">数据?/font>表是W合W二范式的,消除了数据冗余、更新异常、插入异常和删除异常?br />
  另外Q所有单关键字的数据?/font>表都W合W二范式Q因Z可能存在l合关键字?br />
  W三范式Q?NFQ:在第二范式的基础上,数据表中如果不存在非关键字段对Q一候选关键字D늚传递函C赖则W合W三范式。所谓传递函C赖,指的是如果存?A ?B ?C"的决定关p,则C传递函C赖于A。因此,满W三范式?a target="_blank">数据?/font>表应该不存在如下依赖关系Q?br />
  关键字段 ?非关键字Dx ?非关键字Dy

  假定学生关系表ؓStudent(学号, 姓名, q龄, 所在学? 学院地点, 学院?sh)?Q关键字为单一关键?学号"Q因为存在如下决定关p:

  (学号) ?(姓名, q龄, 所在学? 学院地点, 学院?sh)?

  q个数据?/font>是符?NF的,但是不符?NFQ因为存在如下决定关p:

  (学号) ?(所在学? ?(学院地点, 学院?sh)?

  卛_在非关键字段"学院地点"?学院?sh)?对关键字D?学号"的传递函C赖?br />
  它也会存在数据冗余、更新异常、插入异常和删除异常的情况,读者可自行分析得知?br />
  把学生关p表分ؓ如下两个表:

  学生Q?学号, 姓名, q龄, 所在学?Q?br />
  学院Q?学院, 地点, ?sh)??br />
  q样?a target="_blank">数据?/font>表是W合W三范式的,消除了数据冗余、更新异常、插入异常和删除异常?br />
  鲍依?U得范式QBCNFQ:在第三范式的基础上,数据?/font>表中如果不存在Q何字D对M候选关键字D늚传递函C赖则W合W三范式?br />
  假设仓库理关系表ؓStorehouseManage(仓库ID, 存储物品ID, 理员I(y)D, 数量)Q且有一个管理员只在一个仓库工作;一个仓库可以存储多U物品。这?a target="_blank">数据?/font>表中存在如下军_关系Q?br />
  (仓库ID, 存储物品ID) ?理员I(y)D, 数量)

  (理员I(y)D, 存储物品ID) ?(仓库ID, 数量)

  所以,(仓库ID, 存储物品ID)?理员I(y)D, 存储物品ID)都是StorehouseManage的候选关键字Q表中的唯一非关键字Dؓ数量Q它是符合第三范式的。但是,׃存在如下军_关系Q?br />
  (仓库ID) ?(理员I(y)D)

  (理员I(y)D) ?(仓库ID)

  卛_在关键字D决定关键字D늚情况Q所以其不符合BCNF范式。它会出现如下异常情况:

  (1) 删除异常Q?br />
  当仓库被清空后,所?存储物品ID"?数量"信息被删除的同时Q?仓库ID"?理员I(y)D"信息也被删除了?br />
  (2) 插入异常Q?br />
  当仓库没有存储Q何物品时Q无法给仓库分配理员?br />
  (3) 更新异常Q?br />
  如果仓库换了理员,则表中所有行的管理员I(y)D都要修改?br />
  把仓库管理关p表分解Z个关p表Q?br />
  仓库理QStorehouseManage(仓库ID, 理员I(y)D)Q?br />
  仓库QStorehouse(仓库ID, 存储物品ID, 数量)?br />
  q样?a target="_blank">数据?/font>表是W合BCNF范式的,消除了删除异常、插入异常和更新异常?/p>

范式应用

  我们来逐步搞定一个论坛的数据?/font>Q有如下信息Q?br />
  Q?Q?用户Q用户名QemailQ主,?sh)话Q联pd址

  Q?Q?帖子Q发帖标题,发帖内容Q回复标题,回复内容

  W一ơ我们将数据?/font>设计Z仅存在表Q?br />  

用户?email 主页?sh)?/td>联系地址发帖标题发帖内容回复标题回复内容


  q个数据?/font>表符合第一范式Q但是没有Q何一l候选关键字能决?a target="_blank">数据?/font>表的整行Q唯一的关键字D는户名也不能完全决定整个元l。我们需要增?发帖ID"?回复ID"字段Q即表修改为:

用户?/td>email主页?sh)?/td>联系地址发帖ID发帖标题发帖内容回复ID回复标题回复内容


  q样数据表中的关键字(用户名,发帖IDQ回复ID)能决定整行:

  (用户?发帖ID,回复ID) ?(email,主页,?sh)?联系地址,发帖标题,发帖内容,回复标题,回复内容)

  但是Q这L(fng)设计不符合第二范式,因ؓ存在如下军_关系Q?br />
  (用户? ?(email,主页,?sh)?联系地址)

  (发帖ID) ?(发帖标题,发帖内容)

  (回复ID) ?(回复标题,回复内容)

  即非关键字段部分函数依赖于候选关键字D,很明显,q个设计会导致大量的数据冗余和操作异常?

  我们?a target="_blank">数据?/font>表分解ؓQ带下划U的为关键字Q:

  Q?Q?用户信息Q用户名QemailQ主,?sh)话Q联pd址

  Q?Q?帖子信息Q发帖IDQ标题,内容

  Q?Q?回复信息Q回复IDQ标题,内容

  Q?Q?发脓(chung)Q用户名Q发帖ID

  Q?Q?回复Q发帖IDQ回复ID

  q样的设计是满W???范式和BCNF范式要求的,但是q样的设计是不是最好的呢?

  不一定?br />
  观察可知Q第4?发帖"中的"用户??发帖ID"之间?QN的关p,因此我们可以?发帖"合ƈ到第2的"帖子信息"中;W??回复"中的 "发帖ID"?回复ID"之间也是1QN的关p,因此我们可以?回复"合ƈ到第3的"回复信息"中。这样可以一定量地减数据冗余,新的设计为:

  Q?Q?用户信息Q用户名QemailQ主,?sh)话Q联pd址

  Q?Q?帖子信息Q用户名Q发帖IDQ标题,内容

  Q?Q?回复信息Q发帖IDQ回复IDQ标题,内容

  数据?/font>?昄满所有范式的要求Q?br />
  数据?/font>?中存在非关键字段"标题"?内容"对关键字D?发帖ID"的部分函C赖,即不满W二范式的要求,但是q一设计q不会导致数据冗余和操作异常Q?br />
  数据?/font>?中也存在非关键字D?标题"?内容"对关键字D?回复ID"的部分函C赖,也不满W二范式的要求,但是?a target="_blank">数据?/font>?怼Q这一设计也不会导致数据冗余和操作异常?br />
  由此可以看出Qƈ不一定要满范式的要求,对于1QN关系Q当1的一边合q到N的那边后QN的那边就不再满W二范式了,但是q种设计反而比较好Q?br />
  对于MQN的关p,不能M一Ҏ(gu)N一边合q到另一边去Q这样会D不符合范式要求,同时D操作异常和数据冗余?
对于1Q?的关p,我们可以左边的1或者右边的1合ƈ到另一边去Q设计导致不W合范式要求Q但是ƈ不会D操作异常和数据冗余?br />
  l论

  满范式要求?a target="_blank">数据?/font>设计是结构清晰的Q同时可避免数据冗余和操作异常。这q意味着不符合范式要求的设计一定是错误的,?a target="_blank">数据?/font>表中存在1Q??QN关系q种较特D的情况下,合ƈD的不W合范式要求反而是合理的?br />
  在我们设?a target="_blank">数据?/font>的时候,一定要时刻考虑范式的要求?/p>

nbt 2006-06-15 11:40 发表评论
]]>
数据库设计方法、规范与技巧(转蝲Q?/title><link>http://www.tkk7.com/nbtymm/archive/2006/06/15/52951.html</link><dc:creator>nbt</dc:creator><author>nbt</author><pubDate>Thu, 15 Jun 2006 03:23:00 GMT</pubDate><guid>http://www.tkk7.com/nbtymm/archive/2006/06/15/52951.html</guid><wfw:comment>http://www.tkk7.com/nbtymm/comments/52951.html</wfw:comment><comments>http://www.tkk7.com/nbtymm/archive/2006/06/15/52951.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/nbtymm/comments/commentRss/52951.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/nbtymm/services/trackbacks/52951.html</trackback:ping><description><![CDATA[ <div> <font style="BACKGROUND-COLOR: #ffffff" color="#000000">一、数据库设计q程<br />数据库技术是信息资源理最有效的手Dc数据库设计是指对于一个给定的应用环境Q构造最优的数据库模式,建立数据库及其应用系l,有效存储数据Q满用户信息要求和处理要求?br />数据库设计中需求分析阶D늻合各个用L(fng)应用需求(现实世界的需求)Q在概念设计阶段形成独立于机器特炏V独立于各个DBMS产品的概忉|式(信息世界模型Q,用E-R图来描述。在逻辑设计阶段E-R图{换成具体的数据库产品支持的数据模型如关系模型QŞ成数据库逻辑模式。然后根据用户处理的要求Q安全性的考虑Q在基本表的基础上再建立必要的视图(VIEWQŞ成数据的外模式。在物理设计阶段Ҏ(gu)DBMS特点和处理的需要,q行物理存储安排Q设计烦引,形成数据库内模式?br />1. 需求分析阶D?br />需求收集和分析Q结果得到数据字典描q的数据需求(和数据流图描q的处理需求)。?br />需求分析的重点是调查、收集与分析用户在数据管理中的信息要求、处理要求、安全性与完整性要求?br />需求分析的Ҏ(gu)Q调查组l机构情c调查各部门的业务活动情c协助用h对新系l的各种要求、确定新pȝ的边界。?br />常用的调查方法有Q 跟班作业、开调查会、请专h介绍、询问、设计调查表L(fng)户填写、查阅记录?br />分析和表辄户需求的Ҏ(gu)主要包括自顶向下和自底向上两cL法。自向下的l构化分析方法(Structured AnalysisQ简USAҎ(gu)Q从最上层的系l组l机构入手,采用逐层分解的方式分析系l,q把每一层用数据图和数据字典描q?br />数据图表达了数据和处理q程的关pR系l中的数据则借助数据字典QData DictionaryQ简UDDQ来描述?br />数据字典是各cL据描q的集合Q它是关于数据库中数据的描述Q即元数据,而不是数据本w。数据字兔R常包括数据V数据结构、数据流、数据存储和处理q程五个部分(臛_应该包含每个字段的数据类型和在每个表内的d??br />数据Ҏ(gu)qͼ?jng)数据项名,数据含义说明,别名Q数据类型,长度Q?br />         取D_取值含义,与其他数据项的逻辑关系}?br />数据l构描述Q{(jng)数据l构名,含义说明Q组??jng)数据项或数据结构}}?br />数据描qͼ?jng)数据流名,说明Q数据流来源Q数据流dQ?br />         l成:?jng)数据结构}Q^均流量,高峰期流量} <br />数据存储描述Q{(jng)数据存储名,说明Q编P入的数据流Q流出的数据,   <br />        l成:?jng)数据结构}Q数据量Q存取方式} <br />处理q程描述Q{(jng)处理q程名,说明Q输??jng)数据流},输??jng)数据流? <br />          处理:?jng)简要说明}}?br />2. 概念l构设计阶段 <br />通过对用户需求进行综合、归U与抽象QŞ成一个独立于具体DBMS的概忉|型,可以用E-R图表C。?br />概念模型用于信息世界的徏模。概忉|型不依赖于某一个DBMS支持的数据模型。概忉|型可以{换ؓ计算Z某一DBMS支持的特定数据模型。?br />概念模型特点Q?br />(1) h较强的语义表达能力,能够方便、直接地表达应用中的各种语义知识。?br />(2) 应该单、清晰、易于用L(fng)解,是用户与数据库设计h员之间进行交的语言?br />概念模型设计的一U常用方法ؓIDEF1XҎ(gu)Q它?yu)是把实?联系Ҏ(gu)应用到语义数据模型中的一U语义模型化技术,用于建立pȝ信息模型?br />    使用IDEF1XҎ(gu)创徏E-R模型的步骤如下所C?<br />2.1 W零步——初始化工程<br />q个阶段的Q务是从目的描q和范围描述开始,定建模目标Q开发徏模计划,l织建模队伍Q收集源材料Q制定约束和规范。收集源材料是这阶段的重炏V通过调查和观察结果,业务程Q原有系l的输入输出Q各U报表,攉原始数据QŞ成了基本数据资料表?br />2.2 W一步——定义实?br />实体集成员都有一个共同的特征和属性集Q可以从攉的源材料——基本数据资料表中直接或间接标识出大部分实体。根据源材料名字表中表示物的术语以及h“代码”结术语Q如客户代码、代理商代码、品代码等其名词部分代表的实体标识出来,从而初步找出潜在的实体QŞ成初步实体表?br />2.3 W二步——定义联p?br />IDEF1X模型中只允许二元联系Qn元联pdd义ؓn个二元联pR根据实际的业务需求和规则Q用实体联pȝ阉|标识实体间的二元关系Q然后根据实际情늡定出q接关系的势、关pd和说明,定关系cdQ是标识关系、非标识关系Q强制的或可选的Q还是非定关系、分cdpR如果子实体的每个实例都需要通过和父实体的关pL标识Q则为标识关p,否则为非标识关系。非标识关系中,如果每个子实体的实例都与而且只与一个父实体兌Q则为强制的Q否则ؓ非强制的。如果父实体与子实体代表的是同一现实对象Q那么它们ؓ分类关系?br />2.4 W三步——定义码<br />通过引入交叉实体除去上一阶段产生的非定关系Q然后从非交叉实体和独立实体开始标识侯选码属性,以便唯一识别每个实体的实例,再从侯选码中确定主码。ؓ了确定主码和关系的有效性,通过非空规则和非多D则来保证Q即一个实体实例的一个属性不能是I|也不能在同一个时L一个以上的倹{找认的定关系Q将实体q一步分解,最后构造出IDEF1X模型的键图(KB图)?br />2.5 W四步——定义属?br />从源数据表中抽取说明性的名词开发出属性表Q确定属性的所有者。定义非ȝ属性,查属性的非空及非多D则。此外,q要查完全依赖函数规则和非传递依赖规则,保证一个非ȝ属性必M赖于ȝ、整个主码、仅仅是ȝ。以此得C臛_W合关系理论W三范式的改q的IDEF1X模型的全属性视图?br />2.6 W五步——定义其他对象和规则<br />    定义属性的数据cd、长度、精度、非I、缺省倹{约束规则等。定义触发器、存储过E、视图、角艌Ӏ同义词、序列等对象信息?br />3. 逻辑l构设计阶段 <br />    概늻构{换ؓ某个DBMS所支持的数据模型(例如关系模型Q,q对其进行优化。设计逻辑l构应该选择最适于描述与表辄应概늻构的数据模型Q然后选择最合适的DBMS?br />E-R图{换ؓ关系模型实际上就是要实体、实体的属性和实体之间的联p{化ؓ关系模式,q种转换一般遵循如下原则: <br />1Q一个实体型转换Z个关pL式。实体的属性就是关pȝ属性。实体的码就是关pȝ码。?br />2Q一个m:n联系转换Z个关pL式。与该联pȝq的各实体的码以及联pLw的属性均转换为关pȝ属性。而关pȝ码ؓ各实体码的组合。?br />3Q一?:n联系可以转换Z个独立的关系模式Q也可以与n端对应的关系模式合ƈ。如果{换ؓ一个独立的关系模式Q则与该联系相连的各实体的码以及联系本n的属性均转换为关pȝ属性,而关pȝ码ؓn端实体的码。?br />4Q一?:1联系可以转换Z个独立的关系模式Q也可以与Q意一端对应的关系模式合ƈ?br />5Q三个或三个以上实体间的一个多元联p{换ؓ一个关pL式。与该多元联pȝq的各实体的码以及联pLw的属性均转换为关pȝ属性。而关pȝ码ؓ各实体码的组合。 ?br />6Q同一实体集的实体间的联系Q即自联p,也可按上q?:1?:n和m:n三种情况分别处理。?br />7Q具有相同码的关pL式可合ƈ。?br />Zq一步提高数据库应用pȝ的性能Q通常以规范化理论为指|q应该适当C攏V调整数据模型的l构Q这是数据模型的优化。确定数据依赖。消除冗余的联系。确定各关系模式分别属于W几范式。确定是否要对它们进行合q或分解。一般来说将关系分解?NF的标准,卻I<br />表内的每一个值都只能被表达一ơ?br />?表内的每一行都应该被唯一的标识(有唯一键)?br />表内不应该存储依赖于其他键的非键信息。  ?br />4. 数据库物理设计阶D?br />为逻辑数据模型选取一个最适合应用环境的物理结构(包括存储l构和存取方法)。根据DBMS特点和处理的需要,q行物理存储安排Q设计烦引,形成数据库内模式?br />5. 数据库实施阶D?br />q用DBMS提供的数据语aQ例如SQLQ及其宿主语aQ例如CQ,Ҏ(gu)逻辑设计和物理设计的l果建立数据库,~制与调试应用程序,l织数据入库Qƈq行试运行。 数据库实施主要包括以下工作Q用DDL定义数据库结构、组l数据入库 、编制与调试应用E序、数据库试运行 ?br />6. 数据库运行和l护阶段 <br />数据库应用系l经q试q行后即可投入正式运行。在数据库系l运行过E中必须不断地对其进行评仗调整与修改。包括:数据库的转储和恢复、数据库的安全性、完整性控制、数据库性能的监督、分析和改进、数据库的重l织和重构造?br /><br />建模工具的?br />为加快数据库设计速度Q目前有很多数据库辅助工PCASE工具Q,如Rational公司的Rational RoseQCA公司的Erwin和BpwinQSybase公司的PowerDesigner以及Oracle公司的Oracle Designer{?br />ERwin主要用来建立数据库的概念模型和物理模型。它能用囑Ş化的方式Q描q出实体、联pd实体的属性。ERwin支持IDEF1XҎ(gu)。通过使用ERwin建模工具自动生成、更改和分析IDEF1X模型Q不仅能得到优秀的业务功能和数据需求模型,而且可以实现从IDEF1X模型到数据库物理设计的{变。ERwin工具l制的模型对应于逻辑模型和物理模型两U。在逻辑模型中,IDEF1X工具可以方便地用图形化的方式构建和l制实体联系及实体的属性。在物理模型中,ERwin可以定义对应的表、列Qƈ可针对各U数据库理pȝ自动转换为适当的类型?br />设计人员可根据需要选用相应的数据库设计建模工具。例如需求分析完成之后,设计人员可以使用Erwin画ER图,ER图{换ؓ关系数据模型Q生成数据库l构Q画数据图Q生成应用程序?br />二、数据库设计技?br />1. 设计数据库之前(需求分析阶D)<br />1) 理解客户需求,询问用户如何看待未来需求变化。让客户解释光求,而且随着开发的l箋Q还要经常询问客户保证其需求仍然在开发的目的之中?br />2) 了解企业业务可以在以后的开发阶D节U大量的旉?br />3) 重视输入输出?br />在定义数据库表和字段需求(输入Q时Q首先应查现有的或者已l设计出的报表、查询和视图Q输出)以决定ؓ了支持这些输出哪些是必要的表和字Dc?br />举例Q假如客户需要一个报表按照邮政编码排序、分D和求和Q你要保证其中包括了单独的邮政编码字D而不要把邮政~码p进地址字段里?br />4) 创徏数据字典和ER 图表<br />ER 图表和数据字典可以让M了解数据库的人都明确如何从数据库中获得数据。ER囑֯表明表之间关pd有用Q而数据字典则说明了每个字D늚用途以及Q何可能存在的别名。对SQL 表达式的文档化来说这是完全必要的?br />5) 定义标准的对象命名规?br />数据库各U对象的命名必须规范?br />2. 表和字段的设计(数据库逻辑设计Q?br />表设计原?br />1) 标准化和规范?br />数据的标准化有助于消除数据库中的数据冗余。标准化有好几种形式Q但Third Normal FormQ?NFQ通常被认为在性能、扩展性和数据完整性方面达C最好^衡。简单来_遵守3NF 标准的数据库的表设计原则是:“One Fact in One Place”即某个表只包括其本w基本的属性,当不是它们本w所h的属性时需q行分解。表之间的关p通过外键相连接。它h以下特点Q有一l表专门存放通过键连接v来的兌数据?br />举例Q某个存攑֮户及其有兛_单的3NF 数据库就可能有两个表QCustomer 和Order。Order 表不包含定单兌客户的Q何信息,但表内会存放一个键|该键指向Customer 表里包含该客户信息的那一行?br />事实上,Z效率的缘故,对表不进行标准化有时也是必要的?br />2) 数据驱动<br />采用数据驱动而非编码的方式Q许多策略变更和l护都会方便得多Q大大增强系l的灉|性和扩展性?br />举例Q假如用L(fng)面要讉K外部数据源(文g、XML 文档、其他数据库{)Q不妨把相应的连接和路径信息存储在用L(fng)面支持表里。还有,如果用户界面执行工作之cȝdQ发送邮件、打CW、修改记录状态等Q,那么产生工作的数据也可以存攑֜数据库里。角色权限管理也可以通过数据驱动来完成。事实上Q如果过E是数据驱动的,你就可以把相当大的责Ll用Pqhl护自己的工作流q程?br />3) 考虑各种变化<br />在设计数据库的时候考虑到哪些数据字D将来可能会发生变更?br />举例Q姓氏就是如此(注意是西方h的姓氏,比如x结婚后从夫姓等Q。所以,在徏立系l存储客户信息时Q在单独的一个数据表里存储姓氏字D,而且q附加v始日和终止日{字D,q样可以跟t这一数据条目的变化?br /><br />字段设计原则<br />4) 每个表中都应该添加的3 个有用的字段<br />?dRecordCreationDateQ在VB 下默认是Now()Q而在SQL Server 下默认ؓGETDATE()<br />?sRecordCreatorQ在SQL Server 下默认ؓNOT NULL DEFAULT USER<br />?nRecordVersionQ记录的版本标记Q有助于准确说明记录中出现null 数据或者丢失数据的原因<br />5) 对地址和电(sh)话采用多个字D?br />描述街道地址q短一行记录是不够的。Address_Line1、Address_Line2 和Address_Line3 可以提供更大的灵zL。还有,?sh)话L(fng)和邮件地址最好拥有自q数据表,光h自n的类型和标记cd?br />6) 使用角色实体定义属于某类别的?br />在需要对属于特定cd或者具有特定角色的事物做定义时Q可以用角色实体来创建特定的旉兌关系Q从而可以实现自我文化?br />举例Q用PERSON 实体和PERSON_TYPE 实体来描qCh员。比方说Q当John Smith, Engineer 提升为John Smith, Director 乃至最后爬到John Smith, CIO 的高位,而所有你要做的不q是改变两个表PERSON 和PERSON_TYPE 之间关系的键|同时增加一个日?旉字段来知道变化是何时发生的。这P你的PERSON_TYPE 表就包含了所有PERSON 的可能类型,比如Associate、Engineer、Director、CIO 或者CEO {。还有个替代办法是改变PERSON 记录来反映新头衔的变化,不过q样一来在旉上无法跟t个人所处位|的具体旉?br />7) 选择数字cd和文本类型尽量充?br />在SQL 中用smallint 和tinyint cd要特别小心。比如,假如想看看月销售总额Q总额字段cd是smallintQ那么,如果总额过?32,767 ׃能进行计操作了?br />而ID cd的文本字D,比如客户ID 或定单号{等都应该设|得比一般想象更大。假讑֮户ID ?0 位数ѝ那你应该把数据库表字段的长度设?2 或?3 个字W长。但q额外占据的I间却无需来重构整个数据库就可以实现数据库规模的增长了?br />8) 增加删除标记字段<br />在表中包含一个“删除标记”字D,q样可以把行标Cؓ删除。在关系数据库里不要单独删除某一行;最好采用清除数据程序而且要仔l维护烦引整体性。?br />3. 选择键和索引Q数据库逻辑设计Q?br />键选择原则Q?br />1) 键设? 原则<br />?为关联字D创建外键?br />?所有的键都必须唯一?br />?避免使用复合键?br />?外键L兌唯一的键字段?br />2) 使用pȝ生成的主?br />设计数据库的时候采用系l生成的键作Z键,那么实际控制了数据库的烦引完整性。这P数据库和非h工机制就有效地控制了对存储数据中每一行的讉K。采用系l生成键作ؓ主键q有一个优点:当拥有一致的键结构时Q找到逻辑~陷很容易?br />3) 不要用用L(fng)?不让主键h可更新?<br />在确定采用什么字D作的键的时候,可一定要心用户要~辑的字Dc通常的情况下不要选择用户可编辑的字段作ؓ键?br />4) 可选键有时可做主键<br />把可选键q一步用做主键,可以拥有建立强大索引的能力?br /><br />索引使用原则Q?br />索引是从数据库中获取数据的最高效方式之一?5%的数据库性能问题都可以采用烦引技术得到解冟?br />1) 逻辑主键使用唯一的成l烦引,对系l键Q作为存储过E)采用唯一的非成组索引Q对M外键列采用非成组索引。考虑数据库的I间有多大,表如何进行访问,q有q些讉K是否主要用作d?br />2) 大多数数据库都烦引自动创建的主键字段Q但是可别忘了烦引外键,它们也是l常使用的键Q比如运行查询显CZ表和所有关联表的某条记录就用得上?br />3) 不要索引memo/note 字段Q不要烦引大型字D(有很多字W)Q这样作会让索引占用太多的存储空间?br />4) 不要索引常用的小型表<br />不要为小型数据表讄M键,假如它们l常有插入和删除操作更别这样作了。对q些插入和删除操作的索引l护可能比扫描表I间消耗更多的旉?br /><br />4. 数据完整性设计(数据库逻辑设计Q?br />1) 完整性实现机Ӟ<br />实体完整性:主键<br />参照完整性:<br />父表中删除数据:U联删除Q受限删除;|空?br />父表中插入数据:受限插入Q递归插入<br />父表中更新数据:U联更新Q受限更斎ͼ|空?br />DBMS对参照完整性可以有两种Ҏ(gu)实现Q外键实现机ӞU束规则Q和触发器实现机?br />用户定义完整性:<br />    NOT NULLQCHECKQ触发器<br />2) 用约束而非商务规则强制数据完整?br />采用数据库系l实现数据的完整性。这不但包括通过标准化实现的完整性而且q包括数据的功能性。在写数据的时候还可以增加触发器来保证数据的正性。不要依赖于商务层保证数据完整性;它不能保证表之间Q外键)的完整性所以不能强加于其他完整性规则之上?br />3) 强制指示完整?br />在有x据进入数据库之前其剔除。激zL据库pȝ的指C完整性特性。这样可以保持数据的清洁而能q开发h员投入更多的旉处理错误条g?br />4) 使用查找控制数据完整?br />控制数据完整性的最x式就是限制用L(fng)选择。只要有可能都应该提供给用户一个清晰的价值列表供光择。这样将减少键入代码的错误和误解同时提供数据的一致性。某些公共数据特别适合查找Q国家代码、状态代码等?br />5) 采用视图<br />Z在数据库和应用程序代码之间提供另一层抽象,可以为应用程序徏立专门的视图而不必非要应用程序直接访问数据表。这样做q等于在处理数据库变更时l你提供了更多的自由?br />5. 其他设计技?br />1) 避免使用触发?br />触发器的功能通常可以用其他方式实现。在调试E序时触发器可能成ؓq扰。假如你实需要采用触发器Q你最好集中对它文档化?br />2) 使用常用pQ或者其他Q何语aQ而不要用编?br />在创Z拉菜单、列表、报表时最好按照英语名排序。假如需要编码,可以在编码旁附上用户知道的英语?br />3) 保存常用信息<br />让一个表专门存放一般数据库信息非常有用。在q个表里存放数据库当前版本、最q检?修复Q对AccessQ、关联设计文档的名称、客L(fng)信息。这样可以实CU简单机制跟t数据库Q当客户抱怨他们的数据库没有达到希望的要求而与你联pLQ这样做寚w客户?服务器环境特别有用?br />4) 包含版本机制<br />在数据库中引入版本控制机制来定使用中的数据库的版本。时间一长,用户的需求L会改变的。最l可能会要求修改数据库结构。把版本信息直接存放到数据库中更为方ѝ?br />5) ~制文档<br />Ҏ(gu)有的快捷方式、命名规范、限制和函数都要~制文档?br />采用l表、列、触发器{加注释的数据库工具。对开发、支持和跟踪修改非常有用?br />Ҏ(gu)据库文档化,或者在数据库自w的内部或者单独徏立文。这P当过了一q多旉后再回过头来做第2 个版本,犯错的机会将大大减少?br />6) 试、测试、反复测?br />建立或者修订数据库之后Q必ȝ用户新输入的数据试数据字段。最重要的是Q让用户q行试q且同用户一道保证选择的数据类型满_业要求。测试需要在把新数据库投入实际服务之前完成?br />7) 查设?br />在开发期间检查数据库设计的常用技术是通过其所支持的应用程序原型检查数据库。换句话_针对每一U最l表达数据的原型应用Q保证你查了数据模型q且查看如何取出数据?br />三、数据库命名规范<br />1. 实体Q表Q的命名<br />1) 表以名词或名词短语命名,定表名是采用复数还是单数Ş式,此外l表的别名定义简单规则(比方_如果表名是一个单词,别名取单词的前4 个字母;如果表名是两个单词,各取两个单词的前两个字母组? 个字母长的别名;如果表的名字? 个单词组成,从头两个单词中各取一个然后从最后一个单词中再取Z个字母,l果q是l成4 字母长的别名Q其余依ơ类推)<br />对工作用表来_表名可以加上前缀WORK_ 后面附上采用该表的应用程序的名字。在命名q程当中Q根据语义拼凑羃写即可。注意,׃ORCLE会将字段名称l一成大写或者小写中的一U,所以要求加上下划线?br />举例Q?br />定义的羃写 Sales: Sal 销售;<br />Order: Ord 订单Q?br />Detail: Dtl 明细Q?br />则销售订单明l表命名为:Sal_Ord_Dtl;<br />2) 如果表或者是字段的名UC有一个单词,那么不用羃写,而是用完整的单词?br />举例Q?br />定义的羃写 Material Ma 物品Q?br />物品表名为:Material, 而不是 Ma.<br />但是字段物品~码则是QMa_ID;而不是Material_ID<br />3) 所有的存储值列表的表前面加上前~Z<br />目的是将q些值列表类排序在数据库最后?br />4) 所有的冗余cȝ命名(主要是篏计表)前面加上前缀X<br />冗余cLZ提高数据库效率,非规范化数据库的时候加入的字段或者表<br />5) 兌c通过用下划线q接两个基本cM后,再加前缀R的方式命?后面按照字母序|列两个表名或者表名的~写?br />兌表用于保存多对多关系?br />如果被关联的表名大于10个字母,必须原来的表名的进行羃写。如果没有其他原因,都用羃写?br />举例Q表Object与自w存在多对多的关p?则保存多对多关系的表命名为:R_ObjectQ?br />表 Depart和Employee;存在多对多的关系Q则兌表命名ؓR_Dept_Emp<br />2. 属性(列)的命?br />1) 采用有意义的列名Q表内的列要针对键采用一整套设计规则。每一个表都将有一个自动ID作ؓd,逻辑上的d作ؓW一l候选主健来定义,如果是数据库自动生成的编码,l一命名为:ID;如果是自定义的逻辑上的~码则用~写加“ID”的Ҏ(gu)命名。如果键是数字类型,你可以用_NO 作ؓ后缀Q如果是字符cd则可以采用_CODE 后缀。对列名应该采用标准的前~和后~?br />举例Q销售订单的~号字段命名QSal_Ord_IDQ如果还存在一个数据库生成的自动编P则命名ؓQID?br />2) 所有的属性加上有关类型的后缀Q注意,如果q需要其它的后缀Q都攑֜cd后缀之前?br />? 数据cd是文本的字段Q类型后~TX可以不写。有些类型比较明昄字段Q可以不写类型后~?br />3) 采用前缀命名<br />l每个表的列名都采用l一的前~Q那么在~写SQL表达式的时候会得到大大的简化。这样做也确实有~点Q比如破坏了自动表连接工L(fng)作用Q后者把公共列名同某些数据库联系h?br />3. 视图的命?br />1) 视图以V作ؓ前缀Q其他命名规则和表的命名cMQ?br />2) 命名应尽量体现各视图的功能?br />4. 触发器的命名<br />触发器以TR作ؓ前缀Q触发器名ؓ相应的表名加上后~QInsert触发器加'_I'QDelete触发器加'_D'QUpdate触发器加'_U'Q如QTR_Customer_IQTR_Customer_DQTR_Customer_U?br />5. 存储q程?br />存储q程应以'UP_'开_和系l的存储q程区分Q后l部分主要以动宾形式构成Qƈ用下划线分割各个l成部分。如增加代理商的帐户的存储过Eؓ'UP_Ins_Agent_Account'?br />6. 变量?br />变量名采用小写,若属于词lŞ式,用下划线分隔每个单词Q如@my_err_no?br />7. 命名中其他注意事?br />1)  以上命名都不得超q?0个字W的pȝ限制。变量名的长度限制ؓ29Q不包括标识字符@Q?br />2)  数据对象、变量的命名都采用英文字W,止使用中文命名。绝对不要在对象名的字符之间留空根{?br />3) 心保留词,要保证你的字D名没有和保留词、数据库pȝ或者常用访问方法冲H?br />5) 保持字段名和cd的一致性,在命名字Dƈ为其指定数据cd的时候一定要保证一致性。假如数据类型在一个表里是整数Q那在另一个表里可别变成字符型了?</font> </div> <img src ="http://www.tkk7.com/nbtymm/aggbug/52951.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/nbtymm/" target="_blank">nbt</a> 2006-06-15 11:23 <a href="http://www.tkk7.com/nbtymm/archive/2006/06/15/52951.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>_SQL语句(转蝲)http://www.tkk7.com/nbtymm/archive/2006/06/05/50447.htmlnbtnbtMon, 05 Jun 2006 04:08:00 GMThttp://www.tkk7.com/nbtymm/archive/2006/06/05/50447.htmlhttp://www.tkk7.com/nbtymm/comments/50447.htmlhttp://www.tkk7.com/nbtymm/archive/2006/06/05/50447.html#Feedback0http://www.tkk7.com/nbtymm/comments/commentRss/50447.htmlhttp://www.tkk7.com/nbtymm/services/trackbacks/50447.htmldesc 按降序排?br />

下列语句部分是Mssql语句Q不可以在access中用?/p>

SQL分类Q?
DDL—数据定义语a(CREATEQALTERQDROPQDECLARE)
DML—数据操U语a(SELECTQDELETEQUPDATEQINSERT)
DCL—数据控制语a(GRANTQREVOKEQCOMMITQROLLBACK)

首先,要介l基语句Q?br />1、说明:创徏数据?br />CREATE DATABASE database-name
2、说明:删除数据?br />drop database dbname
3、说明:备䆾sql server
--- 创徏 备䆾数据?device
USE master
EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'
--- 开?备䆾
BACKUP DATABASE pubs TO testBack
4、说明:创徏新表
create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)
Ҏ(gu)已有的表创徏新表Q?
AQcreate table tab_new like tab_old (使用旧表创徏新表)
BQcreate table tab_new as select col1,col2?from tab_old definition only
5、说明:删除新表drop table tabname
6、说明:增加一个列
Alter table tabname add column col type
注:列增加后不能删除。DB2中列加上后数据类型也不能改变Q唯一能改变的是增加varcharcd的长度?br />7、说明:d主键Q?Alter table tabname add primary key(col)
说明Q删除主键: Alter table tabname drop primary key(col)
8、说明:创徏索引Qcreate [unique] index idxname on tabname(col?)
删除索引Qdrop index idxname
注:索引是不可更改的Q想更改必须删除重新建?br />9、说明:创徏视图Qcreate view viewname as select statement
删除视图Qdrop view viewname
10、说明:几个单的基本的sql语句
选择Qselect * from table1 where 范围
插入Qinsert into table1(field1,field2) values(value1,value2)
删除Qdelete from table1 where 范围
更新Qupdate table1 set field1=value1 where 范围
查找Qselect * from table1 where field1 like ?value1%?---like的语法很_֦Q查资料!
排序Qselect * from table1 order by field1,field2 [desc]
LQselect count as totalcount from table1
求和Qselect sum(field1) as sumvalue from table1
q_Qselect avg(field1) as avgvalue from table1
最大:select max(field1) as maxvalue from table1
最:select min(field1) as minvalue from table1
11、说明:几个高查询q算?br />AQ?UNION q算W?
UNION q算W通过l合其他两个l果表(例如 TABLE1 ?TABLE2Qƈ消去表中M重复行而派生出一个结果表。当 ALL ?UNION 一起用时Q即 UNION ALLQ,不消除重复行。两U情况下Q派生表的每一行不是来?TABLE1 是来自 TABLE2?
BQ?EXCEPT q算W?
EXCEPT q算W通过包括所有在 TABLE1 中但不在 TABLE2 中的行ƈ消除所有重复行而派生出一个结果表。当 ALL ?EXCEPT 一起用时 (EXCEPT ALL)Q不消除重复行?
CQ?INTERSECT q算W?br />INTERSECT q算W通过只包?TABLE1 ?TABLE2 中都有的行ƈ消除所有重复行而派生出一个结果表。当 ALL ?INTERSECT 一起用时 (INTERSECT ALL)Q不消除重复行?
注:使用q算词的几个查询l果行必L一致的?
12、说明:使用外连?
A、left outer joinQ?
左外q接Q左q接Q:l果集几包括q接表的匚w行,也包括左q接表的所有行?
SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
BQright outer join:
叛_q接(双?Q结果集既包括连接表的匹配连接行Q也包括双接表的所有行?
CQfull outer joinQ?
全外q接Q不仅包括符可接表的匹配行Q还包括两个q接表中的所有记录?/p>

其次Q大家来看一些不错的sql语句
1、说明:复制?只复制结?源表名:a 新表名:b) (Access可用)
法一Qselect * into b from a where 1<>1
法二Qselect top 0 * into b from a

2、说明:拯?拯数据,源表名:a 目标表名Qb) (Access可用)
insert into b(a, b, c) select d,e,f from b;

3、说明:跨数据库之间表的拯(具体数据使用l对路径) (Access可用)
insert into b(a, b, c) select d,e,f from b in ‘具体数据库?where 条g
例子Q?.from b in '"&Server.MapPath(".")&"\data.mdb" &"' where..

4、说明:子查?表名1Qa 表名2Qb)
select a,b,c from a where a IN (select d from b ) 或? select a,b,c from a where a IN (1,2,3)

5、说明:昄文章、提交h和最后回复时?br />select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b

6、说明:外连接查?表名1Qa 表名2Qb)
select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c

7、说明:在线视图查询(表名1Qa )
select * from (SELECT a,b,c FROM a) T where t.a > 1;

8、说明:between的用?between限制查询数据范围时包括了边界?not between不包?br />select * from table1 where time between time1 and time2
select a,b,c, from table1 where a not between 数? and 数?

9、说明:in 的用方?br />select * from table1 where a [not] in (‘??’??’??’??

10、说明:两张兌表,删除主表中已l在副表中没有的信息
delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )

11、说明:四表联查问题Q?br />select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....

12、说明:日程安排提前五分钟提?
SQL: select * from 日程安排 where datediff('minute',f开始时?getdate())>5

13、说明:一条sql 语句搞定数据库分?br />select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段

14、说明:?0条记?br />select top 10 * form table1 where 范围

15、说明:选择在每一lb值相同的数据中对应的a最大的记录的所有信?cMq样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成l排?{等.)
select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)

16、说明:包括所有在 TableA 中但不在 TableB和TableC 中的行ƈ消除所有重复行而派生出一个结果表
(select a from tableA ) except (select a from tableB) except (select a from tableC)

17、说明:随机取出10条数?br />select top 10 * from tablename order by newid()

18、说明:随机选择记录
select newid()

19、说明:删除重复记录
Delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)

20、说明:列出数据库里所有的表名
select name from sysobjects where type='U'

21、说明:列出表里的所有的
select name from syscolumns where id=object_id('TableName')

22、说明:列示type、vender、pcs字段Q以type字段排列Qcase可以方便地实现多重选择Q类似select 中的case?br />select type,sum(case vender when 'A' then pcs else 0 end),sum(case vender when 'C' then pcs else 0 end),sum(case vender when 'B' then pcs else 0 end) FROM tablename group by type
昄l果Q?br />type vender pcs
?sh)?A 1
?sh)?A 1
光盘 B 2
光盘 A 2
手机 B 3
手机 C 3

23、说明:初始化表table1

TRUNCATE TABLE table1

24、说明:选择?0?5的记?br />select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc
  
随机选择数据库记录的Ҏ(gu)Q用Randomize函数Q通过SQL语句实现Q?br />  对存储在数据库中的数据来_随机数特性能l出上面的效果,但它们可能太慢了些。你不能要求ASP“找个随机数”然后打印出来。实际上常见的解x案是建立如下所C的循环Q?
Randomize
RNumber = Int(Rnd*499) +1
 
While Not objRec.EOF
If objRec("ID") = RNumber THEN
... q里是执行脚?...
end if
objRec.MoveNext
Wend
 
  q很Ҏ(gu)理解。首先,你取??00范围之内的一个随机数Q假?00是数据库内记录的LQ。然后,你遍历每一记录来测试ID 的倹{检查其是否匚wRNumber。满x件的话就执行由THEN 关键字开始的那一块代码。假如你的RNumber {于495Q那么要循环一遍数据库q旉可就长了。虽?00q个数字看v来大了些Q但相比更ؓE_的企业解x案这q是个小型数据库了,后者通常在一个数据库内就包含了成千上万条记录。这时候不死定了Q?
  采用SQLQ你可以很快地扑և准确的记录ƈ且打开一个只包含该记录的recordsetQ如下所C:
Randomize
RNumber = Int(Rnd*499) + 1
 
SQL = "SELECT * FROM Customers WHERE ID = " & RNumber
 
set objRec = ObjConn.Execute(SQL)
Response.WriteRNumber & " = " & objRec("ID") & " " & objRec("c_email")
 
  不必写出RNumber 和IDQ你只需要检查匹配情况即可。只要你对以上代码的工作满意Q你自可按需操作“随机”记录。Recordset没有包含其他内容Q因此你很快p扑ֈ你需要的记录q样大大降低了处理旉?
再谈随机?
  现在你下定决心要榨干Random 函数的最后一滴aQ那么你可能会一ơ取出多条随录或者想采用一定随围内的记录。把上面的标准Random CZ扩展一下就可以用SQL应对上面两种情况了?
  Z取出几条随机选择的记录ƈ存放在同一recordset内,你可以存储三个随机数Q然后查询数据库获得匚wq些数字的记录:
SQL = "SELECT * FROM Customers WHERE ID = " & RNumber & " OR ID = " & RNumber2 & " OR ID = " & RNumber3
 
  假如你想选出10条记录(也许是每ơ页面装载时?0条链接的列表Q,你可以用BETWEEN 或者数学等式选出W一条记录和适当数量的递增记录。这一操作可以通过好几U方式来完成Q但?SELECT 语句只显CZU可能(q里的ID 是自动生成的L(fng)Q:
SQL = "SELECT * FROM Customers WHERE ID BETWEEN " & RNumber & " AND " & RNumber & "+ 9"

  注意Q以上代码的执行目的不是查数据库内是否有9条ƈ发记录?/p>

 
随机d若干条记录,试q?br />Access语法QSELECT top 10 * From 表名 ORDER BY Rnd(id)
Sql server:select top n * from 表名 order by newid()
mysqlelect * From 表名 Order By rand() Limit n
Access左连接语?最q开发要用左q接,Access帮助什么都没有,|上没有Access的SQL说明,只有自己试, 现在C以备后查)
语法elect table1.fd1,table1,fd2,table2.fd2 From table1 left join table2 on table1.fd1,table2.fd1 where ...
使用SQL语句 ?..代替q长的字W串昄
语法Q?br />SQL数据库:select case when len(field)>10 then left(field,10)+'...' else field end as news_name,news_id from tablename
Access数据库:SELECT iif(len(field)>2,left(field,2)+'...',field) FROM tablename;
 
Conn.Execute说明
ExecuteҎ(gu)
  该方法用于执行SQL语句。根据SQL语句执行后是否返回记录集Q该Ҏ(gu)的用格式分Z下两U:

 1Q执行SQL查询语句Ӟ返回查询得到的记录集。用法ؓQ?br />    Set 对象变量?q接对象.Execute("SQL 查询语言")
   ExecuteҎ(gu)调用后,会自动创录集对象Qƈ查询结果存储在该记录对象中Q通过SetҎ(gu)Q将记录集赋l指定的对象保存Q以后对象变量就代表了该记录集对象?/p>

    2Q执行SQL的操作性语aӞ没有记录集的q回。此时用法ؓQ?br />    q接对象.Execute "SQL 操作性语? [, RecordAffected][, Option]
      ·RecordAffected 为可选项Q此出可攄一个变量,SQL语句执行后,所生效的记录数会自动保存到该变量中。通过讉K该变量,可知道SQL语句队多条记录q行了操作?br />      ·Option 可选项Q该参数的取值通常为adCMDTextQ它用于告诉ADOQ应该将ExecuteҎ(gu)之后的第一个字W解释ؓ命o文本。通过指定该参敎ͼ可执行更高效?/p>

·BeginTrans、RollbackTrans、CommitTransҎ(gu)
  q三个方法是q接对象提供的用于事务处理的Ҏ(gu)。BeginTrans用于开始一个事物;RollbackTrans用于回滚事务QCommitTrans用于提交所有的事务处理l果Q即认事务的处理?br />  事务处理可以一l操作视Z个整体,只有全部语句都成功执行后Q事务处理才成功;若其中有一个语句执行失败,则整个处理就失败,q恢复到处里前的状态?br />  BeginTrans和CommitTrans用于标记事务的开始和l束Q在q两个之间的语句Q就是作Z务处理的语句。判断事务处理是否成功,可通过q接对象的Error集合来实玎ͼ若Error集合的成员个C?Q则说明有错误发生,事务处理p|。Error集合中的每一个Error对象Q代表一个错误信息?



nbt 2006-06-05 12:08 发表评论
]]>
վ֩ģ壺 һֻ߹ۿ | ѹۿ| ձһѵӰ| AVվ߹ۿ| ˾þں91| þþ뾫Ʒպ| þþþavר| vavaó| ޾Ʒһ| APPѹۿƵ| ѾƷպȾþ| ĻӰԺ| ޾Ʒרþþ| ޹պ߳ѿ| AV㽶һ| Ļ| Ƶ㶮| ѳ¼Ƶ| һ| AVӰԺۿ| ˿wwwƵ| ѹۿڵwwwƵ| ŷŮƵ| AVҹӰԺʦӰԺ| Avһ| ձһѹۿ | һĻ| ŷƵѹ| ŮպѲ| ݹѾþþ91| ޹ƷԲAV| ר˿| ҹѸþӰԺ| ȫƵѹۿ| ˳77777ɫ߲| һ߲ͨ| wwwƵ߹ۿ| ֳִִֺƵ| Ʒպһ| ޹| ֻۿ߹ۿ|