第3 章 数据库定义与更新 SQL语言由4部分组成:数据定义语言DDL、数据操纵语言DML、数据控制语言 DCL和其他,其功能如下: (1)数据定义语言(DataDefinitionLanguage,DDL):主要用于定义数据库的逻辑结 构,包括定义数据库、基本表、视图和索引等,扩展的DDL还包括存储过程、函数、对象、触 发器等的定义。 (2)数据操纵语言(DataManipulationLanguage,DML):主要用于对数据库中的数 据进行检索和更新两大类操作,其中更新操作包括插入、删除和修改数据。 (3)数据控制语言(DataControlLanguage,DCL):主要用于对数据库中的对象进行 授权、用户维护(包括创建、修改和删除)、完整性规则定义和事务定义等。 (4)其他:主要是嵌入式SQL语言和动态SQL语言的定义,规定了SQL语言在宿 主语言中使用的规则。扩展的SQL还包括数据库数据的重新组织、备份与恢复等。 3.1 相关知识 在SQLServer2019中,数据库对象包括表、视图、触发器、存储过程、规则、默认值、 用户自定义的数据类型等。 SQLServer的DDL是指用来定义和管理数据库以及数据库中的各种对象的语句, 这些语句包括CREATE、ALTER和DROP等语句。 SQLServer的DML是指用来查询、添加、修改和删除数据库中数据的语句,这些语 句包括SELECT、INSERT、UPDATE、DELETE 等。在默认情况下,只有sysadmin、 dbcreator、db_Owner或db_Datawriter等角色的成员才有权利执行数据操纵语言。 3.1.1 数据库定义语句 本节主要讨论数据库的定义功能。 1.创建数据库 创建数据库的语法如下: CREATE DATABASE database_name [ON [PRIMARY]] ( [NAME =logical_file_name, ] 第3 章 数据库定义与更新 93 FILENAME ='os_file_name' [, SIZE =size] [, MAXSIZE ={max_size | UNLIMITED} ] [, FILEGROWTH =growth_increment]) [, …n]) [LOG ON] ( [NAME =logical_file_name, ] FILENAME ='os_file_name' [, SIZE =size] [, MAXSIZE ={max_size | UNLIMITED} ] [, FILEGROWTH =growth_increment]) [, …n]) 其中, ● database_name:被创建的数据库的名字。 ● ON:用于指定存储数据库中数据的磁盘文件,除PRIMARY 文件组外,用户可定 义用户的文件组及相关的用户文件。 ● PRIMARY:描述在主文件组中定义的相关文件,所有的数据库系统表存放在 PRIMARY文件组中,同时也存放没有分配具体文件组的对象。在主文件组中第 一个文件称为主文件,通常包括数据库的系统表。对于一个数据库来说,只能有一 个PRIMARY文件组。如果主文件组没有指明,则创建数据库时所描述的第一个 文件将作为主文件组成员。 ● LOGON:用来指明存储数据库日志的磁盘文件。如果没有指定LOG ON,系统 将自动创建单个的日志文件,使用系统默认的命名方法。 创建数据库的注意事项: ① 默认情况下,只有系统管理员可以创建新数据库,但是系统管理员可以通过授权 将创建数据库的权限授予其他用户。 ② 数据库名字必须遵循SQLServer命名规范: ● 字符的长度可以为1~30。 ● 名称的第一个字符必须是一个字母或者是下列字符中的某一个:下画线“_”或符 号@。 ● 在首字母后的字符可以是字母、数字或者前面规则中提到的符号。 ● 名称中不能有空格。 ③ 所有的新数据库都是model数据库的副本,新数据库不可能比model数据库当前 的容量更小。 ④ 单个数据库可以存储在单个文件上,也可以跨越多个文件存储。 ⑤ 数据库的大小可以被扩展或者收缩。 ⑥ 当新的数据库创建时,SQLServer自动地更新master数据库的sysdatabases系 统表。 2.修改数据库 创建数据库后如果想对其定义进行修改,例如增删数据文件、增删文件组等,可以使 用ALTERDATABASE语句处理。 修改数据库的语法如下: 94 数据库系统原理与设计实验教程(第4 版) ALTER DATABASE database_name { ADD FILE [, …n][TO FILEGROUP filegroup_name] | ADD LOG FILE [, …n] | REMOVE FILE logical_file_name | ADD FILEGROUP filegroup_name | REMOVE FILEGROUP filegroup_name | MODIFY FILE | MODIFY FILEGROUP filegroup_name filegroup_property } 其中, ● database_Name:被修改的数据库的名字。 ● ADDFILE:指定添加到数据库中的数据文件。 ● TOFILEGROUPfilegroup_name:指定文件添加到文件组名为filegroup_name 的文件组。 ● ADDLOGFILE:指定添加到数据库中的日志文件。 ● REMOVEFILE:从数据库系统表中删除该文件,并且物理删除该文件。 ● ADDFILEGROUP:指定添加到数据库的文件组。 ● filegroup_name:文件组名。 ● REMOVEFILEGROUP:从数据库中删除该文件组,并删除在这个文件组中的 文件。 ● MODIFYFILE:指定要修改的文件。包含该文件的名称、大小、增长量和最大 容量。 注意:一次只可以修改其中的一个选项。 3.删除数据库 删除数据库的语法如下: DROP DATABASE database_name 删除数据库将删除数据库所使用的数据库文件和磁盘文件。 3.1.2 表定义语句 本节主要讨论关系表的定义功能。 1.创建表 创建表的语法如下: CREATE TABLE ( [DEFAULT ][NULL | NOT NULL][, [DEFAULT ][NULL | NOT NULL]… ] [, [CONSTRAINT ]{UNIQUE | PRIMARY KEY} ([, … ]) [, … n ]] [, [CONSTRAINT ] FOREIGN KEY ([, … ]) 第3 章 数据库定义与更新 95 REFERENCE [.owner.] ([, … ]) [, … n ]] ) [ON ] 其中, ● tableName:新表的名称,表名必须符合标识符规则。 ● columnName:表中的列名,列名必须符合标识符规则,并且在表内唯一。 ● dateType:列的数据类型。 ● default:为列设置默认值,属于可选项。 ● NULL|NOTNULL:为列设置是否允许为空值,属于可选项。 ● :定义约束的名字,属于可选项。 ● UNIQUE:建立唯一索引。 ● PRIMARYKEY:建立主码。 ● FOREIGNKEY:建立外码。 ● ONfilegroupName:指定该表属于哪个文件组。 2.修改表结构 修改表结构的语法如下: ALTER TABLE [database_owner].table_name (ADD column_name datatype, ...... ADD CONSTRAINT …, DROP CONSTRAINT ..., REPLACE column_name DEFAULT expression ) 3.删除表 删除表的语法如下: DROP TABLE table_name 3.1.3 索引与视图定义语句 本节主要讨论索引、视图的定义功能。 1.创建视图 在创建视图前需考虑如下原则。 (1)只能在当前数据库中创建视图。 (2)视图名称必须遵循标识符的规则,且对每个用户必须唯一,该名称不得与该用户 拥有的任何表的名称相同。 (3)可以在其他视图上建立视图。 (4)不能将规则或DEFAULT定义与视图相关联。 (5)定义视图的查询不可以包含ORDERBY、COMPUTE或COMPUTEBY 子句 或INTO 关键字。 96 数据库系统原理与设计实验教程(第4 版) (6)不能在视图上定义全文索引。 (7)不能创建临时视图,也不能在临时表上创建视图。 (8)下列情况下必须在视图中指定每列的名称: ① 视图中有任何从算术表达式、内置函数或常量派生出的列。 ② 视图中两列或多列具有相同名称。 ③ 希望使视图中的列名与它的源列名不同,可在视图中重新命名列。无论重命名与 否,视图列都会继承其源列的数据类型。 创建视图的语法如下: CREATE VIEW [.][.]view_name [(column [, …n])] [WITH [, …n]] AS select_statement [WITH CHECK OPTION ] ::={ encryption | schemabinding | view_metadata } 其中, ● view_name:视图的名称,视图名称必须符合标识符规则。 ● column:视图中的列名。当列是从算术表达式、函数或常量派生的,或两个或更多 的列可能会具有相同的名称(如连接),或视图中的某列被赋予了不同于派生来源 列的名称时必须指定列名。如果未指定column,则视图列将获得与SELECT 语 句中的列相同的名称。 ● n:表示可以指定多列的占位符。 ● select_statement:定义视图的SELECT语句。 ● WITHCHECKOPTION:表示当对视图进行更新操作时必须满足视图定义的谓 词条件。 2.修改视图 尽量不要对视图进行更新操作,同时注意以下方面: ① 若建立视图时用了连接和分组,或DISTICT,或内部函数则不能对视图进行 INSERT、UPDATE和DELETE操作。 ② 若视图中的列直接由基本表得到,而不是由price*10这样的表达式组成的列可 执行UPDATE操作。 修改视图的语法如下: ALTER VIEW [.][.]view_name [(column [, …n]) ] [WITH [, …n]] AS select_statement [WITH CHECK OPTION ] 3.删除视图 如果不需要某视图,可以删除该视图。删除视图后,视图所基于的数据并不受到 影响。 第3 章 数据库定义与更新 97 删除视图的语法如下: DROP VIEW view_name [, …n] 4.创建索引 当为表建立主键和唯一约束时,SQLServer自动创建唯一索引。如果表中不存在聚 集索引,则为主键创建一个唯一的聚集索引。默认情况下对UNIQUE 约束创建唯一的 非聚集索引。 创建索引时须考虑的事项是: ① 只有表的所有者可以在同一个表中创建索引。 ② 每个表只能创建一个聚集索引。 ③ 每个表可以创建的非聚集索引最多为249个(包括PRIMARYKEY或UNIQUE 约束创建的索引)。 ④ 包含索引的所有长度固定列的最大大小为900字节。 ⑤ 包含同一索引的列的最大数目为16。 创建索引的语法如下: CREATE [UNIQUE][CLUSTERED | NONCLUSTERED] INDEX index_name ON {TABLE | VIEW} (column [ASC | DESC][, …n]) [ON filegroup] 其中, ● UNIQUE:为表或视图创建唯一索引,聚集索引必须是UNIQUE索引。 ● CLUSTERED:创建聚集索引,如果没有指定CLUSTERED,则创建非聚集索引。 ● NONCLUSTERED:创建非聚集索引。 ● index_name:索引名,索引名必须遵循标识符规则。 ● TABLE:要创建索引的表。 ● VIEW:要建立索引的视图的名称。 ● column:应用索引的列。 ● ONfilegroup:在给定的filegroup上创建指定的索引。该文件组必须已经通过执 行CREATEDATABASE或ALTERDATABASE创建。 5.删除索引 删除索引的语法如下: DROP INDEX index[, …n]ON 或者, DROP INDEX tableName.index | viewName.index [, …n] 其中, ● tableName.index|viewName.index:要删除的表或视图的索引名称。 ● n:表示可以指定多个索引的占位符。 98 数据库系统原理与设计实验教程(第4 版) ● ON:指定表名或视图名。 3.1.4 表记录更新语句 DML语句包括查询、插入、修改和删除数据库中的数据等操纵语句,即SELECT、 INSERT、UPDATE、DELETE 等。本节主要讨论数据库对象的INSERT、UPDATE、 DELETE功能。 1.插入数据 插入数据的语法如下: INSERT [INTO]table_name/view_name [(column_list)] VALUES {DEFAULT | NULL | expression} 其中, ● table_name/view_name:表名/视图名。 ● column_list:由逗号分隔的列名列表,用来指定为其提供数据的列。如果没有指 定column_list,表中的所有列都将接收数据。 没有包含在column_list的列,将在该列插入一个NULL值(或者该列定义的默认 值)。 由于SQLServe为以下类型的列自动生成值,INSERT语句将不为这些类型的列指 定值:① 具有identity属性的列,该属性为列生成值。 ② 有默认值的列,该列用newid函数生成一个唯一的guid值。 ③ 计算列。 所提供的数据值必须与列的列表匹配。数据值的数目必须与列数相同。 2.修改数据 修改数据的语法如下: UPDATE table_name/view_name SET column_name =expression | DEFAULT | NULL [FROM [, …n]] [WHERE ] 其中, ● table_name/view_name:需要更新的表/视图的名称。 ● column_name:要更改数据的列名。 ● expression:返回的值将替换column_name的现有值。 ● DEFAULT:指定使用对列定义的默认值替换列中的现有值。 ● FROM :指定用表来为更新操作提供准则。 ● WHERE :指定条件来限定所更新的行。 3.删除数据 删除数据的语法如下: 第3 章 数据库定义与更新 99 DELETE FROM [WHERE ] 其中, ● table_name/view_name:要删除记录的表名/视图名。 ● WHERE :指出被删除的记录所满足的条件,若省略,表示 删除表中的所有记录。 关于视图的操作(INSERT、DELETE、UPDATE),应注意以下几个问题: ① 若建立视图时用了连接和分组,DISTINCT 或内部函数则不能对视图进行 INSERT和DELETE操作。 ② 若视图中的列直接由基本表得到,而不是计算列就可执行UPDATE操作。 ③ 对视图插入元组时应注意对NOTNULL字段的处理。 ④ 若视图由多表连接而成,对视图插入元组时应分别对同一张表中的字段插入元组。 ⑤ 尽量不要对视图进行更新操作。 3.2 实验七:数据库与数据表定义 3.2.1 实验目的与要求 (1)掌握数据库的建立、删除和修改操作。 (2)理解基本表之间的关系,掌握表结构的建立、修改和删除操作,创建模式导航图。 3.2.2 实验案例 1.数据库创建与删除 【例3.1】 创建一个myorder数据库,该数据库的主要文件为myorder.mdf,事务日 志为myorderLog.ldf,它们都位于e:\mySQL目录下。 SQL语句如下: CREATE DATABASE myorder ON ( NAME='myorder', FILENAME='e:\mySQL\myorder.mdf', SIZE=3, MAXSIZE=50, FILEGROWTH=1 ) LOG ON ( NAME='myorderLog', FILENAME='e:\mySQL\myorderLog.ldf', SIZE=3, MAXSIZE=20, FILEGROWTH=1 ) 本例中,myorder数据库只有一个主逻辑设备,对应一个物理文件myorder.mdf,该 文件初始大小3MB,最大可扩展为50MB,如果初始文件装不下数据,自动按1MB进行扩 1 00 数据库系统原理与设计实验教程(第4 版) 展,直到50MB为止。日志文件为myorderLog.ldf,该文件初始大小3MB,最大可扩展为 20MB,如果初始文件装不下数据,自动按1MB进行扩展。 【例3.2】 建立一个复杂的数据库tmyorder。 SQL语句如下: CREATE DATABASE tmyorder ON PRIMARY ( NAME='tmyorder', FILENAME='e:\mySQL\tmyorder.mdf', SIZE=100, MAXSIZE=300, FILEGROWTH=1%), ( NAME='tmyorder2', FILENAME='e:\temp\tmyorder2.ndf', SIZE=50, FILEGROWTH=2 ), ( NAME='tmyorder3', FILENAME='e:\temp\ tmyorder3.ndf', SIZE=50, FILEGROWTH=2 ), FILEGROUP temorder ( NAME='temorder', FILENAME='e:\temp\temorder.mdf', SIZE=6, MAXSIZE=10, FILEGROWTH=2 ) LOG ON ( NAME='tmyorderLog', FILENAME='e:\mySQL\tmyorderLog.ldf', SIZE=100, MAXSIZE=500, FILEGROWTH=2%) 在本例中,该数据库由4个数据文件和1个日志文件组成。主设备有1个主要文件 tmyorder.mdf和2个次要文件tmyorder2、tmyorder3组成,用户设备有1个文件temorder.mdf, 日志有1个文件tmyorderLog.ldf。 【例3.3】 删除数据库tmyorder。 SQL语句如下: DROP DATABASE tmyorder 2.创建表 【例3.4】 创建一张客户表(客户编号、客户姓名、客户电话、客户地址、邮政编码)。 SQL语句如下: CREATE TABLE Customer ( customerNo char(9) NOT NULL PRIMARY KEY, /*客户编号*/ customerName varchar(40) NOT NULL, /*客户名称*/ telephone varchar(20) NOT NULL, /*客户电话*/ address char(40) NOT NULL, /*客户住址*/ zip char(6) NULL /*邮政编码*/ 第3 章 数据库定义与更新1 01 ) 【例3.5】 建立一张员工表(员工编号、员工姓名、员工性别、员工生日、员工住址、员 工电话、雇用日期、所属部门、职称、薪水)。 SQL语句如下: CREATE TABLE Employee ( employeeNo char(8) NOT NULL PRIMARY KEY, /*员工编号*/ employeeName varchar(10) NOT NULL, /*员工姓名*/ sex char(1) NOT NULL, /*员工性别*/ birthday datetime NULL, /*员工生日*/ address varchar(50) NULL, /*员工住址*/ telephone varchar(20) NULL, /*员工电话*/ hireDate datetime NOT NULL, /*雇用日期*/ department varchar(30) NOT NULL, /*所属部门*/ title varchar(6) NOT NULL, /*职称*/ salary numeric(8,2) NOT NULL /*薪水*/ ) 【例3.6】 建立一张订单表(订单编号、客户编号、业务员编号、订货日期、订单金额、 发票号码),要求给该表建立主键约束和关于员工表和客户表的外键约束。 SQL语句如下: CREATE TABLE OrderMaster ( orderNo char(12) NOT NULL PRIMARY KEY, /*订单编号*/ customerNo char(9) NOT NULL, /*客户编号*/ salerNo char(8) NOT NULL, /*业务员编号*/ orderDate datetime NOT NULL, /*订货日期*/ orderSum numeric(9,2) NOT NULL, /*订单金额*/ invoiceNo char(10) NOT NULL, /*发票号码*/ CONSTRAINT OrdermasterFK1 FOREIGN KEY(customerNo) REFERENCES Customer(customerNo), CONSTRAINT OrdermasterFK2 FOREIGN KEY(salerNo) REFERENCES Employee(employeeNo) ) 3.2.3 实验内容 (1)创建一个BookDB数据库,要求至少有一个数据文件和一个日志文件。 (2)创建图书借阅管理相关5张关系表,表结构如表3-1~表3-5所示。 表3-1 图书分类表BookClass 属性名类 型空值约束属性含义 classNo char(4) NOTNULL 图书分类号 className varchar(20) NOTNULL 图书分类名称 102 数据库系统原理与设计实验教程(第 4 版) 表3- 2 图书表Bok 属性名类型空值约束属性含义 bookNo char(10) NOTNULL 图书编号 clasNo char(4) NOTNULL 分类号 bookName varchar(40) NOTNULL 图书名称 authorName varchar(8) NOTNULL 作者姓名 publisherNo char(4) NOTNULL 出版社号 price numeric(7,2) NULL 单价 publishingDate datetime NULL 出版日期 shopDate datetime NULL 入库时间 shopNum numeric(3) NULL 入库数量 表3- 3 读者表Reader 属性名类型空值约束属性含义 readerNo char(8) NOTNULL 读者编号 readerName varchar(8) NOTNULL 姓名 sex char(2) NULL 性别 identifycard char(18) NULL 身份证号 workUnit varchar(50) NULL 工作单位 borowCount tinyint NULL 读者最大可借书数量 表3- 4 出版社表Publisher 属性名类型空值约束属性含义 publisherNo char(4) NOTNULL 出版社编号 publisherName varchar(20) NOTNULL 出版社名称 表3- 5 借阅表Borow 属性名类型空值约束属性含义 readerNo char(8) NOTNULL 读者编号 bookNo char(10) NOTNULL 图书编号 borowDate datetime NOTNULL 借阅日期 shouldDate datetime NOTNULL 应归还日期 returnDate datetime NULL 归还日期 第3 章 数据库定义与更新1 03 3.3 实验八:索引与视图定义 3.3.1 实验目的与要求 (1)掌握索引的建立和删除操作。 (2)掌握视图的创建和查询操作。 3.3.2 实验案例 1.创建索引 【例3.7】 在员工表中按生日建立一个非聚簇索引birthdayIdx。 SQL语句如下: CREATE NONCLUSTERED INDEX birthdayIdx ON Employee(birthday) 【例3.8】 在订单主表中,首先按订单金额的降序,然后按客户编号的升序建立一个 非聚簇索引sumcustIdx。 SQL语句如下: CREATE INDEX sumcustIdx ON OrderMaster(orderSum DESC, customerNo) 【例3.9】 在订单主表中按发票号码创建一个唯一性索引uniqincoiceIdx。 SQL语句如下: CREATE UNIQUE INDEX uniqincoiceIdx ON OrderMaster(invoiceno) 【例3.10】 删除birthdayIdx索引。 SQL语句如下: DROP INDEX birthdayIdx ON Employee 2.定义视图 【例3.11】 建立一个女员工的视图,要求显示员工编号、姓名、性别和薪水。 SQL语句如下: CREATE VIEW emp_view AS SELECT employeeNo, employeeName, sex, salary FROM Employee WHERE sex='f' 【例3.12】 创建一个视图,要求查询每个员工的订单号、员工编号、员工姓名、订单金 额、发票号码等信息。 SQL语句如下: CREATE VIEW emp_ordermast AS SELECT orderNo, employeeNo, employeeName, orderSum, invoiceno 1 04 数据库系统原理与设计实验教程(第4 版) FROM Employee, OrderMaster WHERE employeeNo=salerNo 【例3.13】 修改emp_view视图,要求视图只显示薪水3000元以上的女员工信息。 SQL语句如下: ALTER VIEW emp_view AS SELECT employeeNo, employeeName, sex, salary FROM Employee WHERE sex='f' AND salary>3000 【例3.14】 删除视图emp_view。 SQL语句如下: DROP VIEW emp_view 3.3.3 实验内容 (1)根据基本表创建以下索引: ● 在图书表中按出版社号建立一个非聚集索引PublishingnoIdx。 ● 在读者表中按身份证号建立一个非聚集索引IdentifycardIdx。 ● 在读者表中,首先按工作单位的升序,然后按最大借书数量降序建立一个非聚集索 引WorkunitCountIdx。 (2)创建一个图书名称中含有“数据”的图书视图BookView。 (3)创建一个包含读者编号、读者姓名、图书编号、图书名称、借阅日期、归还日期的 视图BorrowView。 (4)创建一个视图,要求显示至少借阅了3本书的读者信息ReaderView。 (5)在视图BorrowView中查询2016年3月1日以前借阅的图书。 (6)在视图ReaderView中查询姓张的读者信息。 (7)在视图BorrowView基础上再建一个只包含“合生元有限公司”的读者所借图书 信息的视图BorrowView1。 (8)删除视图BorrowView。 3.4 实验九:数据更新操作 3.4.1 实验目的与要求 (1)掌握基本表的INSERT、UPDATE、DELETE操作。 (2)正确理解更新操作中涉及的相关约束问题。 3.4.2 实验案例 【例3.15】 在客户表中插入一条信息(C20220004,双良股份有限公司,0510- 第3 章 数据库定义与更新1 05 3566021,江阴市,214400)。 SQL语句如下: INSERT Customer VALUES('C20220004', '双良股份有限公司', '0510-3566021', '江阴市 ', '214400') 【例3.16】 删除1987年以前出生的员工记录。 SQL语句如下: DELETE FROM Employee WHERE year(Birthday)<1987 【例3.17】 删除E2020002业务员的订单明细信息。 SQL语句如下: DELETE FROM OrderDetail WHERE orderNo IN ( SELECT orderNo FROM OrderMaster WHERE salerNo='E2020002' ) 【例3.18】 在客户表中把C20220003客户的客户名称改为西湖商厦,电话改为 021-6800000。 SQL语句如下: UPDATE Customer SET customerName='西湖商厦',Telephone='021-6800000' WHERE customerNo='C20220003' 【例3.19】 在OrderMaster表中找出E2020003业务员的订单,将这些订单对应的 每一项销售商品的单价打8折。 SQL语句如下: UPDATE OrderDetail SET price=price*0.8 WHERE orderNo IN ( SELECT orderNo FROM OrderMaster WHERE salerNo='E2020003' ) 3.4.3 实验内容 根据BookDB中5张关系表,完成以下更新操作: (1)分别给这5张表添加信息,要求在图书分类表、图书表、出版社表、读者表中各插 入5个元组,在借阅表中插入20个元组。 (2)将“合生元有限公司”的读者工作单位修改为“联合立华股份有限公司”。 (3)将入库数量最多的图书单价下调5%。 (4)将“经济类”的图书单价提高10%。 106 数据库系统原理与设计实验教程(第 4 版) (5)将借阅次数高于2次的图书数量增加50% 。 (6)将“兴隆股份有限公司”读者的借书期限延长为3个月。 (7)将至少借了20 次书且每次正常还书的读者的最大可借图书数量增加5。 (8)删除价格超过30 元的图书借阅信息。 (9)删除借阅了大学英语的借阅记录。 (10)删除从未借过书的读者。 第4 章 数据库安全性与完整性 数据库的安全性是指保护数据库以防止不合法的使用所造成的数据泄密、更改或 破坏。数 据库的完整性约束是指数据的正确性与相容性,是为了防止数据库存在不符合语 义的数据。 4.1 相关知识 4.1.1 数据库安全性 SQLServer的安全管理机制是架构在认证和权限两大机制下。认证是指用户必须 要有一个登录账号和密码来登录SQLServer,只有登录后才有访问和使用SQLServer 的基本资格,且只能处理SQLServer特定的管理工作。而数据库内的所有对象的访问权 限必须通过权限设置来决定登录者是否拥有某一对象的访问权限。在数据库内可以创建 多个用户,然后针对具体对象将对象的创建、读取、修改、删除等权限授予特定的数据库 用户。 1.登录账号的管理 登录(亦称Login用户)是通过账号和口令访问SQLServer的数据库。登录SQL Server服务器时,SQLServer有3个默认的用户登录账号:sa、builtin\administrators和 域名\administrator。 (1)sa:SQLServer系统管理员登录账号,该账号拥有最高管理权限,可以执行服务 器范围内的所有权限。 (2)builtin\administrators:一个Windows组账号,凡属于该组的用户账号都可以作 为SQLServer登录账号使用。 (3)域名\administrator:一个Windows用户账号,允许作为SQLServer登录账号 使用。 2.数据库用户的管理 在数据库中,一个用户或工作组取得合法的登录账号,只表明该账号通过了 WindowsNT认证或者SQLServer认证,但不能表明其可以对数据库数据和数据库对象 进行某种或者某些操作,只有当其同时拥有了用户账号后,才能够访问数据库。 数据库用户包括如下。 108 数据库系统原理与设计实验教程(第 4 版) (1)dbo用户:数据库拥有者或数据库创建者,dbo在其所拥有的数据库中拥有所有 操作权限。dbo的身份可被重新分配给另一个用户,系统管理员sa可作为其所管理的任 何数据库的dbo用户。 (2)guest用户:如果guest用户在数据库存在,则允许任意一个登录用户作为guest 用户访问数据库,其中包括那些不是数据库用户的SQL 服务器用户。除系统数据库 master和临时数据库tempdb 的guest用户不能被删除外,其他数据库都可以将自己 uest用户删除,以防止非数据库用户的登录用户对数据库进行访问。g(3)新建的数据库用户:用户根据实际需要创建不同权限的数据库用户。 3. 数据库角色的管理 利用角色,SQLServer管理者可以将某些用户设置为某一角色,这样只对角色进行 权限设置便可以实现对所有用户权限的设置,大大减少了管理员的工作量。SQLServer 提供了一些预定义的服务器角色和数据库角色。 (1)服务器角色是指根据SQLServer的管理任务,以及这些任务相对的重要性等级 来把具有SQLServer管理职能的用户划分为不同的用户组,每一组所具有的管理SQL Server的权限都是SQLServer内置的,即不能对其进行添加、修改和删除,只能向其中加 入用户或者其他角色。 (2)数据库角色是为某一用户或某一组用户授予不同级别的管理或访问数据库以及 数据库对象的权限,这些权限是数据库专有的,并且还可以使一个用户具有属于同一数据 库的多个角色。SQLServer提供了两种类型的数据库角色:固定的数据库角色和用户 自定义的数据库角色。 (3)用户自定义角色:创建用户定义的数据库角色就是创建一组用户,这些用户具 有相同的一组权限。如果一组用户需要执行在SQLServer中指定的一组操作并且不存 在对应的WindowsNT 组,或者没有管理WindowsNT 用户账号的许可,就可以在数据 库中建立一个用户自定义的数据库角色。 用户自定义的数据库角色有两种类型:即标准角色和应用程序角色。 ①标准角色通过对用户权限等级的认定而将用户划分为不同的用户组,用户属于一 个或多个角色,从而实现管理的安全性。 ②应用程序角色是一种比较特殊的角色。当我们打算让某些用户只能通过特定的 应用程序间接地存取数据库中的数据而不是直接地存取数据库数据时,就应该考虑使用 应用程序角色。当某一用户使用了应用程序角色时,他便放弃了已被赋予的所有数据库 专有权限,他所拥有的只是应用程序角色被设置的角色。 4.SQLServer的权限管理 SQLServer权限分为3类:对象权限、语句权限和隐含权限。 (1)对象权限。对象权限是指用户是否允许对数据库中的表、视图、存储过程等对象 的操作权限,其具体内容如图4-1所示。 对象权限的设置方法如下: ①选中一个数据库对象,右击,使之出现弹出菜单。 第 4 章 数据库安全性与完整性 109 Transact-SQL 数据库对象 SELECT(查询) 表、视图、表和视图中的列 UPDATE(修改) 表、视图、表的列 INSERT(插入) 表、视图 DELETE(删除) 表、视图 EXECUTE(调用过程) 存储过程 DRI(声明参照完整性) 表、表中的列 图4- 1 对象权限的具体内容 ②选择“全部任务”中的“管理权限”项,随后就会出现对象权限对话框。 ③选择“列出全部用户/用户定义的数据库角色”项,或选择“仅列出对此对象具有权 限的用户/用户定义的数据库角色”项。 ④在权限表中对各用户或角色的各种对象操作权授予或撤销。 (2)语句权限。语句权限相当于数据库定义语言的语句权限,具体内容如图4-2所 示。设置方法如下: Transact-SQL语句权限说明 CREATEDATABASE 创建数据库,只能由SA 授予SQL 服务器用户 或角色 CREATEDEFAULT 创建默认值 CREATEPROCEDURE 创建存储过程 CREATERULE 创建规则 CREATETABLE 创建表 CREATEVIEW 创建视图 BACKUPDATABASE 备份数据库 BACKUPLOG 备份日志文件 图4- 2 语句权限的具体内容 ①右击指定的数据库文件夹,出现数据库属性对话框。 ②选择“权限”选项卡,单击表中的各复选小方块可分别对各用户或角色授予、撤销 和废除数据库的语句操作权限。 (3)隐含权限。隐含权限是指由SQLServer预定义的服务器角色、数据库所有者 dbo、数据库对象所有者所拥有的权限,它相当于内置权限,不需要明确地授予这些权限。 上面介绍的3种权限中,隐含权限不需要设置,所以实际上权限的设置是指对对象权 限和语句权限的设置。权限管理的内容有3方面: ①授予权限。即允许某个用户或角色对一个对象执行某种操作或语句。 ②拒绝权限。即拒绝某个用户或角色访问某个对象,即使某个用户或角色被授予这 种权限,仍然不允许执行相应的操作。 ③取消权限。即不允许某个用户或角色对一个对象执行某种操作或某种语句。不 110 数据库系统原理与设计实验教程(第 4 版) 允许和拒绝是不同的,不允许还可以通过加入角色来获得允许,而拒绝是无法通过角色来 获得允许的。3种权限冲突时,拒绝权限起作用。 4.1.2 数据库完整性 数据库的完整性主要包括实体完整性、参照完整性和用户自定义完整性。实体完整 性要求基本表的主键值唯一且不允许为空值;参照完整性为若干个表中的相应元组建立 联系;用户自定义完整性就是针对某一具体应用的数据必须满足的语义要求,由RDBMS 提供而不必由应用程序承担。 1.SQLSr数据完整性分类 SQLServer(e) 的(e) 数据完整性可分为3类,如表4-1所示。 表4- 1 数据库完整性分类 完整性类型约束类型完整性功能描述 用户自定义完 整性 DEFAULT 插入数据时,如果没有明确提供列值,则用默认值作为该列值 CHECK 指定某列或列组可以接受的范围,或指定数据应满足的条件 UNIQUE 指出数据应具有唯一值,防止出现冗余 实体完整性PRIMARYKEY 指定主码,确保主码值不重复,且不允许主码为空值 参照完整性FOREIGNKEY 定义外码、被参照表和其主码 (1)实体完整性。实体完整性为表级完整性,它要求表中所有的元组都应该有一个 唯一的标识符,这个标识符就是平常所说的主码。 (2)参照完整性。参照完整性是表级完整性,它维护参照表中的外码与被参照表中 主码的相容关系。如果在被参照表中某一元组被外码参照,那么这一行既不能被删除,也 不能更改其主码。 (3)用户自定义完整性。用户自定义完整性为列级和元组级完整性。它为列或列组 指定一个有效的数据集,并确定该列是否允许为空。 2.SQLSr数据完整性实现方式(1)声明数(e) 据(v) 完整性。声明数据完整性通过在对象定义中定义、(e) 系统本身自动强制 来实现。声明数据完整性包括各种约束、默认值和规则。 (2)过程数据完整性。过程数据完整性通过使用脚本语言来实现。 4.实验十:安全性定义与检查 2 4.2.1 实验目的与要求 (1)掌握登录账号的创建、修改、删除和禁止操作。 (2)掌握数据库用户的添加和删除操作。 (3)掌握数据库角色的创建、删除;数据库角色成员的添加和删除。 第4 章 数据库安全性与完整性1 11 (4)掌握权限管理中语句权限和对象权限的管理。 (5)掌握数据库是如何进行身份检查和权限检查的。 (6)熟练运用数据库的安全机制操作数据库。 4.2.2 实验案例 在SQLServer中,登录账号、数据库用户、数据库角色以及权限的管理都可以通过 SSMS的集成环境来完成,前面已经讲述。下面使用T-SQL语句来实现登录账号、数据 库用户、数据库角色以及权限的管理功能。 1.登录账户管理 (1)创建登录。使用户得以连接使用SQLServer身份验证的SQLServer实例。语 法如下: [EXECUTE]sp_addlogin [@loginame=]'login' [, [@passwd=]'password' ] [, [@defdb=]'database' ] 其中, ● [@loginame=]l'ogin':登录名称。 ● [@passwd=]'password':登录密码,若不指定则默认为NULL。 ● [@defdb=]'database':登录后用户访问的数据库,若不指定则默认为master数 据库。 在sp_addlogin中,除了登录名称之外,其余选项均为可选项。执行sp_addlogin时, 必须具有相应的权限。只有sysadmin和securityadmin固定服务器角色的成员才能执行 该命令。 【例4.1】 创建用户为victoria,密码为p888888的登录账号。创建用户为u1,密码 为p888888的登录账号。创建用户为u2,密码为p888888的登录账号。 SQL语句如下: sp_addlogin 'victoria','p888888' sp_addlogin 'u1','p888888' sp_addlogin 'u2','p888888' 【例4.2】 创建登录账号liu,密码为liusjj999,默认的数据库为orderdb。 SQL语句如下: sp_addlogin 'liu', 'liusjj999', 'OrderDB' (2)修改登录账号属性。修改登录账号的命令有:修改登录密码、修改默认的数据 库和删除账号。语法如下: sp_password [[@old =]'old_password' , ]{ [@new =]'new_password' } [, [@loginame =]'login' ] 【例4.3】 将liu的密码修改为'p888888'。 SQL语句如下: