3.4 修改数据库
创建完数据库后,用户在使用过程中可以根据需要对数据库的定义进行修改。修改数据库的操作主要包括如下几项:
扩大数据库空间。
缩小数据库空间。
添加和删除数据库文件。
创建文件组。
更改数据库所有者。
3.4.1 扩大数据库空间
如果在创建数据库时没有设置自动增长方式,则数据库在使用一段时间后可能会出现数据库空间不足的情况,这些空间包括数据空间和日志空间。如果数据空间不够,则意味着不能再向数据库中插入数据;如果日志空间不够,则意味着不能再对数据库数据进行任何修改操作,因为对数据的修改操作是要记入日志的。此时就应该对数据库空间进行扩大。扩大数据库空间有两种方法,一种是扩大数据库中已有文件的大小,另一种是为数据库添加新的文件。这两种方法均可在SQL Server Management Studio中用图形化的方法实现,也可以用Transact-SQL语句实现。
- 用图形化方法实现
以数据库管理员身份连接到SQL Server Management Studio,在对象资源管理器中,在要扩大空间的数据库上右击鼠标,在弹出的快捷菜单中选择“属性”命令,然后在弹出的窗口中的“选项页”部分选中“文件”选项,窗口形式如图3-11所示。
在如图3-11所示的窗口中,在“初始大小”文本框中可以直接输入一个新的初始大小,来扩大该文件空间的大小。也可以单击“添加”按钮,为数据库增加新的文件,从而达到扩大数据库空间的目的,这种情况尤其适合当已有文件所在磁盘的空白空间不足时。
单击“添加”按钮后,在“数据库文件”网格中,完成如下操作可添加新的文件:
1)在“逻辑名称”部分输入新文件的逻辑名。该文件名在数据库中必须唯一。
2)在“文件类型”列表框中指定文件的类型(“数据”或“日志”)。如果是数据文件,则可从列表中选择文件所属的文件组,或选择“<新文件组>”以创建新的文件组。
3)在“初始大小”部分指定文件的初始大小。
4)如果要指定文件的增长方式,可单击“自动增长”列中的图标按钮,然后从弹出的“自动增长设置”窗口(参见图3-4)中进行相应的设置。
5)在“路径”部分指定文件的存储位置。
可通过多次单击“添加”按钮添加多个文件。添加完成后单击“确定”按钮,完成添加文件操作,关闭“数据库属性”窗口。
- 用Transact-SQL语句实现
用Transact-SQL的ALTER DATABASE语句也可以实现扩大数据库空间的目的,包括增加新的文件和扩大已有文件的初始大小。
扩大数据库空间的ALTER DATABASE语句的语法格式为:
ALTER DATABASE database_name
{
<add_or_modify_files>
}
<add_or_modify_files>::=
{
ADD FILE <filespec> [ ,...n ]
[ TO FILEGROUP { filegroup_name | DEFAULT } ]
| ADD LOG FILE <filespec> [ ,...n ]
| MODIFY FILE <filespec>
}
其中各参数含义如下。
database_name:要修改的数据库名称。
::=:指定要添加或修改的文件。
ADD FILE:在数据库中添加新数据文件。
TO FILEGROUP { filegroup_name | DEFAULT }:说明要将指定文件添加到的文件组。如果指定了DEFAULT,则将文件添加到当前的默认文件组中。
:同CREATE DATABASE语句的。
ADD LOG FILE:在数据库中添加新日志文件。
MODIFY FILE:指定要修改的文件。一次只能更改一个属性。必须在中指定NAME,以标识要修改的文件。
通过MODIFY FILE选项还可以修改数据文件或日志文件的逻辑名称,可以将数据文件或日志文件移动到新的位置,关于具体实现方法,有兴趣的读者可参考SQL Server 2008联机丛书。
【例3-5】为“RShDB”数据库添加一个新的数据文件,逻辑文件名为RShDB_Data2,物理存储位置为E:Data文件夹,物理文件名为RShDB_Data2.ndf,初始大小为6MB,不自动增长。
ALTER DATABASE RShDB
ADD FILE
(
NAME = RShDB_Data2,
FILENAME = 'E:\Data\RShDB_Data2.ndf',
SIZE = 6MB,
FILEGROWTH = 0
)
【例3-6】修改Students数据库中主要数据文件Students的初始大小,将其初始大小改为8MB。
ALTER DATABASE Students
MODIFY FILE
(
NAME = Students,
SIZE = 8MB
)
【例3-7】为Students数据库加添加一个新的日志文件,逻辑文件名为Students_log1,物理存储位置为D:Data文件夹,物理文件名为Students_log1.ldf,初始大小为2MB,每次增加1MB,最多增加到10MB。
ALTER DATABASE Students
ADD LOG FILE
(
NAME = Students_log1,
FILENAME = 'D:\Data\Students_log1.ldf',
SIZE = 2MB,
FILEGROWTH = 1MB,
MAXSIZE = 10MB
)
3.4.2 收缩数据库空间
如果在分配给数据库的空间中存在着大量的空白,则势必造成磁盘空间的浪费,因为操作系统将空间分配给数据库后,就不再使用数据库的这些空间,不管这些空间中有多少“空闲”,操作系统都不会将这些空白空间收回。这种情况下就需要在数据库管理系统中进行收缩数据库空间的操作,以将多余的空白空间还给操作系统。造成数据库空间存在大量浪费的一种情况可能是当数据库运行一段时间后,由于删除了数据库中的大量数据,使数据库所需的空间减少,或者是由于之前对数据库中将要存储的数据量估计不够准确,造成初始空间过大。收缩数据库就是释放数据库中未使用的空间,并可将释放的空间交还给操作系统。
可以对数据文件和日志文件的空间进行收缩。而且可以成组或单独地手工收缩数据库文件,也可以通过设置数据库选项,使其按照指定的间隔自动收缩。
文件的收缩都是从末尾开始的。例如,假设某文件的大小是5GB,如果希望收缩到4GB,则数据库引擎将从文件的最后一个1GB开始释放尽可能多的空间。如果文件中被释放的空间部分包含使用过的数据页,则数据库引擎先将这些页重新放置到保留的空间部分,然后再进行收缩。只能将数据库收缩到没有剩余的可用空间为止。例如,如果某个大小为5GB 的文件中存有4GB的数据,则在对其进行收缩时,最多只能收缩到4GB。
如果希望数据库能够实现自动收缩,只需将该数据库的“自动收缩”选项设置为“True”即可。具体实现方法为:在数据库属性窗口的“选项”界面中,在“自动”部分的“自动收缩”选项对应的下拉列表框中选择“True”(如图3-14所示)。默认情况下,该选项被设置为“False”,表示不自动收缩。如果将“自动收缩”选项设置为“True”,则数据库引擎会定期检查数据库空间的使用情况,并减少数据库中文件的大小。该活动是在后台进行的,不会影响数据库中用户的活动。
手工收缩数据库分为两种情况,一种是收缩数据库中某个数据文件或日志文件的大小,另一种是收缩整个数据库中全部文件的大小。注意,当收缩整个数据库空间的大小时,收缩后数据库的大小不能小于创建数据库时指定的初始大小。例如,如果某数据库创建时的大小为10MB,后来增长到100MB,则该数据库最小只能收缩到10MB,即使删除了数据库的所有数据也是如此。若是收缩某个数据库文件,则可以将该文件收缩得比其初始大小更小。
手工收缩数据库可以通过SSMS工具图形化实现,也可以通过Transact-SQL语句实现。
- 用图形化方法收缩数据库
收缩数据库的操作包括收缩整个数据库的大小(即收缩其中的每个文件)和收缩指定文件的大小两种方式。
(1)收缩整个数据库的大小
在SQL Server Management Studio中图形化地收缩整个数据库的大小的步骤如下。
1)在SQL Server Management Studio中展开“数据库”节点。
2)在要收缩的数据库上单击鼠标右键,然后在弹出的快捷菜单中选择“任务”→“收缩”→“数据库”命令(如图3-15所示,这里假设收缩“Students”数据库),弹出如图3-16所示的窗口。
3)在如图3-16所示的窗口中:
“数据库大小”部分显示了已分配给数据库的空间(这里为16MB)和数据库的可用空间(这里为11.84MB)。
如果选中“在释放未使用的空间前重新组织文件,选中此选项可能会影响性能”复选框,则必须为“收缩后文件中的最大可用空间”指定一个值,表示收缩后数据库中空白空间占收缩后数据库全部空间的百分比,此值介于0~99之间。例如,假设某数据库当前大小是100MB,其中数据占20MB,若指定收缩百分比为50,则收缩后该数据库的大小将是40MB。如果不选中该复选框,则表示将数据文件中所有未使用的空间都释放给操作系统,并将文件收缩到最后分配的大小,而且不需要移动任何数据。默认情况下,该选项为未选中状态。
4)单击“确定”按钮即可实现收缩操作。这里单击“取消”按钮,不收缩数据库。
(2)收缩指定文件的大小
在SSMS中,用图形化的方法收缩某个文件大小的步骤如下。
1)在SSMS中展开“数据库”节点,在要收缩的数据库上单击鼠标右键,然后在弹出的快捷菜单中选择“任务”→“收缩”→“文件”命令(如图3-15所示,这里假设收缩“Students”数据库),弹出如图3-17所示的窗口。
2)在如图3-17所示的窗口中,可以进行如下设定:
在“文件类型”下拉列表框中可以指定要收缩的文件是数据文件还是日志文件(这里选择的是“数据”)。
如果收缩的是数据文件,可在“文件组”下拉列表框中指定要收缩文件所在的文件组(这里选择的是“PRIMARY”)。
在“文件名”下拉列表框中可以指定要收缩的具体文件,这里指定的是Students。
在“收缩操作”部分有如下选项。
“释放未使用的空间”:选中此选项,表示释放文件中所有未使用的空间给操作系统,并将文件收缩到上次分配的大小。这将减小文件的大小,但不移动任何数据。
“在释放未使用的空间前重新组织页”:若选中此选项,则必须指定“将文件收缩到”值,该值指定文件收缩的目标大小(假设这里指定的值是4)。
“通过将数据迁移到同一文件组中的其他文件来清空文件”:若选中此选项,则将指定文件中的所有数据移至同一文件组中的其他文件中,使该文件为空,之后就可以删除该空文件。
3)单击“确定”按钮,完成对文件的收缩操作。
- 用Transact-SQL语句收缩数据库
(1)收缩整个数据库的大小
收缩整个数据库大小的Transact-SQL语句是DBCC SHRINKDATABASE,其语法格式为:
DBCC SHRINKDATABASE
( 'database_name' | 0
[ ,target_percent ]
[ , { NOTRUNCATE | TRUNCATEONLY } ]
)
其中各参数含义如下。
'database_name' | 0:要收缩的数据库名称。如果指定0,则表示收缩的是当前正在使用的数据库。
target_percent:数据库收缩后的剩余可用空间百分比。
NOTRUNCATE:通过将已分配的页从文件末尾移动到文件前面的未分配页来压缩数据文件中的数据。使用该选项时target_percent是可选参数。使用该选项时文件末尾的可用空间不会返回给操作系统,文件的物理大小也不会更改。因此,指定NOTRUNCATE时,数据库看起来未收缩。NOTRUNCATE选项只适用于数据文件,日志文件不受影响。该选项类似于选中“在释放未使用的空间前重新组织文件。选中此选项可能会影响性能”复选框。
TRUNCATEONLY:将文件中任何未使用的空间释放给操作系统,并将文件收缩到最后分配的大小。该选项无须移动任何数据即可减小文件大小。使用TRUNCATEONLY时,将忽略target_percent选项。该选项类似于不选中“在释放未使用的空间前重新组织文件。选中此选项可能会影响性能”复选框。
【例3-8】收缩Students数据库,使该数据库中所有的文件都有20%的可用空间。
DBCC SHRINKDATABASE(students, 20)
注意:当收缩整个数据库的大小时,收缩后的所有文件的大小都不能小于创建这些文件时指定的初始大小,或者是上一次进行收缩文件操作时设置的大小。当对某个具体的文件进行收缩时则无此限制。不管是哪种收缩方法,收缩后的文件都不能小于其当前存放数据所占空间的大小。
(2)收缩指定文件的大小
收缩指定文件大小的Transact-SQL语句是DBCC SHRINKFILE,其语法格式为:
DBCC SHRINKFILE
(
'file_name'
{ [ , EMPTYFILE ]
| [ [ , target_size ] [ , { NOTRUNCATE | TRUNCATEONLY } ] ]
}
)
其中各参数含义如下。
'file_name':要收缩的数据库文件的逻辑名称。
target_size:指定收缩后文件的目标大小(用整数表示,单位为MB)。如果未指定,则DBCC SHRINKFILE 将文件大小减小到创建文件时指定的大小。该语句不会将文件收缩到小于文件中存储数据所需要的大小。例如,如果大小为10MB的数据文件中有7MB的数据,此时将target_size指定为6,则该语句只能将该文件收缩到7MB,而不能收缩到比7MB小的空间。
EMPTYFILE:将指定文件中的所有数据迁移到同一文件组的其他文件中,使该文件为空。将文件设置为空是为了方便删除该文件。当某文件有EMPTYFILE选项时,数据库引擎不会再将数据保存在该文件上。
NOTRUNCATE:将已分配的页从数据文件的末尾移动到该文件前面的未分配页。文件末尾的可用空间不会返回给操作系统,文件的物理大小也不会更改。因此,指定NOTRUNCATE 时,文件看起来未收缩。NOTRUNCATE 只适用于数据文件。日志文件不受影响。
TRUNCATEONLY:将文件中的所有未使用空间都释放给操作系统,并将文件收缩到最后一次分配的大小,从而减小文件的大小。该选项并不移动任何数据。使用TRUNCATEONLY时,将忽略target_size选项。TRUNCATEONLY 只适用于数据文件。
【例3-9】将Students数据库中的students_data1文件收缩到4MB。
DBCC SHRINKFILE (students_data1, 4)
3.4.3 添加和删除数据库文件
可以通过添加数据文件和日志文件的方法来扩大数据库空间,也可以通过删除文件的方法来减小数据库空间。
- 添加文件
SQL Server对每个文件组中的所有数据文件都使用按比例填充的策略,这使得各文件中存储的数据量与文件中的可用空间成正比,这种方式使得所有数据文件几乎是同时被填满的。例如,假设某文件组中有DataFile1、DataFile2和DataFile3三个数据文件,每个文件的大小分别为:10MB、20MB和30MB。设该文件组中的数据总量为30MB,则各文件中的数据量分别为:5MB、10MB和15MB。数据文件空间使用情况如图3-18所示。因此,当添加数据文件时,系统会立刻使用新添加的文件。
日志文件的使用方式与数据文件不同,日志文件彼此是相互独立的,没有文件组。在向日志文件写入信息时,使用的是填充到满的策略而不是按比例填充策略,即先填充第一个日志文件,第一个日志文件填满后,再填充第二个日志文件,依此类推。因此,当添加日志文件时,系统并不立刻使用该文件,直到其他文件被填充满。
向数据库添加文件时,可以指定文件的初始大小、存放位置、增长方式等属性,这同创建数据库时指定文件属性方法相同。也可以指定新添加的数据文件所属的文件组。
添加数据库文件的Transact-SQL语句是ALTER DATABASE,具体添加方法参见3.4.1节中对ALTER DATABASE语句的解释和示例。
- 删除文件
删除数据文件或日志文件是将该文件从数据库中删除。只有当文件中没有数据或日志信息,文件完全为空时,才可以从数据库中删除该文件。
若要让某个数据文件为空,需要将该数据文件中的数据移到同一文件组的其他文件中,这可使用DBCC SHRINKFILE语句并指定EMPTYFILE子句实现(参见3.4.2节)。执行了有EMPTYFILE子句的DBCC SHRINKFILE语句后,SQL Server就不允许再在该文件中放置数据,因此就可以删除该数据文件了。
但将日志信息从一个日志文件移动到另一个日志文件后并不能删除该日志文件。只有当日志文件中不包含任何活动或不活动的事务时,才可以从数据库中删除该日志文件。通过截断事务日志或者备份事务日志的方法可以清除日志文件中的事务记录。通过备份清除日志文件内容的实现方法将在本书第13章介绍。
删除数据库文件的Transact-SQL语句是ALTER DATABASE,其语法格式为:
ALTER DATABASE database_name
REMOVE FILE logical_file_name
其中:
database_name:要删除文件的数据库名。
logical_file_name:被删除文件的逻辑文件名。
【例3-10】删除Students数据库中的Students_data1文件。
ALTER DATABASE Students
REMOVE FILE Students_data1
【例3-11】删除Students数据库中的Students_log1文件。
ALTER DATABASE Students
REMOVE FILE Students_log1
3.4.4 创建和更改文件组
可以在首次创建数据库时创建文件组(参见3.2节),也可以在创建完数据库后添加新数据文件时创建文件组。注意,一旦将文件添加到文件组中,就不能再将这些文件移动到其他文件组中。
一个文件不能是多个文件组的成员。可以指定将表、索引和大型对象(LOB)数据放置到某个文件组中,这意味着这些对象的所有页都将从该文件组的文件中分配。
一个数据库最多可以创建32 767个文件组。文件组中只能包含数据文件,日志文件不能是文件组的一部分。
注意:文件组不能独立于数据库文件创建。文件组是在数据库中组织文件的一种管理机制。
创建和更改文件组可以用图形化方法实现,也可以用Transact-SQL语句实现。
- 用图形化方法实现
用图形化方法创建文件组的方法在3.2.1节已介绍,现在介绍添加新文件组的方法。
1)在SQL Server Management Studio中,在要添加文件组的数据库上单击鼠标右键,在弹出的快捷菜单中选择“属性”命令,然后在弹出的数据库属性窗口中的“选项页”部分选中“文件组”选项,出现的窗口形式如图3-12所示。
2)若要添加新的文件组,可单击“添加”按钮。单击“添加”按钮后,系统会在列表框最后增加一个新行,用户可在此指定文件组名和文件组属性,如图3-19所示。
3)若不需要某个文件组了,可选中该文件组,然后单击“删除”按钮。删除文件组会将文件组中包含的文件一起删掉。
注意:除非文件组为空,或者文件组中的文件全部为空,否则不要删除文件组。
4)定义好文件组后,单击“确定”按钮关闭此窗口。
之后,在向数据库中添加新数据文件时,就可以选用新文件组了。
- 用Transact-SQL语句实现
使用CREATE DATABASE语句可以在创建数据库时定义新的文件组,该语句及实现方法已在3.2.2节中介绍。使用ALTER DATABASE语句可以实现定义新的文件组和删除文件组。定义新文件组主要是为添加新数据文件使用的。
定义和删除文件组的ALTER DATABASE语句的语法格式为:
ALTER DATABASE database_name
{
| ADD FILEGROUP filegroup_name
| REMOVE FILEGROUP filegroup_name
| MODIFY FILEGROUP filegroup_name
{ <filegroup_updatability_option>
| DEFAULT
| NAME = new_filegroup_name
}
}
<filegroup_updatability_option>::=
{
{ READ_ONLY | READ_WRITE }
}
各参数含义如下。
ADD FILEGROUP filegroup_name:将文件组添加到数据库。
REMOVE FILEGROUP filegroup_name:从数据库中删除文件组。
MODIFY FILEGROUP filegroup_name { | DEFAULT | NAME = new_filegroup_name}:通过将状态设置为READ_ONLY或READ_WRITE,将文件组设置为数据库的默认文件组或者更改文件组名称来修改文件组。
:对文件组设置“只读”或“读/写”属性。
DEFAULT:将数据库默认文件组更改为filegroup_name。数据库中只能有一个文件组作为默认文件组。
NAME = new_filegroup_name:更改文件组名称为new_filegroup_name。
::=:将文件组设置为“只读”或“读/写”。
其中,
■ READ_ONLY:指定文件组为只读。不允许更新其中的对象。主文件组不能设置为只读。若要更改此状态,用户必须对数据库有独占访问权限。
■ READ_WRITE:指定文件组为可读/写的,即允许更新文件组中的对象。若要更改此状态,用户也必须对数据库有独占访问权限。
【例3-12】为Students数据库定义一个新的文件组,文件组名为NewFileGroup1,同时在该文件组中添加两个新数据文件,逻辑名分别为students_dat1和students_dat2,初始大小分别为4MB和6MB,均存放在D:Data文件夹中,不自动增长。
(1)创建文件组
ALTER DATABASE Students
ADD FILEGROUP NewFileGroup1
(2)添加新数据文件
ALTER DATABASE Students
ADD FILE
(
NAME = students_dat1,
FILENAME = 'D:\Data\students_dat1.ndf',
SIZE = 4MB,
FILEGROWTH = 0
),
(
NAME = students_dat2,
FILENAME = 'D:\Data\students_dat2.ndf',
SIZE = 6MB,
FILEGROWTH = 0
)
TO FILEGROUP NewFileGroup1
【例3-13】将Students数据库中的NewFileGroup1文件组设置为默认文件组。
ALTER DATABASE Students
MODIFY FILEGROUP NewFileGroup1 DEFAULT