最近断断续续看《Microsoft Sql server 2008 Internals》,中文名是《深入解析Microsoft Sql server 2008》,由于邀月拿到的是英文版,所以一边看,一边查字典,顺便把一些理解记下来,翻译或理解不对之处,敬请指出。[email protected]。欢迎交流。
这里邀月可以保证的是:这个系列95%以上的内容都是邀月根据原英文纯手工翻译,加上自己的理解和注释,没有借助任何翻译工具。除了已注明的出处 MSDN 之外,如有转载,请注明来自邀月工作室。
本系列文章预计约60-70篇,文章中所有示例,邀月均在SQL Server 2008环境下运行通过。
本书是讲述SQL Server关系数据库引擎内部机理和架构的权威指南。书中详细阐述了SQL Server处理查询、管理数据的相关内容,包括SQL Server架构和配置、跟踪/扩展事件、日志和恢复、索引、表格、查询优化、事务/并发以及DBCC。本书适合中高级数据库开发人员阅读。
首 先看的是第三章 “Databases and Database Files”--数据库和数据库文件,只所以写出来,是觉得这书读了还是有收获,以前的一些概念理解不对。简单的东西越要弄清楚,免得到时很丢人。呵呵。 本系列如无特别说明,均指SQL server 2008,邀月用的是Sql server 2008 sp1英文版。
一、一些基本概念:
1、一个SQL实例最多可以有32767个数据库。
2、一个数据库的大小可以从2MB到524272TB(terabytes)。
3、数据库中的对象集合(objects),包含表、视图、存储过程、约束,不超过2有31次方-1 ,直观点,就是超过20亿。
4、数据库文件有三类(Primary data files(.mdf)、Second data files(.ndf)、Log files(.ldf)
二、几类常用的数据库:
1、系统数据库。包括master,model,tempdb
2、 资源数据库。像mssqlsystemresource,msdb。前者一般位于E:/Program Files/Microsoft SQL Server/MSSQL10.AGRONET08/MSSQL/Binn下的mssqlsystemresource.mdf,约60M大。如我们熟悉 的
就 是该数据库的内置函数,本机查询结果为
Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (Intel X86) Mar 29 2009 10:27:29 Copyright (c) 1988-2008 Microsoft Corporation Enterprise Edition on Windows NT ****
3、示例数据库。如advertureworks,pubs,Northwind
三、创建数据库语句
1、创建一个数据库
view plain copy to clipboard print ?
- -- A CREATE DATABASE Example
- CREATE DATABASE Archive
- ON
- PRIMARY
- ( NAME = Arch1,
- FILENAME =
- 'c:/program files/microsoft sql server/mssql.1/mssql/data/archdat1.mdf',
- SIZE = 100MB,
- MAXSIZE = 200MB,
- FILEGROWTH = 20MB),
- ( NAME = Arch2,
- FILENAME =
- 'c:/program files/microsoft sql server/mssql.1/mssql/data/archdat2.ndf',
- SIZE = 10GB,
- MAXSIZE = 50GB,
- FILEGROWTH = 250MB)
- LOG ON
- ( NAME = Archlog1,
- FILENAME =
- 'c:/program files/microsoft sql server/mssql.1/mssql/data/archlog1.ldf',
- SIZE = 2GB,
- MAXSIZE = 10GB,
- FILEGROWTH = 100MB);
2、创建一个文件组FileFroup
view plain copy to clipboard print ?
- -- A FILEGROUP CREATION Example
- CREATE DATABASE Sales
- ON PRIMARY
- ( NAME = salesPrimary1,
- FILENAME =
- 'c:/program files/microsoft sql server/mssql.1/mssql/data/salesPrimary1.mdf',
- SIZE = 100,
- MAXSIZE = 500,
- FILEGROWTH = 100 ),
- ( NAME = salesPrimary2,
- FILENAME =
- 'c:/program files/microsoft sql server/mssql.1/mssql/data/salesPrimary2.ndf',
- SIZE = 100,
- MAXSIZE = 500,
- FILEGROWTH = 100 ),
- FILEGROUP SalesGroup1
- ( NAME = salesGrp1Fi1e1,
- FILENAME =
- 'c:/program files/microsoft sql server/mssql.1/mssql/data/salesGrp1Fi1e1.ndf',
- SIZE = 500,
- MAXSIZE = 3000,
- FILEGROWTH = 500 ),
- ( NAME = salesGrp1Fi1e2,
- FILENAME =
- 'c:/program files/microsoft sql server/mssql.1/mssql/data/salesGrp1Fi1e2.ndf',
- SIZE = 500,
- MAXSIZE = 3000,
- FILEGROWTH = 500 ),
- FILEGROUP SalesGroup2
- ( NAME = salesGrp2Fi1e1,
- FILENAME =
- 'c:/program files/microsoft sql server/mssql.1/mssql/data/salesGrp2Fi1e1.ndf',
- SIZE = 100,
- MAXSIZE = 5000,
- FILEGROWTH = 500 ),
- ( NAME = salesGrp2Fi1e2,
- FILENAME =
- 'c:/program files/microsoft sql server/mssql.1/mssql/data/salesGrp2Fi1e2.ndf',
- SIZE = 100,
- MAXSIZE = 5000,
- FILEGROWTH = 500 )
- LOG ON
- ( NAME = 'Sales_log',
- FILENAME =
- 'c:/program files/microsoft sql server/mssql.1/mssql/data/saleslog.ldf',
- SIZE = 5MB,
- MAXSIZE = 25MB,
- FILEGROWTH = 5MB );
3、进阶:利用FileGroup实现分区数据的物理存放。
分三步:第一步:创建FileGroup
view plain copy to clipboard print ?
- Create database DemoFileGroup
- go
- use DemoFileGroup
- go
- alter database DemoFileGroup add filegroup [fg01]
- go
- alter database DemoFileGroup add filegroup [fg02]
- go
- alter database DemoFileGroup add filegroup [fg03]
- go
- alter database DemoFileGroup add filegroup [fg04]
- go
- alter database DemoFileGroup add filegroup [fg05]
- go
- alter database DemoFileGroup
- add file
- (name='fg01',
- filename='c:/fg01.ndf',
- size=5mb)
- to filegroup [fg01]
- go
- alter database DemoFileGroup
- add file
- (name='fg02',
- filename='I:/fg02.ndf',
- size=5mb)
- to filegroup [fg02]
- go
- alter database DemoFileGroup
- add file
- (name='fg03',
- filename='C:/fg03.ndf',
- size=5mb)
- to filegroup [fg03]
- go
- alter database DemoFileGroup
- add file
- (name='fg04',
- filename='C:/fg04.ndf',
- size=5mb)
- to filegroup [fg04]
- go
- alter database DemoFileGroup
- add file
- (name='fg05',
- filename='C:/fg05.ndf',
- size=5mb)
- to filegroup [fg05]
- go
第二步:创建partition function,这里偷懒从Northwind数据库中插入一些数据。
view plain copy to clipboard print ?
- -----------------------------------------------------
- -------Create the partition function
- -----------------------------------------------------
- CREATE PARTITION FUNCTION CustomersCountryPFN(nvarchar(50))
- AS
- RANGE LEFT FOR VALUES ('France', 'Germany', 'Italy', 'Spain' )
- GO
- -----------------------------------------------------
- ------Create the partition scheme
- -----------------------------------------------------
- CREATE PARTITION SCHEME [CustomersCountryPScheme]
- AS
- PARTITION CustomersCountryPFN TO ([fg01], [fg02], [fg03],[fg04],[fg05])
- GO
- -------------------------------------------------------
- -- ----Create the Customers table on the partition scheme
- -------------------------------------------------------
- CREATE TABLE [dbo].[Customers](
- [CustomerID] [nchar](5) NOT NULL,
- [CompanyName] [nvarchar](40) NOT NULL,
- [ContactName] [nvarchar](30) NULL,
- [ContactTitle] [nvarchar](30) NULL,
- [Address] [nvarchar](60) NULL,
- [City] [nvarchar](15) NULL,
- [Region] [nvarchar](15) NULL,
- [PostalCode] [nvarchar](10) NULL,
- [Country] [nvarchar](50) NULL,
- [Phone] [nvarchar](24) NULL,
- [Fax] [nvarchar](24) NULL
- ) ON CustomersCountryPScheme (Country)
- -------------------------------------------------------
- -- Add data
- -------------------------------------------------------
- INSERT Customers
- SELECT *
- FROM northwind.dbo.customers
- WHERE Country IN ('France', 'Germany', 'Italy', 'Spain', 'UK' )
第三步:察看数据记录在不同分区和文件组的存放位置。
view plain copy to clipboard print ?
- ------------------------------------------------------
- -- Verify Partition Ranges
- -------------------------------------------------------
- SELECT $partition.CustomersCountryPFN(Country)
- AS 'Partition Number'
- , count(*) AS 'Rows In Partition'
- FROM Customers
- GROUP BY $partition.CustomersCountryPFN(Country)
- ORDER BY 'Partition Number'
- GO
- -------------------------------------------------------
- -- To see the partition information row by row
- -------------------------------------------------------
- SELECT CompanyName, Country,
- $partition.CustomersCountryPFN(Country)
- AS 'Partition Number'
- FROM Customers
- GO
效果:实现了按照分区函数指定的条件下数据记录的物理分开存放。这个效果很酷!


发现,一个问题:
view plain copy to clipboard print ?
- alter database DemoFileGroup
- add file
- (name='fg3',
- filename='I:/fg3.ndf',
- size=5mb)
- to filegroup [fg3]
- go
以上语句无法在NTFS分区 执行,提示:
view plain copy to clipboard print ?
- Msg 5009, Level 16, State 1, Line 1
- One or more files listed in the statement could not be found or could not be initialized.
- Msg 5123, Level 16, State 1, Line 1
- CREATE FILE encountered operating system error 5(拒绝访问。) while attempting to open or create the physical file 'D:/fg3.ndf'.
很奇怪这个问题,终于找到答案。原来是FileStream权限不足,进入MSSQLServer配置管理器,进行如图设置即可

更详细的信息,请参看MSDN
SQL Server 2005 中的分区表和索引: http://msdn.microsoft.com/zh-cn/library/ms345146%28SQL.90%29.aspx#EHAA:
宋立桓的webcast讲座也不错:http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032327866&Culture=zh-CN
四、文件收缩
文件收缩有两个命令:
(一) DBCC SHRINKFILE:收缩当前数据库的指定数据或日志文件的大小,或通过将数据从指定的文件移动到相同文件组中的其他文件来清空文件,以允许从数据库中删除该文件。文件大小可以收缩到比创建该文件时所指定的大小更小。这样会将最小文件大小重置为新值。
关于文件不收缩或收缩被阻塞,请查看MSDN http://msdn.microsoft.com/zh-cn/library/ms189493.aspx
值得注意的是:
1、强烈建议不采用自动收缩文件。在SQL Server后续版本中将取消自动收缩选项。因为这必然会引起所有物理文件的整理,并根据要求截断日志流,并将新文件移动到新位置,,在某些情况下可能引起文件的破坏,并对系统的性能造成影响。
2、DBCC SHRINKFILE,有两个限制:一是磁盘的空间大小,如15M的文件指定收缩为12M,空间足够,则将最后3M强行截断,不保证数据的完整性,而这 3M空间立即被文件系标志为自由空间使用;空间不够,则不操作。二是文件实际使用大小限制。如10M文件要收缩为5M,但文件实际使用为7M,则最终收缩 为7M而不是5M。
(二)DBCC SHRINKDATABASE
收缩指定数据库中的数据文件和日志文件的大小。http://msdn.microsoft.com/zh-cn/library/ms190488.aspx
有些时候我们经常看到收缩命令不起作用,或者文件大小没有任何变化,请注意以下几点:
1、DBCC SHRINKDATABASE不能收缩到数据库的最小MB数, 在创建数据库时指定最小为10M,那第无论如何都不会收缩到10M以下。此时应该用DBCC SHRINKFILE收缩单个文件的大小。
2、 收缩参数target_percent,是指收缩后数据库可以留给文件的百分比。如100M的数据库文件,收缩参数百分比为25%。假如已经使用60M, 则SQL会收缩文件到80M,即80M*25%=20M的自由空间,原有的60M不变。假如已经使用80M,则此时数据库不收缩。因为已经没有收缩空间。
3、 DBCC SHRINKDATABASE是基于文件系统的,所以其实执行的还是DBCC SHRINKFILE,只不过执行的时候把所有FileGroup统一处理而已。
先看到这里,下面将继续了解数据库文件的相关内容。
《Microsoft Sql server 2008 Internals》读书笔记--目录索引