??xml version="1.0" encoding="utf-8" standalone="yes"?> 假设仓库理关系表ؓStorehouseManage(仓库ID, 存储物品ID, 理员ID, 数量)Q且有一个管理员只在一个仓库工作;一个仓库可以存储多U物品。这个数据库表中存在如下军_关系Q?br />
范式应用 1 数据的完整?/strong> drop table EmployeeInfo create table EmployeeInfo 一、基 1、说明:创徏数据?/p>
CREATE DATABASE database-name 2、说明:删除数据?/p>
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],..) Ҏ已有的表创徏新表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的长度?/p>
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想更改必须删除重新建?/p>
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算?/p>
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?/p>
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>
二、提?/p>
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和最后回复时?/p>
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不包?/p>
select * from table1 where time between time1 and time2 select a,b,c, from table1 where a not between 数? and 数? 9、说明:in 的用方?/p>
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?/p>
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 语句搞定数据库分?/p>
select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段 14、说明:?0条记?/p>
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条数?/p>
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?/p>
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?/p>
type vender pcs 电脑 A 1 电脑 A 1 光盘 B 2 光盘 A 2 手机 B 3 手机 C 3 23、说明:初始化表table1 TRUNCATE TABLE table1 24、说明:选择?0?5的记?/p>
select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc 三、技?/p>
1?=1Q?=2的用,在SQL语句l合时用的较?/p>
"where 1=1" 是表C选择全部 "where 1=2"全部不选, 如: if @strWhere !='' begin set @strSQL = 'select count(*) as Total from [' + @tblName + '] where ' + @strWhere end else begin set @strSQL = 'select count(*) as Total from [' + @tblName + ']' end 我们可以直接写成 set @strSQL = 'select count(*) as Total from [' + @tblName + '] where 1=1 安定 '+ @strWhere 2、收~数据库 --重徏索引 DBCC REINDEX DBCC INDEXDEFRAG --收羃数据和日?/p>
DBCC SHRINKDB DBCC SHRINKFILE 3、压~数据库 dbcc shrinkdatabase(dbname) 4、{UL据库l新用户以已存在用户权限 exec sp_change_users_login 'update_one','newname','oldname' go 5、检查备份集 RESTORE VERIFYONLY from disk='E:\dvbbs.bak' 6、修复数据库 ALTER DATABASE [dvbbs] SET SINGLE_USER GO DBCC CHECKDB('dvbbs',repair_allow_data_loss) WITH TABLOCK GO ALTER DATABASE [dvbbs] SET MULTI_USER GO 7、日志清?/p>
SET NOCOUNT ON DECLARE @LogicalFileName sysname, @MaxMinutes INT, @NewSize INT USE tablename -- 要操作的数据库名 SELECT @LogicalFileName = 'tablename_log', -- 日志文g?/p>
@MaxMinutes = 10, -- Limit on time allowed to wrap log. @NewSize = 1 -- 你想讑֮的日志文件的大小(M) -- Setup / initialize DECLARE @OriginalSize int SELECT @OriginalSize = size FROM sysfiles WHERE name = @LogicalFileName SELECT 'Original Size of ' + db_name() + ' LOG is ' + CONVERT(VARCHAR(30),@OriginalSize) + ' 8K pages or ' + CONVERT(VARCHAR(30),(@OriginalSize*8/1024)) + 'MB' FROM sysfiles WHERE name = @LogicalFileName CREATE TABLE DummyTrans (DummyColumn char (8000) not null) DECLARE @Counter INT, @StartTime DATETIME, @TruncLog VARCHAR(255) SELECT @StartTime = GETDATE(), @TruncLog = 'BACKUP LOG ' + db_name() + ' WITH TRUNCATE_ONLY' DBCC SHRINKFILE (@LogicalFileName, @NewSize) EXEC (@TruncLog) -- Wrap the log if necessary. WHILE @MaxMinutes > DATEDIFF (mi, @StartTime, GETDATE()) -- time has not expired AND @OriginalSize = (SELECT size FROM sysfiles WHERE name = @LogicalFileName) AND (@OriginalSize * 8 /1024) > @NewSize BEGIN -- Outer loop. SELECT @Counter = 0 WHILE ((@Counter < @OriginalSize / 16) AND (@Counter < 50000)) BEGIN -- update INSERT DummyTrans VALUES ('Fill Log') DELETE DummyTrans SELECT @Counter = @Counter + 1 END EXEC (@TruncLog) END SELECT 'Final Size of ' + db_name() + ' LOG is ' + CONVERT(VARCHAR(30),size) + ' 8K pages or ' + CONVERT(VARCHAR(30),(size*8/1024)) + 'MB' FROM sysfiles WHERE name = @LogicalFileName DROP TABLE DummyTrans SET NOCOUNT OFF 8、说明:更改某个?/p>
exec sp_changeobjectowner 'tablename','dbo' 9、存储更改全部表 CREATE PROCEDURE dbo.User_ChangeObjectOwnerBatch @OldOwner as NVARCHAR(128), @NewOwner as NVARCHAR(128) AS DECLARE @Name as NVARCHAR(128) DECLARE @Owner as NVARCHAR(128) DECLARE @OwnerName as NVARCHAR(128) DECLARE curObject CURSOR FOR select 'Name' = name, 'Owner' = user_name(uid) from sysobjects where user_name(uid)=@OldOwner order by name OPEN curObject FETCH NEXT FROM curObject INTO @Name, @Owner WHILE(@@FETCH_STATUS=0) BEGIN if @Owner=@OldOwner begin set @OwnerName = @OldOwner + '.' + rtrim(@Name) exec sp_changeobjectowner @OwnerName, @NewOwner end -- select @name,@NewOwner,@OldOwner FETCH NEXT FROM curObject INTO @Name, @Owner END close curObject deallocate curObject GO 10、SQL SERVER中直接@环写入数?/p>
declare @i int set @i=1 while @i<30 begin insert into test (userid) values(@i) set @i=@i+1 end 记存储q程中经常用到的本周Q本月,本年函数 Dateadd(wk,datediff(wk,0,getdate()),-1) Dateadd(wk,datediff(wk,0,getdate()),6) Dateadd(mm,datediff(mm,0,getdate()),0) Dateadd(ms,-3,dateadd(mm,datediff(m,0,getdate())+1,0)) Dateadd(yy,datediff(yy,0,getdate()),0) Dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate())+1, 0)) 上面的SQL代码只是一个时间段 Dateadd(wk,datediff(wk,0,getdate()),-1) Dateadd(wk,datediff(wk,0,getdate()),6) 是表示本周旉D? 下面的SQL的条仉?是查询旉D在本周范围内的: Where Time BETWEEN Dateadd(wk,datediff(wk,0,getdate()),-1) AND Dateadd(wk,datediff(wk,0,getdate()),6) 而在存储q程? select @begintime = Dateadd(wk,datediff(wk,0,getdate()),-1) select @endtime = Dateadd(wk,datediff(wk,0,getdate()),6)
数据库的设计范式是数据库设计所需要满的规范Q满些规范的数据库是z的、结构明晰的Q同Ӟ不会发生插入QinsertQ、删除(deleteQ和更新QupdateQ操作异常。反之则是ؕ七八p,不仅l数据库的编Eh员制造麻烦,而且面目可憎Q可能存储了大量不需要的冗余信息?br />
设计范式是不是很难懂呢?非也Q大学教材上l我们一堆数学公式我们当然看不懂Q也C住。所以我们很多h根本不按照范式来设计数据库?br />
实质上,设计范式用很形象、很z的话语p说清楚,道明白。本文将对范式进行通俗地说明,q以W者曾l设计的一个简单论坛的数据库ؓ例来讲解怎样这些范式应用于实际工程?br />
范式说明
W一范式Q?NFQ:数据库表中的字段都是单一属性的Q不可再分。这个单一属性由基本cd构成Q包括整型、实数、字W型、逻辑型、日期型{?br />
例如Q如下的数据库表是符合第一范式的:
字段1
字段2
字段3
字段4
而这L数据库表是不W合W一范式的:
字段1
字段2
字段3
字段4
字段3.1
字段3.2
很显Ӟ在当前的M关系数据库管理系l(DBMSQ中Q傻瓜也不可能做ZW合W一范式的数据库Q因些DBMS不允怽把数据库表的一列再分成二列或多列。因此,你想在现有的DBMS中设计出不符合第一范式的数据库都是不可能的?br />
W二范式Q?NFQ:数据库表中不存在非关键字D对M候选关键字D늚部分函数依赖Q部分函C赖指的是存在l合关键字中的某些字D决定非关键字段的情况)Q也x有非关键字段都完全依赖于L一l候选关键字?
假定选课关系表ؓSelectCourse(学号, 姓名, q龄, 评名称, 成W, 学分)Q关键字为组合关键字(学号, 评名称)Q因为存在如下决定关p:
(学号, 评名称) → (姓名, q龄, 成W, 学分)
q个数据库表不满第二范式,因ؓ存在如下军_关系Q?br />
(评名称) → (学分)
(学号) → (姓名, 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没?学号"关键字,评名称和学分也无法记录入数据库?br />
(4) 删除异常Q?br />
假设一批学生已l完成课E的选修Q这些选修记录应该从数据库表中删除。但是,与此同时Q课E名U和学分信息也被删除了。很昄Q这也会D插入异常?
把选课关系表SelectCourse改ؓ如下三个表:
学生QStudent(学号, 姓名, q龄)Q?br />
评QCourse(评名称, 学分)Q?br />
选课关系QSelectCourse(学号, 评名称, 成W)?br />
q样的数据库表是W合W二范式的,消除了数据冗余、更新异常、插入异常和删除异常?br />
另外Q所有单关键字的数据库表都符合第二范式,因ؓ不可能存在组合关键字?br />
W三范式Q?NFQ:在第二范式的基础上,数据表中如果不存在非关键字段对Q一候选关键字D늚传递函C赖则W合W三范式。所谓传递函C赖,指的是如果存?A → B → C"的决定关p,则C传递函C赖于A。因此,满W三范式的数据库表应该不存在如下依赖关系Q?br />
关键字段 → 非关键字Dx → 非关键字Dy
假定学生关系表ؓStudent(学号, 姓名, q龄, 所?a >学院, 学院地点, 学院电话)Q关键字为单一关键?学号"Q因为存在如下决定关p:
(学号) → (姓名, q龄, 所?a >学院, 学院地点, 学院电话)
q个数据库是W合2NF的,但是不符?NFQ因为存在如下决定关p:
(学号) → (所?a >学院) → (学院地点, 学院电话)
卛_在非关键字段"学院地点"?学院电话"对关键字D?学号"的传递函C赖?br />
它也会存在数据冗余、更新异常、插入异常和删除异常的情况,读者可自行分析得知?br />
把学生关p表分ؓ如下两个表:
学生Q?学号, 姓名, q龄, 所?a >学院)Q?br />
学院Q?学院, 地点, 电话)?br />
q样的数据库表是W合W三范式的,消除了数据冗余、更新异常、插入异常和删除异常?br />
鲍依?U得范式QBCNFQ:在第三范式的基础上,数据库表中如果不存在M字段对Q一候选关键字D늚传递函C赖则W合W三范式?/p>
(仓库ID, 存储物品ID) →(理员ID, 数量)
(理员ID, 存储物品ID) → (仓库ID, 数量)
所以,(仓库ID, 存储物品ID)?理员ID, 存储物品ID)都是StorehouseManage的候选关键字Q表中的唯一非关键字Dؓ数量Q它是符合第三范式的。但是,׃存在如下军_关系Q?br />
(仓库ID) → (理员ID)
(理员ID) → (仓库ID)
卛_在关键字D决定关键字D늚情况Q所以其不符合BCNF范式。它会出现如下异常情况:
(1) 删除异常Q?br />
当仓库被清空后,所?存储物品ID"?数量"信息被删除的同时Q?仓库ID"?理员ID"信息也被删除了?br />
(2) 插入异常Q?br />
当仓库没有存储Q何物品时Q无法给仓库分配理员?br />
(3) 更新异常Q?br />
如果仓库换了理员,则表中所有行的管理员ID都要修改?br />
把仓库管理关p表分解Z个关p表Q?br />
仓库理QStorehouseManage(仓库ID, 理员ID)Q?br />
仓库QStorehouse(仓库ID, 存储物品ID, 数量)?br />
q样的数据库表是W合BCNF范式的,消除了删除异常、插入异常和更新异常?
我们来逐步搞定一个论坛的数据库,有如下信息:
Q?Q?用户Q用户名QemailQ主,电话Q联pd址
Q?Q?帖子Q发帖标题,发帖内容Q回复标题,回复内容
W一ơ我们将数据库设计ؓ仅仅存在表:
用户?
email
主页
电话
联系地址
发帖标题
发帖内容
回复标题
回复内容
q个数据库表W合W一范式Q但是没有Q何一l候选关键字能决定数据库表的整行Q唯一的关键字D는户名也不能完全决定整个元l。我们需要增?发帖ID"?回复ID"字段Q即表修改为:
用户?/td>
email
主页
电话
联系地址
发帖ID
发帖标题
发帖内容
回复ID
回复标题
回复内容
q样数据表中的关键字(用户名,发帖IDQ回复ID)能决定整行:
(用户?发帖ID,回复ID) → (email,主页,电话,联系地址,发帖标题,发帖内容,回复标题,回复内容)
但是Q这L设计不符合第二范式,因ؓ存在如下军_关系Q?br />
(用户? → (email,主页,电话,联系地址)
(发帖ID) → (发帖标题,发帖内容)
(回复ID) → (回复标题,回复内容)
即非关键字段部分函数依赖于候选关键字D,很明显,q个设计会导致大量的数据冗余和操作异常?
我们数据库表分解ؓQ带下划U的为关键字Q:
Q?Q?用户信息Q用户名QemailQ主,电话Q联pd址
Q?Q?帖子信息Q发帖IDQ标题,内容
Q?Q?回复信息Q回复IDQ标题,内容
Q?Q?发脓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主,电话Q联pd址
Q?Q?帖子信息Q用户名Q发帖IDQ标题,内容
Q?Q?回复信息Q发帖IDQ回复IDQ标题,内容
数据库表1昄满所有范式的要求Q?br />
数据库表2中存在非关键字段"标题"?内容"对关键字D?发帖ID"的部分函C赖,即不满W二范式的要求,但是q一设计q不会导致数据冗余和操作异常Q?br />
数据库表3中也存在非关键字D?标题"?内容"对关键字D?回复ID"的部分函C赖,也不满W二范式的要求,但是与数据库?怼Q这一设计也不会导致数据冗余和操作异常?br />
由此可以看出Qƈ不一定要满范式的要求,对于1QN关系Q当1的一边合q到N的那边后QN的那边就不再满W二范式了,但是q种设计反而比较好Q?br />
对于MQN的关p,不能M一ҎN一边合q到另一边去Q这样会D不符合范式要求,同时D操作异常和数据冗余?
对于1Q?的关p,我们可以左边的1或者右边的1合ƈ到另一边去Q设计导致不W合范式要求Q但是ƈ不会D操作异常和数据冗余?br />
l论
满范式要求的数据库设计是结构清晰的Q同时可避免数据冗余和操作异常。这q意味着不符合范式要求的设计一定是错误的,在数据库表中存在1Q??QN关系q种较特D的情况下,合ƈD的不W合范式要求反而是合理的?br />
在我们设计数据库的时候,一定要时刻考虑范式的要求?/p>
]]>
U束是用来确保数据的准确性和一致性。数据的完整性就是对数据的准性和一致性的一U保证?br />
数据完整?Data Integrity)是指数据的精?Accuracy)和可靠?Reliability)?br />
分ؓ以下四类Q?br />
1 实体完整?/strong>Q规定表的每一行在表中是惟一的实体?br />
2 域完整性: 是指表中的列必须满某种特定的数据类型约束,其中U束又包括取D围、精度等规定?br />
3 参照完整?/strong>Q?是指两个表的d键字和外关键字的数据应一_保证了表之间的数据的一致性,防止了数据丢失或无意义的数据在数据库中扩散?br />
4 用户定义的完整?/strong>Q?不同的关pL据库pȝҎ其应用环境的不同Q往往q需要一些特D的U束条g。用户定义的完整性即是针Ҏ个特定关pL据库的约束条Ӟ它反映某一具体应用必须满的语义要求?br />
2 完整性约束的cdQ?br />
可分ZU类型:与表有关的约束、域(Domain)U束、断a(Assertion)
1 与表有关的约? 是表中定义的一U约束。可在列定义时定义该U束Q此时称为列U束Q也可以在表定义时定义约束,此时UCؓ表约束?br />
2 ?Domain)U束Q?/strong> 在域定义中被定义的一U约束,它与在特定域中定义的M列都有关pR?br />
3 断言(Assertion)Q?/strong>在断a定义时定义的一U约束,它可以与一个或多个表进行关联?br />
一?与表有关的约束:包括列约?表约?NOT NULL)和表U束(PRIMARY KEY、foreign key、check、UNIQUE) ?br />
(1) not nullQ非I?U束Q?/strong> 只用于定义列U束?br />
语法如下Q?br />
Colunm_name datatype | domain not null
实例Q?br />
create table Employee
(
emp_id int not null,
emp_name varchar(10) not null,
address varchar(40) ,
)
创徏之后Q如果往表Employee表中非空U束中插入空|insert into Employee values(1,null,'neimeng')会出错。如下:
Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into column 'emp_name', table 'Student.dbo.Employee';
column does not allow nulls. INSERT fails.
The statement has been terminated.
(2) unique(惟一)U束Q用于指明创建惟一U束的列上的取值必L一?br />
语法如下Q?br />
Colunm_name datatype | domain unique
实例Q?br />
create table EmployeeInfo
(
emp_id int not null,
emp_name varchar(10) not null,
phone char(11) unique,
address varchar(40) ,
)
如下往EmployeeInfo插入数据Ӟ如果两条记录的phone不惟一Q?br />
insert into EmployeeInfo values(1,'abcdwxc','neimeng','13612345678')
insert into EmployeeInfo values(2,'terry','neimeng','13612345678')
则会出现错误。如下:
(1 row(s) affected)
Msg 2627, Level 14, State 1, Line 2
Violation of UNIQUE KEY constraint 'UQ__EmployeeInfo__060DEAE8'. Cannot insert duplicate key in object 'dbo.EmployeeInfo'.
The statement has been terminated.
除了在定义列时添加uniqueU束外,也可以将uniqueU束作ؓ表约束添加。即把它作ؓ表定义的元素?br />
语法如下Q?br />
[CONSTRAINT constraint_name] unique (column1,column2,.....)
实例Q?br />
create table EmployeeInfo
(
emp_id int not null,
emp_name varchar(10) not null,
phone char(11)
address varchar(40) ,
constraint p_uniq unique(phone)
)
(3) primary key(主键)U束Q?/strong>用于定义基本表的主键Qv惟一标识作用Q其g能ؓnull,也不能重复,以此来保证实体的完整性?br />
语法如下Q?br />
Colunm_name datatype | domain primary key
实例Q?nbsp;
(
emp_id int primary key,
emp_name varchar(10) not null,
phone char(11),
address varchar(40) ,
)
如果向EmployeeInfo表插入的emp_id重复了或者插入时emp_id为null|则会出错?br />
可以在创Ӟ创徏主键U束Q也可创完成以后Q创Z键,例如Q?br />
alter table EmployeeInfo
add constraint e_prim primary key(emp_id)
primary key ?unique的区别:
1.在一个表中,只能定义一个primary keyU束Q但可定义多个uniqueU束?br />
2.对于指定为primary key的一个列或多个列的组合,其中M一个列都不能出现空|而对于unique所U束的惟一键,则允ؓnull,只是null值最多有一个?br />
(4) foreign key(外键)U束Q定义了一个表中数据与另一个表中的数据的联pR?br />
foreign keyU束指定某一个列或一l列作ؓ外部键,其中包含外部键的表称为子表,包含外部键所引用的主键的表称为父表。系l保证,表在外部键上的取D么是父表中某一主键Q要么取I|以此保证两个表之间的q接Q确保了实体的参照完整性?br />
语法如下Q?br />
Colunm_name datetype | domain references table_name(column)
[match full|partial|simple] //注:sqlserver不支持?br />
[referential triggered action]
说明Qtable_name为父表的表名Qcolumn为父表中与外键对应的主键倹{?br />
[match full|partial|simple]为可选子句,用于讄如何处理外键中的null倹{?br />
[referential triggered action]也ؓ可选子句,用于讄更新、删除外键列时的操作准则?br />
可以的一列或多列创徏foreign key U束Q如果ؓ多列创徏 foreign keyU束Q将分别与主表中的相应主键相对应?br />
实例Q?br />
create table EmployeeInfo
(
emp_id int primary key,
emp_name varchar(10) not null,
account char(4) primary key,
phone char(11)
address varchar(40) ,
)
create table Emp_Sal
(
emp_id int , account CHAR(4) ,salary DECIMAL(5,1),
CONSTRAINT E_SAL FOREIGN KEY(emp_id,account) REFERENCES EmployeeInfo (emp_id,account))
)
也可以表创徏以后d到表上。如下:
create table Emp_Sal
(
emp_id int ,emp_name varchar(10) not null, account CHAR(4) ,salary DECIMAL(5,1),
)
alter table Emp_Sal
add CONSTRAINT E_SAL FOREIGN KEY(emp_id,account) REFERENCES EmployeeInfo (emp_id,account)
该外键的作用Q确保表Emp_Sal的每个emp_id列都对应表EmployeeInfo中相应的emp_id。此Ӟ表EmployeeInfo为父表,而表Emp_Sal为子表。子表的emp_id列参照父表的emp_id列?br />
如果惛_子表的emp_id列插入一个|首先父表的emp_id列必d在,否则会插入失败。如果想从父表的emp_id删除一个|则必L删除子表emp_id列中所有与之对应的倹{?br />
(?foreign key 列上的取值可以取null)?
潜在问题Q由于foreign key列上可以取空?DBMS蟩q对foreign keyU束的检查,因此如果插入Emp_Sal如下数据Q?br />
insert into Emp_Sal values(6,null,null) 则插入到Emp_Sal中,但其主表的相兛_却不存在?br />
解决办法Q?/strong>
Q?Q将联合外键的列dnot nullU束Q但q限制了用户的部分操作?br />
Q?Q采用Match子句?sqlserver不支?.
更新、删除操作规则:
在删除或更新有primary key值的行,且该g子表的foreign key中一个或多个值相匚wӞ会引起匹配完整性的丧失?br />
在foreign key创徏语法中,提供了可选的on update和on delete子句Q也是上面的[referential triggered action]。可用此保持引用完整性?br />
on update / on delete
no action|cascade|restrict|set null|set default
no action:更新或删除父表中的数据时Q如果会使子表中的外键违反引用完整性,该动作将被禁止执行。不q在某些条g下,可出现暂时的Q但在数据的最l状态中Q不能违反外键的引用完整性?br />
cascade: 当父表中被引用列的数据被更新或删除时Q子表中的相应的数据也被更新或删除?br />
restrict:与no action规则基本相同Q只是引用列中的数据永远不能q反外键的引用完整性,暂时的也不行?br />
set null:当父表数据被更新或删除时Q子表中的相应数据被讄成Null|前提是子表中的相应列允许null倹{?br />
set default:当父表数据被更新或删除时,子表中的数据被设|成默认倹{前提是子表中的相应列设|有默认倹{?br />
(5) checkQ校验)U束Q?/strong>用来查字D值所允许的范围。DBMS每当执行delete,insert或update语句Ӟ都对q个U束qo。如果ؓtrueQ则执行。否则,取消执行q提C错误?br />
列定义语法如下:
Column datetype | domain check(search condition)
表约束语法如下:
constraint constraint_name check(search condition)
实例如下Q?br />
create table Emp_Sal
(
emp_id int , account CHAR(4) ,salary DECIMAL(5,1),
constraint validsal check(salary >=1000 and salary<=10000)
)
如果此时Q再往表中插入如下语句则会出错Q?因ؓ不满salary大于{于1000的约束?
insert into Emp_Sal values(8,'12324343',800.0)
二?域约束:(sqlserver 不支?
语法如下Q?br />
create domain domain_name as data type
[default default_value]
[constraint constraint_name] check(value condition expression)
例如Q?br />
create domain valid_no as int
constraint constraint_no check(value between 100 and 999)
然后创徏表时Q用valid_no域?br />
create table TestDomain
(
emp_id valid_no,
emp_name varchar(10),
)
三、断aU束Q?/strong>不必与特定的列绑定,可以理解应用于多个表的checkU束Q因此必d表定义之外独立创建断a?br />
语法如下Q?br />
create assertion constraint_name
check search condition
例如Q?br />
create assertion name
check (Emp_Sal.emp_id in(select emp_id from EmployeeInfo where emp_name is not null)
d断言后,每当试图d或修改Emp_Sal表中的数据时Q就Ҏa中的搜烦条g求|如果为falseQ则取消执行Q给出提C?br />
]]>
]]>
]]>
Oracle 9i的标量数据类型名U?nbsp; 含义
Char 用于描述定长的字W型数据Q长?lt;=2000字节
varchar2 用于描述变长的字W型数据Q长?lt;=4000字节
nchar 用来存储Unicode字符集的定长字符型数据,长度<=1000字节
nvarchar2 用来存储Unicode字符集的变长字符型数据,长度<=1000字节
number 用来存储整型或者Q点型数?br />
Date 用来存储日期数据
Long 用来存储最大长度ؓ2GB的变长字W数?
Raw 用来存储非结构化数据的变长字W数据,长度<=2000字节
Long raw 用来存储非结构化数据的变长字W数据,长度<=2GB
rowid 用来存储表中列的物理地址的二q制数据Q占用固定的10个字?
Blob 用来存储多达4GB的非l构化的二进制数?
Clob 用来存储多达4GB的字W数?
nclob 用来存储多达4GB的Unicode字符数据
Bfile 用来把非l构化的二进制数据存储在数据库以外的操作pȝ文g?br />
urowid 用来存储表示Mcd列地址的二q制数据
float 用来存储点?nbsp;