第6章 数据表管理
◆ 数据类型简介
◆ 如何修改数据表结构
◆ 如何编写数据表脚本
◆ 临时表简介
数据表可以说是数据库中最重要的对象,一个数据库管理员在数据库中打交道最多的也是数据表。在学会管理数据库之后,本章接着学习如何管理数据表,包括创建、修改、删除数据表,设置各字段的类型,建立主键、外键、关系,设置约束等。
6.1 数据表简介
数据表是数据库中最重要的对象,数据库里的所有数据都是放在数据表里的。数据表与平常所说的表类似,也是按着行和列的格式组织的。表定义的是一个列的集合。每一行代表的是一条记录,每一列代表记录中的一个属性,称为字段。例如,一个包含着供货商信息的表中,每一行代表一位供货商,而每一列代表该供货商的一个信息,例如公司名称、联系人姓名和地址等。图6.1所示的是一个数据表。
图6.1 数据表
6.1.1 数据表的分类
按照表的用途分类,可以分为系统表、用户表、已分区表和临时表四类:
◆ 系统表:在SQL Server 2008中,服务器的配置信息、数据表的定义信息都存储在一组特殊的表中,这组表称为系统表。系统表主要用于维护SQL Server 2008服务器和数据库正常工作,这些表是只读的,只能由SQL Server 2008自己维护,不允许用户进行更改。
◆ 用户表:用户自己创建和维护的、用于各种需要所开发的表。
◆ 已分区表:已分区表是将数据水平划分为多个单元的表,这些单元可以分布到数据库中的多个文件组中。在维护整个集合的完整性时,使用分区表可以快速而有效地访问或管理数据子集,从而使大型表或索引更易于管理。如果表非常大或者有可能变得非常大,可以考虑使用已分区表。
◆ 临时表:临时表是由于系统或用户运算的临时需要而创建的表,该表只是临时使用,使用完毕之后即可删除。SQL Server 2008中的临时表有两种类型,本地临时表和全局临时表。本地临时表只有创建者可以看见并使用,在创建者与SQL Server实例断开连接后,系统会自动删除本地临时表。全局临时表在创建后,对任何用户和任何连接来说,都是可见的,当引用该表的所有用户都与SQL Server实例断开连接后,系统才会将该表删除。
6.1.2 认识列
事实上,创建数据表的过程,也就是创建这个表的列集合的过程。在创建列时,要为列指定字段名(也就是列名)、数据类型、是否允许为Null、是否自动增长等属性。
字段名是列的标识,也就是列的名称,与数据库名和表名类似,要符合命名规范。数据类型用于声明放在该列里的是什么类型的数据,例如在联系人表中,联系人姓名和地址是字符型的,生日是日期型的。
是否允许为Null,即声明该列是不是必填的列。例如在联系人表中,联系人姓名是必填的字段,那么这个字段就应该设置为Not Null,而联系人地址这个字段不是必填的,那么这个字段就可以设置为Null。
说明 Null表示数值未知。Null与空字符串不一样,空字符串是一个字符串,只是里面内容是空的,而Null是没有内容,它既不是字符串,也不是数字,就是空。空字符串在T-SQL里表示为’',而空表示为Null。
是否自动增长,也就是IDENTITY属性,这种类型的字段,可以让表中的记录有个唯一的标识来区别每一行的数据。
6.2 数据类型
在定义数据表列时,必须指定其数据类型。数据类型是一种属性,用于指定该字段可以保存的数据的类型,例如整数数据、字符数据、货币数据、日期数据还是二进制字符串等。
SQL Server 2008中的数据类型可以分为以下几类:精确数字型、近似数字型、日期时间型、字符串型、Unicode字符串型、二进制字符串型和其他数据类型。
说明 在后续章节中要介绍的T-SQL语言定义的局部变量、表达式、参数等的数据类型与本节介绍的类型一致。
6.2.1 精确数字型
精确数字型可以细分为整数型、带固定精度和小数位数的数据类型、货币型三种。
6.2.1.1整数型
此类型的数据可以用来存放整数数据,例如1,2,3和400等,该类型数据包括bigint,int,smallint,tinyint和bit五种,其数据范围如表6.1所示。
表6.1 整数型数据
虽然将bit类型归为整数型,但它只能储存1,0和Null三种值,并且字符串值TRUE和FALSE可以转换为bit类型(TRUE转换为1, FALSE转换为0)。因此,该类型也常用来代表“是/否”字段。
6.2.1.2 带固定精度和小数位数的数据类型
此类型的数据可以用来定义有小数部分的数据,例如1.2和3.45等,此类型有numeric与decimal两种。使用该类型数据时,必须指明精确度与小数位数,例如numeric(3,1)表示精确度为3,小数位数为1,也就是说,此类型数据一共有3位,其中整数2位,小数为1位。精确度可指定的范围为1~38,小数位数可指定的范围最少为0,最多不能超过精确度。表6.2列出了这两种类型数据的数据范围。
表6.2 带固定精度和小数位数的数据类型
6.2.1.3 货币型
货币型数据是用来定义货币数据的,例如$123和$7000等,此类型有money和smallmoney两种,其数据范围如表6.3所示。
表6.3 货币型数据
6.2.2 近似数字型
当数值非常大或非常小时,可以用表示浮点数值数据的大致数值来表示,浮点数据为近似值,例如12345678987654可以用1.23E+13来表示。由于浮点数据是近似值,所以此类型的数据不一定都能精确表示。此类型包括float和real两种,其数据范围如表6.4所示。
表6.4 近似数字型数据
6.2.3 日期和时间型
该类型用来存储日期和时间数据,例如“2006-7-15”和“2006-7-15 21:55:34”等,此类型包括datetime和smalldatetime两种,其数据范围如表6.5所示。
表6.5 日期和时间型数据
6.2.4 字符串型
该类型用来存储字符型数据,例如“abc”和“北京中医药大学”等,此类型包括char,varchar和text三种。
char为固定长度,可用范围为1~8000个字符。例如定义的数据为char(10),表示该数据是char类型的数据,长度为10个字符,如果插入的字符串只有8位,系统会自动在尾部补上两个空格,填满到10位。
varchar为可变长度。例如定义的数据为varchar(10),表示该数据是varchar类型的数据,最大长度为10个字符,如果插入的字符串只有8位,那就只占8位。在SQL Server 2008中,varchar还可以定义为varchar(n)和varchar(max)两种。在varchar(n)中,n的取值范围是1~8000,而varchar(max)的最大存储量是231-1个字节。text是用来存储大量字符的类型,其最多可以存储231-1(2147483647)个字符。三种数据类型的说明如表6.6所示。
表6.6 字符串型数据
在使用char和varchar数据类型时,必须指定字符长度,例如char(10)和varchar(30),默认长度为1。text类型不用指定长度。
6.2.5 Unicode字符串型
该类型与字符串数据类型类似,由于Unicode是双字节字符编码标准,所以在Unicode字符串中,一个字符用两个字节存储。此类型包括nchar,nvarchar和ntext三种,其数据范围如表6.7所示。
表6.7 Unicode字符串型数据
和字符串型数据一样,在使用nchar和nvarchar数据类型时,必须指定字符长度,例如nchar(10)和nvarchar(30),默认长度为1。ntext类型不需要指定长度。
6.2.6 二进制字符串型
该类型用来存储二进制数据,例如“0xAB”和图像文件等。此类型包括binary,varbinary和image三种,其数据范围如表6.8所示。
表6.8 二进制字符串型数据
6.2.7 其他数据类型
在使用binary和varbinary数据类型时,必须指定字符长度,例如binary(10)和varbinary(30),默认长度为1。image类型不用指定长度。Image还可以用来存储二制进文件,例如word文件、图像文件和可执行文件等。
归在其他数据类型的有:cursor,sql_variant,table,timestamp,uniqueidentifier和xml六种。
cursor类型主要是用于变量或存储过程OUTPUT参数的一种数据类型,这些参数包含对游标的引用。cursor主要用来存储查询结果,它是一个数据集,其内部的数据可以单条取出来进行处理。
注意 cursor只能用于程序中声明变量类型,不能用来定义数据表的字段。
sql_variant类型可以用来存储除了text,ntext,image,timestamp和sql_variant之外的所有SQL Server 2008支持的数据类型,其主要用于列、参数、变量和用户定义函数的返回值中。当某个字段需要存储不同类型的数据时,可以将其设置为sql_variant类型。
table类型是一种特殊的数据类型,用于存储结果集以便于后续的处理。table类型主要用于临时存储一组行,这些行是作为表值函数的结果集返回的,其用途与临时表很类似。
注意 可以将函数和变量声明为table类型,但不可以将字段定义为table类型。table类型主要用于函数、存储过程和批处理中。
timestamp数据类型的作用是在数据库范围内提供唯一值,在数据库中更新或插入数据行时,此数据类型定义的列的值会自动更新,一个计数值被自动添加到列中,而且此值在整个数据库中是唯一的。每个数据表中只能有一个timestamp类型的字段。
uniqueidentifier数据类型与timestamp数据类型类似。timestamp存储的是8字节的16进制数据,uniqueidentifier存储的是16字节的16进制数据;timestamp提供的是在数据库范围内的唯一值,uniqueidentifier提供的是在全球范围内的唯一值。
XML数据类型可以在列或变量中存储XML文档和片段,XML片段是缺少单个顶级元素的XML实例。这是SQL Server 2005开始新增的数据类型。XML数据类型实例的存储空间不能超过2GB。
6.2.8 用户自定义型
除了使用系统提供的数据类型外,SQL Server 2008还允许用户根据自己的需要自定义数据类型,并可以用此数据类型来声明变量或字段。
例如在一个数据库中,有很多数据表的字段都需要用到char(50)的数据类型,那么就可以自定义一个数据类型,例如ch50,它代表的是char(50)。然后,在所有数据表里需要用到char(50)的列时,都可以将其设置为ch50的自定义类型。
说明 数据类型中的char(max), varchar(max), nchar(max), nvarchar(max), binary(max),varbinary(max)和xml,为SQL Server 2005之后的新增类型。
6.3.1 定义数据表的字段和主键
6.3 在SQLServerManagementStudio中创建表
了解了什么是数据表、数据表里的字段与数据类型之后,就可以自己动手创建数据表了。
数据表中的字段,也就是数据表中的列。定义数据表的字段时,要为其定义字段名、字段类型、长度、默认值、是否允许空、是否自动增长和排序规则等。
每个数据表中通常会有一个可以标识记录的字段,它具有唯一性,不能重复。例如在联系人表中,联系人姓名可能会重复,但是联系人的编号是不会重复的,这个编号就可以设置为主键。主键是数据表中唯一可以标识表中每一行的值的一个或多个字段。在创建或修改数据表时,可以通过定义Primary Key约束来创建主键。
下面以一个公司的部门信息表为例,说明如何在SQL Server Management Studio中创建表。部门表的结构说明如表6.9所示。
表6.9 部门表
注意 在创建和设计表结构时,不建议使用中文为字段命名,应该使用有意义的英文或拼音来命名。在本书中,为了方便与直观,还是用中文来命名。
step 1 启动SQL Server Management Studio,连接到本地默认实例,在【对象资源管理器】窗格中,选择本地数据库实例→【数据库】→【Northwind】→【表】选项。其中,Northwind数据库是本书所使用的示例数据库,读者也可以自己创建一个数据库作为示例。
step 2 右击【表】选项,在弹出的快捷菜单里选择【新建表】选项。
step 3 在图6.2所示的表设计器窗格中输入各字段的字段名、数据类型、是否允许Null值等内容。如果部门编号和部门名称不允许为空,则取消选中【允许Null值】栏中相对应的复选框。
图6.2 表设计器
step 4 在本例中,部门编号是一个不能重复的唯一性字段,可以将其设置为主键。在表设计器窗格中选中【部门编号】行,然后单击【设置主键/取消主键】按钮,将此列设置为主键。
step 5 设置完毕后,单击【保存】按钮,出现图6.3所示的【选择名称】对话框,输入表的名称,单击【确定】按钮,完成创建表的操作。
图6.3 【选择名称】对话框
如果一个表中没有一个字段可以作为标识记录的唯一性字段,可以将多个字段联合起来设置为主键。在SQL Server Management Studio中,只要同时选择两个字段(按【Ctrl】键选择),然后单击【设置主键/取消主键】按钮,就可以将多个字段共同设置为主键。例如在Northwind数据库中,有个订单明细表,其中“订单ID”和“产品ID”两个字段共同组成主键,如图6.4所示。
图6.4 将两个字段共同设置为主键
6.3.2 设置默认值
如果在插入记录时,没有为其中的一个或多个字段指定内容,可以使用默认值用来指定这些字段中使用什么值。默认值可以是计算结果为常量的任何值,比如常量、函数和数学表达式,都可以用来设置默认值。
在很多种情况下,一个公司并不是每个部门都有传真机,可以为部门表中的“传真”字段设一个默认值,如果不特别指定,在插入部门记录时,SQL Server 2008会自动将此默认数据插入到该记录中。
如图6.5所示,在表设计器窗格中,选择“传真”字段,在【列属性】窗格的【默认值或绑定】文本框中输入传真的默认值“010-88888888”。
图6.5 设置字段默认值
设置完毕后,单击【保存】按钮完成操作。
6.3.3 设置标识列
标识列,相当于Access中的自动增长列。设置标识列的同时,还必须设置该标识列的标识种子和标识增量。标识种子用于指定从哪个数字开始标识。例如标识种子设置为1,则在该数据表中插入的第1条记录,标识列字段里的内容为1;如果标识种子设置为10,则在该数据表中插入的第1条记录,标识列字段里的内容为10。标识增量用于设置标识列递增的幅度。例如,一个标识列的标识种子为1,标识增量为2,则在该数据表中插入的第1条记录,标识列字段里的内容为1;插入第2条记录时,标识列字段里的内容为3;插入第3条记录时,标识列字段里的内容为5……依此类推。
在上面的例子中,“部门编号”这个字段是不可重复的主键,它的数据类型是varchar(16)。在每插入一条记录之前,要生成一个主键,还要保证这个主键的唯一性,这是一件很令人头痛的事。所以,如果不是因为有特殊情况,例如该主键代表着一定意义,主键都会用能自动增长的字段来代替。这样,每插入一条记录,就会自动生成一个不会重复的字段了。例如,建立一个员工通讯录表,其表结构如表6.10所示。
表6.10 员工通讯录表
创建员工通讯录表的过程与本章6.3.1节介绍的案例相同,添加字段名和类型时,要注意将“员工编号”设置为主键和自动增长。设置为自动增长的步骤如下:
step 1 在表设计器窗格中选中【员工编号】行,然后在【列属性】窗格中展开【标识规范】选项,如图6.6所示。
图6.6 设计列
step 2 将【(是标识)】选项设置为【是】,将【标识增量】选项设置为1,将【标识种子】选项也设置为1。
◆ 【标识规范】选项用来设置是否自动增长。
◆ 【标识种子】选项指定从哪个数字开始标识。
◆ 【标识增量】选项指定一次增加多少。
step 3 设置完毕之后,单击【保存】按钮,完成操作。
6.3.4 建立表与表之间的关系
在关系型数据库中,表与表之间并不是完全独立的,它们可以通过外键来建立联系。例如在公司的员工通讯录表中,为了建立员工与部门之间的联系,就需要创建一个字段来指向部门表,通过这个字段,可以知道员工属于哪个部门。反过来,通过这个外键,也可以知道某个部门下有哪些员工。外键通常是指向另一个表的主键。例如本例中,员工通讯录表中的“所属部门”这个外键,就是指向部门表的主键,因为只有主键才可以标识该表中的唯一记录。因为外键是指向主键的,所以这两个键的类型和大小必须是一样的,但是字段名可以不一样。图6.7所示的就是这两个表之间的关系。
图6.7 员工通讯录表与部门表之间的关系
在SQL Server Management Studio里创建外键的方法如下:
step 1 右击表设计器窗格,在弹出的快捷菜单里选择【关系】选项,弹出图6.8所示的【外键关系】对话框,单击【添加】按钮。
图6.8 【外键关系】对话框
step 2 在【外键关系】对话框中,已经新添加了一个名为“FK_员工通讯表_员工通讯表*”的外键,如图6.9所示,但该外键名称不是最终名称。选中【表和列规范】选项,会弹出【…】按钮,单击此按钮。
图6.9 添加外键关系
说明 在SQL Server中,一般用“FK”前缀命名外键,用“PK”前缀命名主键。
step 3 弹出如图6.10所示的【表和列】对话框。在【外键表】下拉列表框中显示的是外键所在的表,本例中是员工通讯录表。单击【外键表】下拉列表框下面的栏,可以通过下拉列表框选择外键字段,本例中选择的是“所属部门”字段。在【主键表】下拉列表框中,可以选择该外键指向的主键所属的数据表,本例中是“部门表”。然后选择“部门表”中的“部门编号”字段。此时,【关系名】文本框里的文字已经自动变为了“FK_员工通讯表_部门表”。如果有需要,还可以自行修改关系名称。
图6.10 设置主键表和外键表
step 4 设置完毕后,单击【确定】按钮,返回到【外键关系】对话框,如图6.11所示。【选定的关系】列表框中的关系名已自动改为“FK_员工通讯表_部门表”,如果还想修改关系名,可以在【标识】区域下的【名称】文本框内修改。
图6.11 显示外键关系
step 5 单击【表设计器】区域里【INSERT和UPDATE规范】选项前的加号标记(+),如图6.12所示,显示出【更新规则】和【删除规则】两个选项。单击任意一个选项后面的属性栏,会弹出下拉列表框,有4个选项:【不执行任何操作】、【级联】、【设置Null】和【设置默认值】。
图6.12 【外键关系】对话框
◆ 不执行任何操作:在删除或更新主键表的数据时,显示一条错误信息,告诉用户不允许执行该删除或更新操作,删除或更新操作将被回滚。在本例中,如果更新规则设置为【不执行任何操作】,只要有一个员工属于该部门,就不能修改该部门的主键信息,也就是该部门的部门编号不能修改。如果修改了,会显示一条错误信息,然后回滚更新操作。如果删除规则设置为【不执行任何操作】,只要有一个员工属于该部门,都不能删除该部门信息,如果删除,会显示一条错误信息,然后回滚删除操作。
◆ 级联:删除或更新包含外键关系中所涉及的数据的所有行。在本例中,如果更新规则设置为【级联】,当部门编号被修改时,所有属于该部门员工的“所属部门”的部门编号也会自动修改。如果删除规则设置为【级联】,当该部门信息被删除时,所有属于该部门的员工信息也会被删除。
◆ 设置Null:如果表的所有外键列都可接受空值,则将值设置为空值。这是SQL Server 2008中新增的功能。在本例中,如果更新规则设置为【设置Null】,当部门编号被修改时,所有属于该部门的员工的“所属部门”字段内容都会变为Null。如果删除规则设置为【设置Null】,当该部门信息被删除时,所有属于该部门的员工信息的“所属部门”字段内容都会变为Null。
◆ 设置默认值:如果表的所有外键列均已定义默认值,则将值设置为该列定义的默认值,这也是SQL Server 2008中新增的功能。在本例中,如果更新规则设置为【设置默认值】,当部门编号被修改时,所有属于该部门的员工的“所属部门”字段内容都会变为该字段的默认值。如果删除规则设置为【设置默认值】,当该部门信息被删除时,所有属于该部门的员工信息的“所属部门”字段内容都会变为该字段的默认值。
注意 要将外键的更新规则和删除规则设置为【设置Null】,该外键必须是可以为空的字段。
注意 要将外键的更新规则和删除规则设置为【设置默认值】,该外键必须是具有默认值的字段。
step 6 设置完毕后,单击【外键关系】对话框中的【关闭】按钮。
step 7 回到表设计器窗格,单击工具栏上的【保存】按钮。
6.3.5 创建索引
数据库中的索引与图书馆中书的索引很类似。使用索引,可以加快从表或视图中检索行的速度。索引在后续章节里还会详细介绍,在此可以简单地把索引想象成排序。例如,将员工通讯录表中的员工编号设置为索引后,如果要查第38号员工的信息,数据库可以很快定位到员工编号为38的记录,如果员工编号为38的记录不存在,数据库也不会再去搜索其他记录。但如果没有建立索引,数据库就要将所有记录都搜索一遍才知道该记录是否存在,搜索的速度就会慢很多。
说明 在此只是举个例子认识索引,SQL Server中的索引并不是简单的排序。
例如,在员工通讯录表里,一般情况下都是以员工姓名为条件来搜索员工的信息,所以可以将员工姓名这个字段建立为索引。建立索引的方法如下:
step 1 右击表设计器窗格,在弹出的快捷菜单里选择【索引和键】选项,弹出图6.13所示的【索引/键】对话框。在【选定的主/唯一键或索引】列表框里,已经存在一个名为“PK_员工通讯表”的主键,系统会为每个主键自动建立索引。单击【添加】按钮。
图6.13 【索引/键】对话框
step 2 如图6.14所示,在【选定的主/唯一键或索引】列表框里,添加了一个名为“IX_员工通讯表”的索引。在SQL Server中,一般以“IX”前缀来命名索引。在【常规】区域里,可以选择新建的是索引还是唯一键,本例中选择索引。在【标识】区域中可以修改索引名称。
图6.14 添加索引
step 3 在【常规】区域中选择【列】选项,会显示【…】按钮。单击此按钮,弹出如图6.15所示的【索引列】对话框。在【列名】下拉列表框内可以选择要设置索引的字段名,在【排序顺序】下拉列表框内可以选择升序或降序排序。在本例中设置“姓名”字段升序索引。
图6.15 【索引列】对话框
step 4 单击【确定】按钮,返回到图6.14所示的【索引/键】对话框,再单击【关闭】按钮。
step 5 最后单击【保存】按钮完成操作。
6.3.6 创建约束
为了减少输入错误和保证数据库数据的完整性,可以对字段设置约束。例如员工通讯录表中的生日,其输入范围应该是1940年到1989年之间。约束是为了保证数据库里数据的完整性而实现的一套机制,它包括主键约束、外键约束、Unique约束、Check约束、默认值和允许空六种机制。
在前面,已经陆续提到过主键、外键、默认值和允许空几个约束,下面介绍Unique约束和Check约束。
6.3.6.1 Unique约束
Unique约束是指定该字段列里的数据不允许出现重复。例如在部门表里,部门的名称是不能重复的,那么就可以将部门表里的“部门名称”设置为Unique约束,设置方法如下:
step 1 在表设计器窗格中右击空白处,在弹出的快捷菜单中选择【索引与键】选项,弹出图6.16所示的【索引/键】对话框。
图6.16 【索引/键】对话框
step 2 单击【添加】按钮,在【选定的主/唯一键或索引】列表框中会自动添加一个名为“IX_部门表”的键。此键名可以在【标识】区域的【(名称)】文本框中修改。
step 3 在【常规】区域的【类型】下拉列表框中选择【唯一键】选项,单击【列】选项后的【…】按钮,然后选择【部门名称】选项,再单击【关闭】按钮。
step 4 退出【索引/键】对话框,单击【保存】按钮完成操作。
说明 Unique约束与主键的区别:Unique约束可以输入Null值,主键不能。在一个表中,可以定义多个Unique约束的字段,而主键字段只能有一个。
6.3.6.2 Check约束
Check约束可以用来限制字段里的值在某个允许的范围内。例如员工通讯录表中的生日,其输入范围应该是1940年到1989年之间。设置Check约束的方法如下:
step 1 在表设计器窗格中单击工具栏上的【管理Check约束】按钮,弹出如图6.17所示的【CHECK约束】对话框。
图6.17 【CHECK约束】对话框
step 2 单击【添加】按钮,在【选定的CHECK约束】列表框中将自动添加一个名为“CK_员工通讯表”的Check约束。该Check约束名可以在【标识】区域中的【(名称)】文本框中修改。
step 3 单击【常规】区域里的【表达式】后的【…】按钮,弹出如图6.18所示的【CHECK约束表达式】对话框。在文本框中输入“(生日 > '1940-1-1' ) and (生日<'1990-1-1' )”。
图6.18 CHECK约束表达式
step 4 单击【确定】按钮返回到【CHECK约束】对话框,此时在【表达式】文本框里自动添加了约束内容。
step 5 单击【关闭】按钮,退出【CHECK约束】对话框,单击【保存】按钮完成操作。
设置完毕后,在员工通讯录表中添加或修改员工通讯录信息时,只要生日字段里的日期不在1990年和1989年之间,系统就会弹出图6.19所示的对话框,提示插入或更新记录失败。
图6.19 插入或更新记录失败
6.3.7 设置数据表所在文件组
文件组的作用是将数据文件集合起来,以便于管理、进行数据分配和放置。每个数据库都有一个主要文件组,该文件组包含主要数据文件和未放入其他文件组的所有次要文件。
在创建数据表时,可以同时指定数据表属于哪个文件组。在SQL Server 2008中,可以将数据表(不包括Text和Image字段)放在文件组中,也可以将Text和Image字段放在文件组中,如果不指定,默认放在primary文件组中。下面以设置员工通讯录数据表的文件组为例,介绍如何设置数据表所在文件组。
step 1 右击【对象资源管理器】窗格中的【员工通讯录表】选项,在弹出的快捷菜单里选择【修改】选项。
step 2 打开数据表的【属性】对话框,在菜单栏上选择【视图】→【属性对话框】选项。
step 3 弹出如图6.20所示的【属性】对话框,在【文件组或分区方案】下拉列表框内可以选择存放数据表的文件组,在【Text/Image文件组】下拉列表框内可以选择存放Text和Image字段的文件组。
图6.20 数据表的属性设置
step 4 修改完毕后,单击工具栏的【保存】按钮保存设置。
6.4 用T-SQL语言创建表
学习了用图形化界面创建数据表之后,下面介绍如何用T-SQL语言创建表。T-SQL语言可以在查询编辑器里执行,有关查询编辑器的使用介绍请参照本书3.3.3节。
6.4.1 基本语法
创建数据表的T-SQL语法如下:
CREATE TABLE [ database_name . [ schema_name ] . | schema_name . ] table_name --设置表名 ( { <column_definition> --设置列属性 | <computed_column_definition> } --设置计算列 [ <table_constraint> ] [ , ...n ] ) --设置表约束 [ ON { partition_scheme_name ( partition_column_name ) | filegroup | "default" } ] --指定存放表数据的分区架构或文件组 [ { TEXTIMAGE_ON --指定存放Text及Image类型字段数据的分区架构或文件组 { filegroup | "default" } ]
为了简化内容,在这里就不给出每个语法块的代码了,在下面的参数讲解中会继续介绍。
6.4.2 参数说明
Create table语句的参数很多,下面介绍一些比较常用的参数。
6.4.2.1 database_name.[schema_name] .|schema_name.]table_name
该项用于设置数据表的名称。一个完整的数据表名称包括三个部分:
◆ database_name:数据表所在数据库的名称。如果省略,代表当前所连接的数据库。
◆ schema_name:数据表所属架构的名称。如果省略,默认为数据表创建者在当前数据库中的用户名称。
◆ table_name:要创建的新表名称。
6.4.2.2 <column_definition>语法块
该语法块主要用于设置数据表字段的属性,其代码如下:
<column_definition> ::= column_name <data_type> --列名 [ COLLATE collation_name ] --列排序规则 [ NULL | NOT NULL ] --列是否为空 [ [ CONSTRAINT constraint_name ] --列约束 DEFAULT constant_expression ] --默认值 | [ IDENTITY [ ( seed , increment ) ] --标识列 [ NOT FOR REPLICATION ] --不用于复制 ] [ ROWGUIDCOL ] --GUID列(全球唯一值) [ <column_constraint> [ ...n ] ] --设置约束
其中的参数说明如下:
◆ column_name:表中列的名称。
◆ <data_type>:列的数据类型,详见<data_type>语法块。
◆ COLLATE collation_name:列的排序规则。排序规则的设置与数据库中的排序规则设置相同。该排序规则只适用于char, varchar, text, nchar, nvarchar和ntext等数据类型。
◆ NULL | NOT NULL:设置该列是否可以为空。
◆ CONSTRAINT constraint_name:建立约束。CONSTRAINT为可选关键字,表示PRIMARY KEY, NOT NULL, UNIQUE, FOREIGN KEY或CHECK约束定义的开始。constraint_name是约束的名称。约束名称必须在表所属的架构中唯一。
◆ DEFAULT constant_expression:如果在插入过程中未显式提供值,则指定为列提供的值。constant_expression是列的默认值常量、NULL或系统函数。
◆ IDENTITY:表示该列是标识列。在表中添加新记录时,SQL Server 2008将为该列提供一个唯一的增量值。标识列通常与主键一起用做表的唯一行标识符。可以将IDENTITY属性分配给tinyint, smallint, int, bigint, decimal(p,0)或numeric(p,0)列。对于每个表,只能创建一个标识列。不能对标识列使用绑定默认值和DEFAULT约束。必须同时指定种子和增量,或者两者都不指定。如果二者都未指定,则取默认值(1,1)。
◆ NOT FOR REPLICATION:在CREATE TABLE语句中,可为IDENTITY属性、外键约束和约束指定NOT FOR REPLICATION子句。如果为IDENTITY属性指定了该子句,则复制代理执行插入操作时,标识列中的值将不会增加。如果为约束指定了此子句,则当复制代理执行插入、更新或删除操作时,将不会强制执行此约束。
◆ ROWGUIDCOL:指定该列是GUID列。其生成的值是全球唯一值。
◆ <column_constraint>:用于设置字段约束,详见<column_constraint>语法块。
6.4.2.3 <data_type>语法块
该语法块用于设置列的数据类型,其语法代码如下:
<data type> ::= [ type_schema_name . ] type_name --列的数据类型及架构 [ ( precision --数据类型的精度 [ , scale ] | max | --小数位数 [ { CONTENT | DOCUMENT } ] xml_schema_collection ) ] --指定xml数据类型
其中的参数说明如下:
◆ [ type_schema_name . ] type_name:指定列的数据类型以及该列所属的架构。
◆ precision:指定数据类型的精度。
◆ scale:指定数据类型的小数位数。
◆ max:同样是指定数据类型的精度,但只适用于varchar, nvarchar和varbinary数据类型,用于存储231个字节的字符和二进制数据,以及230个字节的Unicode数据。
◆ CONTENT:仅适用于xml数据类型,用于指定该列中每个XML的实例都可以包含多个顶级元素。该参数只有在同时指定了xml_schema_collection时才能指定。
◆ DOCUMENT:仅适用于xml数据类型,用于指定该列中每个XML的实例都只包含一个顶级元素。该参数只有在同时指定了xml_schema_collection时才能指定。
◆ xml_schema_collection:仅适用于xml数据类型,用于将XML架构集合与该类型相关联。
6.4.2.4 <column_constraint>语法块
该语法块用于设置字段约束,主要用于为单一字段设置约束。其语法代码如下:
<column_constraint> ::= [ CONSTRAINT constraint_name ] --设置约束名 { { PRIMARY KEY| UNIQUE } --设置主键或UNIQUE约束 [ CLUSTERED | NONCLUSTERED ] --指定聚集索引或非聚集索引 [ WITH FILLFACTOR=fillfactor --指定填充因子 | WITH ( < index_option > [ , ...n ] ) --指定一个或多个索引选项 ] [ ON { partition_scheme_name ( partition_column_name ) | filegroup | "default" } ] --指定索引存放的位置 | [ FOREIGN KEY ] --设置外键约束 REFERENCES [ schema_name . ] referenced_table_name [ ( ref_column ) ] --设置外键所引用的表及字段 [ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] --设置删除规则 [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] --设置更新规则 [ NOT FOR REPLICATION ] --设置强制复制 | CHECK [ NOT FOR REPLICATION ] ( logical_expression ) --设置CHECK约束 }
其中的参数说明如下:
◆ CONSTRAINT:CHECK约束定义的开始。
◆ constraint_name:约束名称。
◆ PRIMARY KEY:主键。
◆ UNIQUE:UNIQUE约束,唯一索引。
◆ CLUSTERED | NONCLUSTERED:指示为PRIMARY KEY或UNIQUE约束创建聚集索引或非聚集索引。PRIMARY KEY约束默认为CLUSTERED, UNIQUE约束默认为NONCLUSTERED。
◆ WITH FILLFACTOR=fillfactor:指定索引页的填充程度(填充因子),值为1~100之间。
◆ <index_option>:指定一个或多个索引选项。详见<index_option>语法块。
◆ ON { partition_scheme_name ( partition_column_name ) | filegroup | "default" }:用于指定索引所存放的位置。如果指定了filegroup,则索引将存储在命名的文件组中。如果指定了default,或者根本未指定ON,则索引将与表存储在同一文件组中。
◆ partition_scheme_name:分区架构的名称,该分区架构定义要将已分区表的分区映射到的文件组。数据库中必须存在该分区架构。
◆ partition_column_name:指定对已分区表进行分区所依据的列。该列必须在数据类型、长度和精度方面与partition_scheme_name所使用的分区函数中指定的列相匹配。分区函数使用的计算列必须显式标记为PERSISTED。
◆ filegroup | "default":与ON一起指定约束创建索引。如果指定了filegroup,则索引将存储在命名的文件组中。如果指定了default,或者根本未指定ON,则索引将与表存储在同一文件组中。
◆ FOREIGN KEY REFERENCES:为列中的数据提供引用完整性的约束。外键约束要求列中的每个值都存在于所引用的表的对应被引用列中。外键约束只能引用在所引用的表中是主键或UNIQUE约束的列,或所引用的表中在UNIQUE INDEX内的被引用列。
◆ [ schema_name . ] referenced_table_name:外键约束引用的表的名称,以及该表所属架构的名称。
◆ ref_column:外键约束所引用的表中的一列或多列。
◆ ON DELETE:指定删除规则,可选项为NO ACTION, CASCADE、SET NULL和SET DEFAULT,即不操作、层叠、设置为空和设置为默认值。
◆ ON UPDATE:指定更新规则,可选项为NO ACTION, CASCADE, SET NULL和SET DEFAULT,即不操作、层叠、设置为空和设置为默认值。
◆ NOT FOR REPLICATION:当复制代理执行插入、更新或删除操作时,将不会强制执行此约束。
◆ CHECK:设置Check约束。
◆ logical_expression:返回TRUE或FALSE的逻辑表达式。别名数据类型不能作为表达式的一部分。
6.4.2.5 <computed_column_definition>语法块
该语法块用于定义计算列,其语法代码如下:
<computed_column_definition> ::= column_name AS computed_column_expression --定义计算列 [ PERSISTED [ NOT NULL ] ] --设置更新 [ [ CONSTRAINT constraint_name ] --设置约束 { PRIMARY KEY | UNIQUE } --设置主键或UNIQUE约束 [ CLUSTERED | NONCLUSTERED ] --指定聚集索引或非聚集索引 [ WITH FILLFACTOR=fillfactor --指定填充因子 | WITH ( <index_option> [ , ...n ] ) --指定一个或多个索引选项 ] | [ FOREIGN KEY ] --设置外键约束 REFERENCES referenced_table_name [ ( ref_column ) ] --设置外键所引用的表及字段 [ ON DELETE { NO ACTION | CASCADE } ] --设置删除规则 [ ON UPDATE { NO ACTION } ] --设置更新规则 [ NOT FOR REPLICATION ] --设置强制复制 | CHECK [ NOT FOR REPLICATION ] ( logical_expression ) --设置CHECK约束 [ ON { partition_scheme_name ( partition_column_name ) | filegroup | "default" } ] --为约束创建索引 ]
其中的参数说明如下:
◆ column_name:列名。
◆ computed_column_expression:定义计算列的值的表达式。
◆ PERSISTED:指定SQL Server将在表中物理存储计算值,而且,当计算列依赖的任何其他列发生更新时对这些计算值进行更新。
其他参数与<column_constraint>语法块的相同,在此不再赘述。
6.4.2.6 <table_constraint>语法块
该语法块用于设置数据表约束,数据表约束是指要同时针对多个字段设置约束。其语法代码如下:
<table_constraint> ::= [ CONSTRAINT constraint_name ] { { PRIMARY KEY | UNIQUE } --设置主键或UNIQUE约束 [ CLUSTERED | NONCLUSTERED ] --指定聚集索引或非聚集索引 (column [ ASC | DESC ] [ , ...n ] ) --指定加入到表约束中的一列或多列的排序顺序 [ WITH FILLFACTOR=fillfactor --指定填充因子 |WITH ( <index_option> [ , ...n ] ) --指定一个或多个索引选项 ] [ ON { partition_scheme_name (partition_column_name) | filegroup | "default" } ] --指定索引存放的位置 | FOREIGN KEY --设置外键约束 ( column [ , ...n ] ) REFERENCES referenced_table_name [ ( ref_column [ , ...n ] ) ] --设置外键所引用的表及字段 [ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] --设置删除规则 [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] --设置更新规则 [ NOT FOR REPLICATION ] --设置强制复制 | CHECK [ NOT FOR REPLICATION ] ( logical_expression ) --设置CHECK约束 }
由于数据表约束的语法和代码与字段约束很类似,在此不再赘述。
6.4.2.7 <index_option>语法块
该语法块用于指定一个或多个索引选项。其语法代码如下:
<index_option> ::= { PAD_INDEX={ ON | OFF } --是否填充索引 | FILLFACTOR=fillfactor --设置填充因子 | IGNORE_DUP_KEY={ ON | OFF } --重复键错误响应方式 | STATISTICS_NORECOMPUTE={ ON | OFF } --重新计算统计数据 | ALLOW_ROW_LOCKS={ ON | OFF} --允许行锁定 | ALLOW_PAGE_LOCKS={ ON | OFF} --允许页锁定 }
其中的参数说明如下:
◆ PAD_INDEX:是否填充索引。如果为ON,则填充因子指定的可用空间百分比将应用于该索引的中间级别页。如果未指定OFF或FILLFACTOR值,则考虑到中间级别页的键集,将中间级别页填充到一个近似容量,以留出足够的空间来容纳至少一个索引的最大行。
◆ FILLFACTOR:设置填充因子。该值为一个百分比,指示在索引创建或更改过程中数据库引擎应使每个索引页的叶级别达到的填充程度。此值为0到100之间的整数。
◆ IGNORE_DUP_KEY:设置有重复键时的错误响应方式。指定对唯一聚集索引或唯一非聚集索引的多行INSERT事务中重复键值的错误响应。如果此参数为ON,并且其中一行违反了唯一索引,则发出警告消息,并且只有违反了UNIQUE索引的行失败。如果此参数为OFF,并且某行违反了唯一索引,则发出错误信息,并回滚整个INSERT事务。在处理UPDATE语句时,IGNORE_DUP_KEY不起作用。
◆ STATISTICS_NORECOMPUTE:设置是否重新计算统计数据。如果为ON,则过期的索引统计信息不会自动重新计算。如果为OFF,则启用自动统计信息更新。
◆ ALLOW_ROW_LOCKS:设置是否允许行锁定。如果为ON,则访问索引时允许使用行锁。数据库引擎确定何时使用行锁。如果为OFF,则不使用行锁。
◆ ALLOW_PAGE_LOCKS:设置是否允许页锁定。如果为ON,则访问索引时允许使用页锁。数据库引擎确定何时使用页锁。如果为OFF,则不使用页锁。
6.4.2.8 ON参数
“ON { partition_scheme_name ( partition_column_name ) | filegroup | "default" }”用于指定存放表数据(不包括Text和Image类型)的分区架构或文件组,如果省略或设置为默认,则表示放在PRIMARY文件组中。
6.4.2.9 TEXTlMAGE_ON参数
“TEXTIMAGE_ON { filegroup | "default" }”用于指定存放表的Text和Image数据的文件组,如果省略或设置为默认,则表示放在PRIMARY文件组中。
6.4.3 创建新表
从本节开始,以下示例都在名为“Northwind”的数据库里进行的,读者也可以自己创建一个新数据库来进行示例测试。
下面的示例用“表名(列名1类型1,列名2类型2)”来代表要创建的数据表结构。例如要创建一个用户信息表,其中包括编号和姓名两个字段,编号用的是int类型数据,姓名用的是nvarchar类型数据,长度是50,那么这个表就用“用户信息表(编号int,姓名nvarchar(50))”来表示。
例一:创建新表。
创建一个新表,表结构为“例一表(编号int,姓名nvarchar(50))”。其代码如下:
CREATE TABLE Northwind.dbo.例一表 ( 编号int, 姓名nvarchar(50) )
以上代码中的“Northwind.dbo.例一表”是最完整的表达方式,可以省略owner,那么owner默认为创建者在当前数据库中的用户名称,如下代码所示:
CREATE TABLE Northwind..例一表 ( )
编号int,
姓名nvarchar(50)
以上代码还可以将数据库名省略,如果省略,则默认是当前数据库,如下代码所示:
USE Northwind CREATE TABLE例一表 ( 编号int, 姓名nvarchar(50) )
6.4.4 创建标识字段
例二:创建新表并设置标识字段。
创建一个新表,表结构为“例二表(编号int,姓名nvarchar(50))”。其中,“编号”为自动增长列。其代码如下:
CREATE TABLE例二表 ( 编号int IDENTITY, 姓名nvarchar(50) )
6.4.5 创建带标识种子和标识增量的标识字段
例三:创建带标识种子和标识增量的标识字段。
创建一个新表,表结构为“例三表(编号int,姓名nvarchar(50))”。其中,“编号”为主键和自动增长列,增长步长为2。其代码如下:
CREATE TABLE例三表 ( 编号int IDENTITY(1,2) PRIMARY KEY, 姓名nvarchar(50) )
6.4.6 创建非Null字段
例四:创建非空值字段。
创建一个新表,表结构为“例四表(编号int,姓名nvarchar(50))”。其中,“编号”为主键和自动增长列,“姓名”为不能为Null列。其代码如下:
CREATE TABLE例四表 ( 编号int IDENTITY(1,1) PRIMARY KEY, 姓名nvarchar(50) NOT NULL )
6.4.7 字段的默认值
例五:设置字段的默认值。
创建一个新表,表结构为“例五表(编号int,姓名nvarchar(50),性别bit)”。其中,“编号”为主键和自动增长列,“姓名”为不能为Null列,“性别”的默认值为“男”,在bit里用“1”表示。其代码如下:
CREATE TABLE例五表 ( 编号int IDENTITY(1,1) PRIMARY KEY, 姓名nvarchar(50) NOT NULL, 性别bit DEFAULT 1 )
6.4.8 将创建的表放在文件组中
例六:创建新表并将其放在文件组中。
创建一个新表,表结构与例五中的相同,并将新表放到“第二文件组”中。其代码如下:
CREATE TABLE例六表 ( 编号int IDENTITY(1,1) PRIMARY KEY, 姓名nvarchar(50) NOT NULL, 性别bit DEFAULT 1 ) ON第二文件组
注意 当将表放在文件组中时,必须保证文件组不是只读的。
6.4.9 使用Check约束
例七:创建新表并使用Check约束。
创建一个新表,表结构为“例七表(编号int,姓名nvarchar(50),性别bit,年纪tinyint)”。其中,“编号”为主键和自动增长列,“姓名”为不能为Null列,“性别”的默认值为“1”,年纪为1到100之间。其代码如下:
CREATE TABLE例七表 ( 编号int IDENTITY(1,1) PRIMARY KEY, 姓名nvarchar(50) NOT NULL, 性别bit DEFAULT 1, 年纪tinyint CONSTRAINT CK_年纪CHECK (年纪>0 AND年纪<101) )
6.4.10 设置字段的排序规则
例八:创建新表并设置字段的排序规则。
创建一个新表,表结构与例七中表结构相同,并且按“姓名”字段排序。其代码如下:
CREATE TABLE例八表 ( 编号int IDENTITY(1,1) PRIMARY KEY, 姓名nvarchar(50) COLLATE Chinese_PRC_CI_AS Not null, 性别bit DEFAULT 1, 年纪tinyint CONSTRAINT CK_例八年纪CHECK (年纪>0 AND年纪<101) )
注意 由于在例七里已经建立了一个名为“CK_年纪”的约束,所以在例八中不能再创建一个同名的约束。
6.4.11 创建外键
例九:创建两个新表并设置外键。
创建两个新表,一个是部门表,表结构为“例九_部门表(部门编号int,部门名称nvarchar(50))”。其中,“部门编号”为自动增长的主键,“部门名称”不能重复也不能为空。另一个是员工表,表结构为“例九_员工表(员工编号int,所属部门int,员工姓名nvarchar(20))”。其中,“员工编号”为自动增长的主键,“所属部门”为外键,指向“例九_部门表”的“部门编号”字段,“员工姓名”为不能为Null的字段。其代码如下:
CREATE TABLE例九_部门表 ( 部门编号int IDENTITY(1,1) PRIMARY KEY, 部门名称nvarchar(50) Not null ) GO CREATE TABLE例九_员工表 ( 员工编号int IDENTITY(1,1) PRIMARY KEY, 所属部门int CONSTRAINT FK_员工表外键 FOREIGN KEY REFERENCES例九_部门表(部门编号), 员工姓名nvarchar(20) not null ) GO
6.4.12 设置外键的更新规则和删除规则
例十:创建新表并设置外键规则。
创建两个新表,表结构与例九中两个表一样,并将外键约束的更新规则设置为“层叠”,删除规则设置为“设置空”。
CREATE TABLE例十_部门表 ( 部门编号int IDENTITY(1,1) PRIMARY KEY, 部门名称nvarchar(50) Not null ) GO CREATE TABLE例十_员工表 ( 员工编号int IDENTITY(1,1) PRIMARY KEY, 所属部门int CONSTRAINT FK_例十_员工表外键 FOREIGN KEY REFERENCES例十_部门表(部门编号) ON UPDATE CASCADE ON DELETE SET NULL, 员工姓名nvarchar(20) not null ) GO
6.4.13 创建Unique约束
例十一:创建新表并同时创建Unique约束。
创建一个新表,表结构与“例九_部门表”结构一样,并将“部门名称”设置为Unique约束。代码如下:
CREATE TABLE例十一_部门表 ( 部门编号int IDENTITY(1,1) PRIMARY KEY, 部门名称nvarchar(50) Not null UNIQUE )
6.4.14 创建计算列
例十二:创建新表并创建可计算的列。
创建一个新表,表结构为“例十二表(编号int,单价money,数量int,合计money)”。其中,“编号”为主键和自动增长列,“单价”不能为空,“数量”不能为空,且大于零,“合计”为“单价”乘以“数量”。其代码如下:
CREATE TABLE例十二 ( 编号int IDENTITY(1,1) PRIMARY KEY, 单价money Not null, 数量int Not null CONSTRAINT CK_例十二CHECK (数量>0), 合计as单价*数量 )
在SQL Server Management Studio中打开例十二表,在里面输入两条记录(不输入“合计”字段内容),SQL Server 2008会自动在合计字段里填入结果,如图6.21所示。合计字段是只读的,不能输入内容。
图6.21 计算列
6.4.15 设置数据表的约束
数据表约束同时针对多个字段设置约束。通过下面的示例可以看出数据表约束与字段约束的不同。
例十三:创建新表并设置数据表的约束。
创建一个新表,表结构为“例十三_用户注册表(编号int,用户名nvarchar(50),密码varchar(16),电话varchar(50),地址nvarchar(200))”。其中,“编号”为主键和自动增长列,“用户名”和“密码”不能为空,“电话”和“地址”至少有一个不为空。其代码如下:
CREATE TABLE例十三_用户注册表 ( 编号int IDENTITY(1,1) PRIMARY KEY, 用户名nvarchar(50) Not null, 密码varchar(16) Not null, 电话varchar(50), 地址nvarchar(200), CHECK (电话is not null or地址is not null) )
6.4.16 Create table语句的注意事项
在SQL Server 2008中,Create table语句的几点注意事项如下:
◆ 可以创建永久化计算列。
◆ 可以使用带ON UPDATE和ON DELETE子句的SET NULL和SET DEFAULT。
◆ 指定用于存储大量varchar, nvarchar和varbinary数据的max数据类型。
◆ 可以创建xml列,并且根据需要可以将该列归入XML架构。
6.5 在SQL Server Management Studio中修改表
在数据表创建完毕后,有可能因为种种原因要进行修改,例如创建时对字段长度的设置不合理、想要增加索引或约束等,这些修改都可以在SQL Server Management Studio中完成。
6.5.1 修改数据表名
修改数据表名称的方法如下:
step 1 启动SQL Server Management Studio,连接上数据库实例,展开【对象资源管理器】窗格中的树形目录,定位到要修改的数据表上。
step 2 右击要修改的数据表,在弹出的快捷菜单里选择【重命名】选项。
step 3 输入数据表名,再按下【Enter】键完成操作。
6.5.2 插入、移动和删除数据表的字段
要插入、移动和删除数据表的字段,可以使用下面介绍的方法。
step 1 启动SQL Server Management Studio,连接上数据库实例,展开【对象资源管理器】窗格中的树形目录,定位到要修改的数据表上。在本例中定位到【员工通讯表】选项。
step 2 右击【员工通讯表】选项,在弹出的快捷菜单里选择【修改】选项。此时出现图6.22所示的表设计器窗格,样式与创建新表时的表设计器窗格一样。
图6.22 表设计器窗格
step 3 右击要插入的位置,例如要在“备注”字段前插入一个“照片说明”字段,则右击“备注”字段,在弹出的快捷菜单里选择【插入列】选项。
step 4 在新出现的行中设置字段名称和类型,如图6.23所示,然后单击工具栏上的【保存】按钮完成操作。
图6.23 插入新字段
在表设计器窗格中,各字段允许上下移动位置。例如要将“性别”字段排在“密码”字段前面,则先选择“性别”字段,然后用鼠标将“性别”字段拖动到“密码”字段前,释放鼠标键,“性别”字段就会移动到“密码”字段前。
如果要删除某个字段,只需右击该字段名称,在弹出的快捷菜单里选择【删除列】选项。
注意 删除字段时,SQL Server 2008不会给出任何提示,在删除时一定要谨慎。
6.5.3 修改字段数据类型
在表设计器窗格中也可以修改字段的数据类型,修改方法很简单,直接在【数据类型】下拉列表框里选择所要修改的数据类型,然后保存即可。
注意 如果数据表里没有记录,则字段的数据类型怎么改都可以。但如果数据表里有记录,就不能随意改了,只能修改成兼容的数据类型。例如,varchar(20)类型可以改为varchar(50)类型,反过来,varchar(50)类型也可以改为varchar(20)类型,但如果数据表该字段里的数据长度超过20,将会被截断。再如,bit类型可以改为decimal(18,0)类型,反过来,decimal(18,0)就不一定可以改为bit类型了。
6.5.4 修改主键、外键、索引和约束
修改数据表的主键、外键、索引和约束都可以在表设计器窗格中进行,修改方法与设置数据表的主键、外键、索引和约束的方法相似,在此就不赘述,读者自行操作就会明白。
6.5.5 修改数据表属性
查看数据表属性的方法如下:
step 1 启动SQL Server Management Studio,连接上数据库实例,展开【对象资源管理器】窗格中的树形目录,定位到要查看属性的数据表上。
step 2 右击数据表,在弹出的快捷菜单里选择【属性】选项。
step 3 在图6.24所示的【表属性】对话框中,可以查看数据表的许多属性,例如数据所占用的空间、索引所占用的空间、数据表所属的文件组、Text和Image字段所属的文件组、数据库所在的服务器名和数据库名等。
图6.24 【表属性】对话框
修改数据表的属性不能在【表属性】对话框里进行,下面以员工通讯表为例,介绍修改数据表属性的方法。
step 1 启动SQL Server Management Studio,连接上数据库实例,展开【对象资源管理器】窗格中的树形目录,定位到【员工通讯表】选项上。
step 2 右击【员工通讯表】选项,在弹出的快捷菜单里选择【修改】选项,弹出图6.25所示的表设计器窗格。
图6.25 修改数据表属性
step 3 在程序主界面的【属性】窗格中,可以修改数据表名、数据表所在文件组、Text和Image字段所在文件组。
说明 如果没有出现【属性】窗格,单击菜单栏上的【视图】→【属性对话框】选项可调出【属性】窗格。
step 4 修改完毕后,单击【保存】按钮完成操作。
6.6 用T-SQL语言修改数据表结构
T-SQL提供了Alter table语句,用于修改数据表结构,包括新建/删除字段、约束和主键等。
6.6.1 基本语法
修改数据表的T-SQL语法如下:
ALTER TABLE [ database_name . [ schema_name ] . | schema_name . ] table_name { ALTER COLUMN column_name --要修改的字段名 { [ type_schema_name. ] type_name [ ( { precision [ , scale ] | max | xml_schema_collection } ) ] --修改后的数据类型 [ NULL | NOT NULL ] --设置是否为NULL [ COLLATE collation_name ] --设置排序规则 | {ADD | DROP } { ROWGUIDCOL | PERSISTED } --添加或删除ROWGUIDCOL属性 } | [ WITH { CHECK | NOCHECK } ] ADD --添加字段 { <column_definition> --设置字段属性 | <computed_column_definition> --设置计算列 | <table_constraint> --设置表约束 } [ ,...n ] | DROP --删除 { [ CONSTRAINT ] constraint_name --删除约束 [ WITH ( <drop_clustered_constraint_option> [ ,...n ] ) ] --设置聚集约束选项 | COLUMN column_name --删除字段 } [ ,...n ] | [ WITH { CHECK | NOCHECK } ] { CHECK | NOCHECK } CONSTRAINT --启用或禁用约束 { ALL | constraint_name [ ,...n ] } | { ENABLE | DISABLE } TRIGGER --启用或禁用触发器 { ALL | trigger_name [ ,...n ] } | SWITCH [ PARTITION source_partition_number_expression ] --切换数据块 TO [ schema_name. ] target_table [ PARTITION target_partition_number_expression ] }
6.6.2 参数说明
Alter table语句的参数比较多,有很多参数与创建新表的语句一样,这里就不再介绍。下面介绍一些比较常用的参数。
1. database_name
数据表所在的数据库名,如果省略,代表当前所连接的数据库。
2. schema_name
数据表所属的架构名,如果省略,默认为当前用户名称。
3. table_name
要修改的数据表名称。
4. ALTER COLUMN column_name
指定要修改的字段名。
5. [type_schema_name.] type_name
更改后字段的数据类型或添加的字段的数据类型。“precision [, scale] | max | xml_schema_collection”为数据类型的精度和小数位数等。
6. NULL | NOT NULL
设置字段是否能为空。
7. {ADD | DROP } {ROWGUIDCOL | PERSISTED}
在指定字段中添加或删除ROWGUIDCOL属性。如果参数为ROWGUIDCOL,代表该字段为GUID字段;如果参数为PERSISTED,代表该字段必须是由表达式定义的计算字段。
8. WITH { CHECK | NOCHECK }
用于指定表中的数据是否用新添加或重新启用的外键或CHECK约束进行验证。如果未指定,对于新约束,假定为WITH CHECK,对于重新启用的约束,假定为WITH NOCHECK。
9. ADD
用于指定添加一个或多个字段、计算列或表约束。
10. <column_definition>语法块
该语法块主要用于设置数据表字段的属性。其语法代码如下:
<column_definition> ::= column_name [ type_schema_name. ] type_name --数据类型 [ ( { precision [ , scale ] | max | [ { CONTENT | DOCUMENT } ] xml_schema_collection } ) ] [ [ CONSTRAINT constraint_name ] DEFAULT constant_expression --约束 [ WITH VALUES ] | IDENTITY [ (seed , increment ) ] [ NOT FOR REPLICATION ] ] [ ROWGUIDCOL ] --GUID列(全球唯一值) [ COLLATE < collation_name > ] --列排序规则 [ <column_constraint> [ ...n ] ]
此语法块中的参数解释请参照本章6.4.2.2节。
11. <column_constraint>语法块
该语法块用于设置字段约束,主要为单一字段设置约束。其语法代码如下:
<column_constraint> ::= [ CONSTRAINT constraint_name ] --设置约束名 { [ NULL | NOT NULL ] { PRIMARY KEY | UNIQUE } --设置主键或UNIQUE约束 [ CLUSTERED | NONCLUSTERED ] --指定聚集索引或非聚集索引 [ WITH FILLFACTOR=fillfactor ] --指定填充因子 [ WITH ( index_option [, ...n ] ) ] --指定一个或多个索引选项 [ ON { partition_scheme_name (partition_column_name) | filegroup | "default" } ] --指定索引存放的位置 | [ FOREIGN KEY ] --设置外键约束 REFERENCES [ schema_name . ] referenced_table_name [ ( ref_column ) ] --设置外键所引用的表及字段 [ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] --设置删除规则 [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] --设置更新规则 [ NOT FOR REPLICATION ] --设置强制复制 | CHECK [ NOT FOR REPLICATION ] --设置CHECK约束 | DEFAULT constant_expression [ WITH VALUES ] ( logical_expression ) }
此语法块中的参数解释请参照本章6.4.2.4节。
12. <computed_column_definition>语法块
该语法块用于定义计算列。其语法代码如下:
<computed_column_definition> ::= column_name AS computed_column_expression --定义计算列 [ PERSISTED [ NOT NULL ] ] --设置更新 [ [ CONSTRAINT constraint_name ] --设置约束 { PRIMARY KEY | UNIQUE } --设置主键或UNIQUE约束 [ CLUSTERED | NONCLUSTERED ] --指定聚集索引或非聚集索引 [ WITH FILLFACTOR=fillfactor ] --指定填充因子 [ WITH ( <index_option> [, ...n ] ) ] --指定一个或多个索引选项 [ ON { partition_scheme_name ( partition_column_name ) | filegroup | "default" } ] --为约束创建索引 | [ FOREIGN KEY ] --设置外键约束 REFERENCES ref_table [ ( ref_column ) ] --设置外键所引用的表及字段 [ ON DELETE { NO ACTION | CASCADE } ] --设置删除规则 [ ON UPDATE { NO ACTION } ] --设置更新规则 [ NOT FOR REPLICATION ] --设置强制复制 | CHECK [ NOT FOR REPLICATION ] ( logical_expression ) --设置CHECK约束 ]
此语法块中的参数解释请参照本章6.4.2.5节。
13. <index_option>语法块
该语法块用于指定一个或多个索引选项。其语法代码如下:
<index_option> ::= { PAD_INDEX={ ON | OFF } --是否填充索引 | FILLFACTOR=fillfactor --设置填充因子 | IGNORE_DUP_KEY={ ON | OFF } --重复键错误响应方式 | STATISTICS_NORECOMPUTE={ ON | OFF } --重新计算统计数据 | ALLOW_ROW_LOCKS={ ON | OFF} --允许行锁定 | ALLOW_PAGE_LOCKS={ ON | OFF} --允许页锁定 | SORT_IN_TEMPDB={ ON | OFF } --指定是否将排序结果存储在tempdb中 | ONLINE={ ON | OFF } --是否可用于查询和数据修改操作 | MAXDOP=max_degree_of_parallelism --在索引操作期间覆盖“最大并行度”配置选项 }
此语法块中的参数解释请参照本章6.4.2.7节。
14.<table_constraint>语法块
该语法块用于设置数据表约束。数据表约束是指要同时针对多个字段设置约束。其语法代码如下:
<table_constraint> ::= [ CONSTRAINT constraint_name ] { { PRIMARY KEY | UNIQUE } --设置主键或UNIQUE约束 [ CLUSTERED | NONCLUSTERED ] --指定聚集索引或非聚集索引 (column [ ASC | DESC ] [ ,...n ] ) --指定加入到表约束中的一列或多列 的排序顺序 [ WITH FILLFACTOR=fillfactor --指定填充因子 [ WITH ( <index_option>[ , ...n ] ) ] --指定一个或多个索引选项 [ ON { partition_scheme_name ( partition_column_name ... ) | filegroup | "default" } ] --指定索引存放的位置 | FOREIGN KEY --设置外键约束 ( column [ ,...n ] ) REFERENCES referenced_table_name [ ( ref_column [ ,...n ] ) ] --设置外键所引用的表及字段 [ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] --设置删除规则 [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] --设置更新规则 [ NOT FOR REPLICATION ] --设置强制复制 | DEFAULT constant_expression FOR column [ WITH VALUES ] --指定字段的默认值 | CHECK [ NOT FOR REPLICATION ] ( logical_expression ) --设置CHECK约束 }
此语法块中的参数解释请参照本章6.4.2.6节。
15. DROP { [ CONSTRAINT ] constraint_name | COLUMN column_name }
用于指定从表中删除的约束或字段,可以列出多个列或约束。其中,constraint_name为约束名,column_name为字段名。
16. WITH <drop_clustered_constraint_option>
用于指定设置一个或多个删除聚集约束选项。
17. <drop_clustered_constraint_option>语法块
该语法块用于设置聚集约束选项。其语法代码如下:
<drop_clustered_constraint_option> ::= { MAXDOP=max_degree_of_parallelism | ONLINE={ON | OFF } | MOVE TO { partition_scheme_name ( column_name ) | filegroup | "default"} }
其中的参数说明如下:
◆ MAXDOP:只在操作期间覆盖max_degree_of_parallelism配置选项,使用MAXDOP选项来限制执行并行计划时所用的处理器数量。最大数量为64个处理器。
◆ max_degree_of_parallelism:可设置的值为“0”、“>1”和“1”。为“1”时代表取消生成并行计划,为“>1”时代表将并行索引操作中使用的最大处理器数量限制为指定数量,为“0”时代表根据当前系统工作负荷使用实际的处理器数量或更少数量的处理器。其中,“0”为默认值。
◆ ONLINE:指定在索引操作期间基础表和关联的索引是否可用于查询和数据修改操作。默认值为OFF。
◆ MOVE TO:指定一个位置以移动聚集索引的叶级别中的当前数据行。表被移至新位置。
18. {CHECK|NOCHECK} CONSTRAINT{ALL |constraint_name[ ,...n ]}
用于启用或禁用约束,constraint_name为约束名。此选项只能与外键和CHECK约束一起使用。如果指定了NOCHECK,将禁用约束,从而在将来插入或更新列时不根据约束条件进行验证。无法禁用DEFAULT、主键和UNIQUE约束。
19. {ENABLE|DISABLE}TRIGGER{ALL|trigger_name[ ,...n]}
启用或禁用触发器。设置为“ALL”表示启用或禁用所有触发器。trigger_name为触发器名。
20. SWITCH数据块
用于切换数据块,可选择方式为:将表的所有数据作为分区重新分配给现有的已分区表,将分区从一个已分区表切换到另一个已分区表,将已分区表的一个分区中的所有数据重新分配给现有的未分区表。
如果数据表为已分区表,则必须指定source_partition_number_expression。如果target_table已进行分区,则必须指定target_partition_number_expression。如果要将表的数据作为分区重新分配给现有的已分区表,或者将分区由一个已分区表切换到另一个已分区表,则目标分区必须存在,并且必须为空。
如果重新分配一个分区的数据以组成单个表,则必须已经创建了目标表,并且该表必须为空。源表或分区以及目标表或分区必须在同一个文件组中。对应的索引或索引分区也必须在同一个文件组中。
6.6.3 修改字段属性
本章6.4节中创建了很多数据表,本节以这些数据表为例,介绍如何修改数据表结构。
例十四:更改表字段的属性。
将“例一表”中的“姓名”字段改为nvarchar(10),不能为Null,排序规则为Chinese_PRC_CI_AS。其代码如下:
ALTER TABLE例一表 ALTER COLUMN姓名nvarchar(20) COLLATE Chinese_PRC_CI_AS not null
6.6.4 添加字段
例十五:在表中添加字段。
在“例一表”中添加一个“性别”字段,数据类型为nvarchar(2)。其代码如下:
ALTER TABLE例一表 ADD性别nvarchar(2)
6.6.5 添加字段并设置字段属性
例十六:在表中添加字段并设置属性。
在“例一表”中添加一个“密码”字段,数据类型为varchar(16),不能为Null。其代码如下:
ALTER TABLE例一表 ADD密码varchar(16) Not null
说明 用Alter table语句添加字段的代码与在创建新数据表时添加字段的代码相同,可以参照本章6.4.3节。
6.6.6 删除字段
例十七:删除表中的字段。
在“例一表”中删除“密码”字段。其代码如下:
ALTER TABLE例一表 DROP COLUMN密码
6.6.7 添加约束
例十八:在表中添加约束。
在“例一表”中添加一个约束,“性别”字段只能为“男”或“女”。其代码如下:
ALTER TABLE例一表 ADD CONSTRAINT CK_性别CHECK (性别='男' OR性别='女')
在默认情况下,添加Check约束时会检查数据表里的数据是否符合Check约束,如果有数据不符合Check约束,添加Check约束操作会失败。如果希望添加约束时不检查数据库里的数据是否符合Check约束,请用以下代码:
ALTER TABLE例一表 WITH NOCHECK ADD CONSTRAINT CK_性别CHECK (性别='男' OR性别='女')
6.6.8 禁用约束
例十九:禁用表的约束。
禁用“例一表”中的“CK_性别”约束。其代码如下:
ALTER TABLE例一表 NOCHECK CONSTRAINT CK_性别
也可以一次禁用多个约束:
ALTER TABLE例一表 NOCHECK CONSTRAINT CK_1,CK_2,CK_3
如果要禁用所有约束,则用以下代码:
ALTER TABLE例一表 NOCHECK CONSTRAINT ALL
6.6.9 启用约束
例二十:启用表的约束。
启用“例一表”中的“CK_性别”约束。其代码如下:
ALTER TABLE例一表 CHECK CONSTRAINT CK_性别
也可以一次启用多个约束:
ALTER TABLE例一表 CHECK CONSTRAINT CK_1,CK_2,CK_3
如果要启用所有约束,则用以下代码:
ALTER TABLE例一表 CHECK CONSTRAINT ALL
6.6.10 删除约束
例二十一:删除表的约束。
将“例一表”中的“CK_性别”约束删除。其代码如下:
ALTER TABLE例一表 DROP CK_性别
6.6.11 设置主键
例二十二:设置表主键。
将“例一表”中的“编号”字段设置为主键。其代码如下:
ALTER TABLE例一表 ALTER COLUMN编号int not null GO ALTER TABLE例一表 ADD CONSTRAINT PK_主键PRIMARY KEY (编号) GO
6.6.12 修改字段名和数据表名
Alter table语句并没有直接修改数据表名和字段名的功能,如果要修改数据表名或字段名,只能使用sp_rename存储过程。
例二十三:修改表名和字段名。
将“例一表”中的“姓名”字段改名为“名称”,并将“例一表”改名为“例二十三表”。其代码如下:
exec sp_rename '例一表.姓名','名称','COLUMN' exec sp_rename '例一表','例二十三表'
其实,用存储过程“sp_rename”可以修改数据库中任何用户建立的对象名称,其语法代码如下:
sp_rename '原对象名称' , '新对象名称' [ , '对象类型']
其中的“对象类型”可以为以下5种:
◆ COLUMN:修改字段名称。
◆ DATABASE:修改数据库名称。
◆ INDEX:修改索引名称。
◆ OBJECT:修改约束(Check约束、主键、外键或Unique约束)、数据表、视图、存储过程和触发器名称。
◆ USERDATATYPE:修改用户自定义数据类型对象的名称。
6.6.13 Alter table语句的注意事项
在SQL Server 2008中,Alter table语句有以下几点注意事项:
◆ 该语句允许添加列,但是,不允许删除或更改参与架构绑定视图的表中的列。
◆ 用于删除列时,必须在删除所有基于列的索引和约束后,才能删除列。
◆ ALTER COLUMN子句并不会在列上绑定或取消绑定任何规则。
◆ 如果新添加列的数据类型为uniqueidentifier,则该列可以使用NEWID( )函数作为默认值。
6.7 在SQL Server Management Studio中删除表
当一个数据表不再需要使用时,就可以将其删除。下面以删除“部门表”为例介绍如何在SQL Server Management Studio中删除表。
step 1 启动SQL Server Management Studio,连接到本地数据库默认实例。
step 2 在【对象资源管理器】窗格中展开树形目录,定位到【部门表】选项。右击【部门表】选项,在弹出的快捷菜单里选择【删除】选项。
step 3 弹出如图6.26所示的【删除对象】对话框,在该对话框里可以看到要删除的数据表名称。单击【确定】按钮完成操作。
图6.26 【删除对象】对话框
下面将“例九_部门表”删除,看看会发生什么情况。
step 1 在【对象资源管理器】窗格中展开树形目录,定位到【例九_部门表】选项。右击【例九_部门表】选项,在弹出的快捷菜单里选择【删除】选项。
step 2 弹出【删除对象】对话框,单击【确定】按钮,出现如图6.27所示的信息,提示删除数据表失败。
图6.27 删除数据表失败
step 3 在图6.27所示的对话框中,单击【消息】栏中的说明链接,弹出如图6.28所示的对话框。在该对话框中可以查看删除失败的原因。本例的失败原因是该数据表正被一个外键约束引用。
图6.28 删除失败的原因
step 4 单击【确定】按钮返回到图6.27所示的【删除对象】对话框。单击【显示依赖关系】按钮,弹出如图6.29所示的【依赖关系】对话框,在此对话框中可以查看依赖于“例九_部门表”的对象和“例九_部门表”所依赖的对象。
图6.29 【依赖关系】对话框
要查看数据表的依赖关系,也可以右击数据表名,在弹出的快捷菜单中选择【查看依赖关系】选项。当数据表有外键依赖时是不能被删除的,只有先将依赖于该数据表的关系都删除后才能删除该表。SQL Server Management Studio还允许一次删除多个数据表,删除方法如下:
step 1 在【对象资源管理器】窗格中定位到要删除的表所在的数据库,在本例中,选择【(local)】→【数据库】→【Northwind】→【表】选项,打开【摘要】窗格,如图6.30所示。
图6.30 【摘要】窗格
step 2 在【摘要】窗格里中选择要删除的多个数据表(按住【Shift】键或【Ctrl】键选择),然后单击鼠标右键,在弹出的快捷菜单中选择【删除】选项。
step 3 打开图6.31所示的【删除对象】对话框,可以看到要删除的多个数据表名。在【错误选项】栏中可以选择出错后的操作,是继续删除对象,还是停止删除对象。
图6.31 要删除的表
step 4 单击【确定】按钮完成操作。
6.8 用Drop table删除数据表
T-SQL语言中删除数据表的代码,不像创建数据表和修改数据表那么复杂,其语法代码如下:
DROP TABLE [ database_name . [ schema_name ] . | schema_name . ] table_name [ ,...n ] [ ; ]
例二十四:删除表。
删除“例二表”,其代码如下:
DROP TABLE例二表
注意 如果要删除的数据表是外键所指向的数据表,那么用Drop table语句无法将其删除,必须先删除表与表之间的关联才能进行删除。
6.9 编写表脚本
在SQL Server 2008里,同样可以将现有的数据表结构生成一个T-SQL代码脚本,利用该脚本可以创建或更新数据表开发代码,或维护、备份数据表脚本。下面以“例十_部门表”为例,介绍如何在SQL Server Management Studio中生成数据表脚本。
step 1 启动SQL Server Management Studio,连接到本地数据库默认实例。
step 2 在【对象资源管理器】窗格中展开树形目录,定位到【例十_部门表】选项。右击【例十_部门表】选项,在弹出的快捷菜单中选择【编写表脚本为】→【CREATE到】→【新查询编辑器对话框】选项。
step 3 打开一个新的查询编辑器窗格,系统自动生成了创建“例十_部门表”数据表的T-SQL脚本代码,生成的代码如下所示。
USE [Northwind] GO /****** 对象: Table [dbo].[例十_部门表] 脚本日期: 05/19/2009 13:53:12 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[例十_部门表]( [部门编号] [int] IDENTITY(1,1) NOT NULL, [部门名称] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL, PRIMARY KEY CLUSTERED ( [部门编号] ASC )WITH (IGNORE_DUP_KEY=OFF) ON [PRIMARY] ) ON [PRIMARY]
step 4 可以将该数据表脚本保存为一个SQL文件,在其他数据库服务器上执行以生成一个相同结构的数据表。
在SQL Server 2008中,还可以同时为多个表生成脚本:
step 1 在【对象资源管理器】窗格中,定位到要生成脚本的表所在的数据库上。本例定位到【(local)】→【数据库】→【Northwind】→【表】选项,切换到【摘要】窗格,如图6.30所示。
step 2 在【摘要】窗格中选择要生成脚本的多个数据表(按住【Shift】键或【Ctrl】键选择),然后单击鼠标右键,在弹出的快捷菜单中选择【编写表脚本为】→【CREATE到】→【新查询编辑器对话框】选项。
step 3 打开一个新的查询编辑器窗格,在里面生成了多个数据表的脚本。
6.10 数据库关系图的使用
数据库关系图以图形方式显示数据库结构和数据表之间的联系。通过关系图可以很直观地了解整个数据库的轮廓和关联。使用数据库关系图可以创建和修改数据表、字段、关系、键、索引和约束。在SQL Server 2008中,可以在【对象资源管理器】窗格中创建和使用数据库关系图。
6.10.1 创建数据库关系图并添加数据表
下面介绍如何创建新的数据库关系图,并在新的数据库关系图里添加数据表。
step 1 在图6.32所示的【对象资源管理器】窗格中,右击【数据库关系图】选项,在弹出的快捷菜单中选择【新建数据库关系图】选项。
图6.32 【对象资源管理器】窗格
step 2 在第一次使用时,系统会弹出图6.33所示的对话框,询问是否创建所需的支持对象,单击【是】按钮。
图6.33 安装关系图所需的支持对象
step 3 安装完毕后,重复第1步,弹出图6.34所示的【添加表】对话框,使用该对话框可以在关系图中添加数据表,本例添加“例十_部门表”和“例十_员工表”。
图6.34 【添加表】对话框
step 4 单击【关闭】按钮,回到图6.35所示的数据库关系图,通过该图可以看到表“例十_员工表”与表“例十_部门表”之间的联系,还可以看到两个表的主键。
图6.35 查看两个表之间的关系
step 5 如果还要再添加数据表到关系图中,右击关系图的空白处,在弹出的快捷菜单里选择【添加表】选项,打开图6.34所示的【添加表】对话框添加数据表。
step 6 操作完毕后,单击保存【保存】按钮,在弹出的【选择名称】对话框里输入关系图名称,再单击【确定】按钮,完成保存操作。
6.10.2 添加相关联的数据表
在【关系图】视图中可以为数据表自动添加相关表:
step 1 将具有关系的表添加到数据库关系图中。
step 2 右击该数据表,在弹出的快捷菜单中选择【添加相关表】选项,SQL Server 2008会自动向关系图里添加与该数据表有关联的数据表。
如果该数据表没有相关联的数据表,则快捷菜单中的【添加相关表】选项为灰色不可用状态。
6.10.3 更改数据表的显示模式
在【关系图】视图中可以更改数据表的显示模式,方法如下:
step 1 在【关系图】视图中,右击数据表,在弹出的快捷菜单中选择【表视图】选项。
step 2 在【表视图】菜单中有五种可选方式,【标准】、【列】、【键】、【仅表名】和【自定义】,分别代表不同的显示模式,如图6.36所示。
图6.36 不同的显示模式
在自定义模式中可以自行设定要显示的内容。在【关系图】视图中,右击数据表,在弹出的快捷菜单中选择【表视图】→【修改自定义】选项,弹出图6.37所示的【列选择】对话框,在此可以选择要显示的属性。选择完毕后单击【确定】按钮,在【关系图】视图中可以看到修改过的自定义模式。
图6.37 【列选择】对话框
6.10.4 在关系图中删除数据表
删除数据表有两种不同的模式,一种是在关系图中删除数据表,一种是在数据库中删除数据表。在关系图中删除数据表,数据表本身并没有被删除,只是不存在于关系图中了。
在关系图中删除数据表的方法:在【关系图】视图中,右击数据表,在弹出的快捷菜单中选择【从关系图中移除】选项。或者,在【关系图】视图中,选择数据表,再按下键盘上的【Delete】键。
在关系图中也可以将数据表从数据库中删除(不仅仅是在关系图中删除),其方法为:在【关系图】视图中右击数据表,在弹出的快捷菜单中选择【从数据库中删除表】选项。
6.10.5 建立和删除表与表之间的关联
因为关系图是图形界面,所以可以很直观地建立表与表之间的关联(即外键),也可以很直观地删除表与表之间的关联。下面通过例子学习如何删除和建立表与表之间的关联:
step 1 创建一个新的关系图,在关系图中添加“例十_部门表”、“例十_员工表”和“例十一_部门表”。三个表之间的关系如图6.38所示。本例要删除“例十_员工表”与“例十_部门表”之间的外键联系,并建立“例十_员工表”与“例十一_部门表”之间的联系。“例十_员工表”中的“所属部门”是个外键,指向“例十一_部门表”的“部门编号”字段。
图6.38 查看三个表之间的关系
step 2 右击连接“例十_部门表”和“例十_员工表”之间的关联线,在弹出的快捷菜单里选择【从数据库中删除关系】选项。
step 3 在弹出的警告对话框里单击【是】按钮,完成删除外键操作。
step 4 将“例十_员工表”的“所属部门”字段拖放到“例十一_部门表”的“部门编号”字段上,出现如图6.39所示的【表和列】对话框,接下来的操作与本章6.3.4节中介绍的设置外键的方法一致。SQL Server 2008已经将主键和外键都设置好了,如果不正确,还可以修改。最后单击【确定】按钮。
图6.39 【表和列】对话框
step 5 返回到如图6.40所示的【关系图】视图,此时可以看出表与表之间的关联已经更改。
图6.40 表关系发生了变化
step 6 单击【保存】按钮,弹出【选择名称】对话框,输入关系图名,例如“Diagram_0”,单击【确定】按钮。此时会弹出如图6.41所示的【保存】对话框,询问是否对刚才修改过的三个数据表进行修改。单击【是】按钮,将数据表之间的新关系保存到数据库中。
图6.41 【保存】对话框
如果曾经保存过关系图,再单击【保存】按钮就不会出现【选择名称】对话框,而是直接询问是否保存对数据表的修改。保存后的关系图,可以在需要使用时再次打开。
6.10.6 保存部分修改过的数据表
从6.10.5节的示例可以看出,在关系图中可以对多个数据表进行修改。如果在修改完多个数据表之后,只想保存其中几个数据表的修改,那该怎么办?SQL Server 2008提供了几个方法。
下面举例说明。打开“Diagram_0”关系图,添加“例九_部门表”与“例九_员工表”两个数据表到关系图中,删除关系图中的所有关联,然后建立“例十_部门表”与“例十_员工表”之间的关联。但最后只保存“例十_部门表”、“例十_员工表”和“例十一_部门表”三个数据表的修改。
step 1 在【对象资源管理器】窗格中展开【Northwind】→【数据库关系图】→【Diagram_0】选项,双击【Diagram_0】选项,打开【关系图】视图。
step 2 在关系图中添加“例九_部门表”与“例九_员工表”,并将“例九_部门表”与“例九_员工表”之间的关系删除,再将“例十_部门表”与“例十_员工表”之间的关系删除,然后添加“例十_部门表”与“例十_员工表”之间的关联。此时的关系如图6.42所示。
图6.42 查看关系图
step 3 图6.42中,数据表名后带 “*”号的,代表已经修改过的数据表,按住【Ctrl】键选择“例十_部门表”、“例十_员工表”和“例十一_部门表”三个数据表,然后单击菜单栏上的【文件】→【保存选择】选项,弹出如图6.43所示的【保存】对话框。
图6.43 【保存】对话框
step 4 在【保存】对话框里可以看出要保存的数据表只有选择的三个。单击【是】按钮,完成对三个表修改的保存。保存后的【关系图】视图如图6.44所示,此时可以看到数据表名后带“*”号的表只剩下两个。
图6.44 保存三个表后的关系图
step 5 关闭【关系图】视图,在询问是否保存修改的对话框里单击【否】按钮,放弃对“例九_部门表”与“例九_员工表”的修改。
6.10.7 在关系图中创建数据表
在关系图中可以创建新的数据表,创建方法如下。
step 1 右击【关系图】视图的空白处,在弹出的快捷菜单里选择【新建表】选项。
step 2 在如图6.45所示的【选择名称】对话框中输入数据表名称,单击【确定】按钮。
图6.45 【选择名称】对话框
step 3 在【关系图】视图中自动添加了一个数据表,如图6.46所示,在此可以为新表添加字段和字段属性。
图6.46 在【关系图】视图中新建表
step 4 设计完成后,单击【保存】按钮。
6.10.8 在关系图中修改字段属性
在关系图中可以修改数据表中字段的属性,其修改方法如下:
step 1 打开关系图,将要修改字段的数据表的显示模式设置为“标准”或“自定义”。
step 2 在如图6.47所示的【关系图】视图中,选择要修改的字段,并修改其属性。
图6.47 在【关系图】视图中修改字段属性
step 3 修改完毕后,单击【保存】按钮。
6.10.9 在关系图中设置或修改表的外键与约束
在关系图中还可以添加或删除数据表的主键、插入或删除字段、创建或删除索引、创建或删除键、创建或删除Check约束,甚至还可以生成更改的T-SQL脚本。
如图6.48所示,右击数据表,在弹出的快捷菜单中有【设置主键】、【插入列】、【删除列】、【关系】、【索引/键】、【CHECK约束】、【生成更改脚本】等选项。选择这些选项后,出现的对话框与创建数据表和修改数据表时所用的对话框十分类似,在此不再赘述。
图6.48 【关系图】视图中的快捷菜单
6.11 临时表简介
临时表是一种因为暂时需要所产生的数据表,它存放在tempdb数据库中,当使用完临时表且关闭连接后,临时表会被自动删除。根据使用范围的不同,临时表可分为两类:
◆ 本地临时表:本地临时表是以“#”开头命名的表,只有创建它的用户可以使用它,当该用户断开连接后,SQL Server会自动删除它。
说明 如果是在储存过程或触发器中创建的本地临时表,当存储过程或触发器结束时,该本地临时表也会被自动删除。
◆ 全局临时表:全局临时表是以“##”开头命名的表,在创建后,任何用户和连接都可以使用它,只有当所有使用该临时表的用户都与SQL Server实例断开连接后,SQL Server才将其删除。
说明 临时表也可以用Drop table语句删除。
创建临时表和创建一般的表的方法相同,只是数据表名前必须加上“#”或“##”。
CREATE TABLE #数据表名(字段1,字段2) CREATE TABLE ##数据表名(字段1,字段2)
6.12 已分区表简介
已分区表是将超大表按照某种业务规则(例如年份)分别存储在不同的物理介质中(文件组),以提高性能、方便管理。已分区表将一个表分为两个或多个表,这些表在物理上来说是多个表,但是从逻辑上来说,是同一个表。
一般来说,当一个数据表里的数据量达到千万级时,就应该考虑使用已分区表了。已分区表将一个表拆分成了多个表,每个表里的记录数就会相对减少。这样,对单个表的维护成本也会大大减少。例如数据库备份,对于一个千万级记录的表备份,可能需要数分钟,但对于十个百万级记录的表备份,可能只要数秒钟。因为进行备份时需要将数据库锁定,不让其他用户操作数据库,备份数据库的时间越长,就意味着有越多的用户需要等待。
另一种情况,当数据表里数据量大,且数据有着不同的操作方式时,也可以考虑使用已分区表。例如,一个数据表里的记录,对于当月的记录所进行的操作主要是插入、修改和删除,而对于以往的记录所进行的操作主要是统计和查询,那么也可以考虑使用已分区表。将数据表按月份进行分区,对数据表的管理可能会更容易一些。
在对表进行分区之前,必须先创建分区函数和分区方案。分区函数定义如何根据某些列(例如时间字段)的值将表的行映射到一组分区。分区方案将分区函数指定的每个分区映射到文件组。由于一些概念性的问题在前面还未涉及,所以在此不介绍如何对数据表进行分区,有兴趣的读者可以先查询帮助文档。
6.13 小结
数据表是行与列的集合,可以分为系统表、用户表、已分区表和临时表四类。创建数据表就是定义数据表中的列属性、表与表之间的关系,以及数据表存放的位置。
创建列时要为列指定列名(字段名)、数据类型、是否为Null、默认值、约束、是否是标识列等属性。其中,数据类型可以分为精确数字型、近似数字型、日期时间型、字符串型、Unicode字符串型、二进制字符串型和其他数据类型几大类。数据表与数据表之间的关系体现了关系数据库的“关系”二字,设置数据表之间的关系也就是为数据表设置主键和外键。将不同的数据表放在不同的文件组中可以方便管理和数据分配。
虽然用SQL Server Management Studio创建、删除和修改数据都很方便,但也不要忘记怎么使用T-SQL来操作数据表。创建表使用CREATE TABLE语句,删除表使用DROP TABLE语句,修改表使用ALTER TABLE语句。创建表和修改表的参数比较多,不一定要全部记住,只要知道用法,在忘记时查阅文档即可。
数据库关系图是以图形方式显示数据库结构和数据表之间的联系。通过关系图可以很直观地了解整个数据库的轮廓和关联。使用数据库关系图可以创建和修改数据表、字段、关系、键、索引和约束。
最后,本章还对临时表和已分区表进行了介绍。临时表是一种因为暂时需要所产生的数据表,它存放在tempdb数据库中,当使用完临时表且关闭连接后,临时表会被自动删除。已分区表是将超大表按照某种业务规则(例如年份)分别存储在不同的物理介质中(文件组),以提高性能、方便管理。
第7章将会重点介绍如何操作数据表里的数据。