SQL Server 数据类型详解
A. 整数
整数型数据包括bigint 型、int 型、smallint 型和tinyint 型。
·bigint 型数据的存储大小为8 个字节,共64 位。其中63 位用于表示数值的大小,1 位用于表示符号。bigint 型数据可以存储的数值范围是-2 63 ~2 63 -1 ,即-9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807 。
·int 型数据的存储大小为4 个字节,共32 位。其中31 位用于表示数值的大小,1 位用于表示符号。int 型数据存储的数值范围是-2 31 ~2 31 -1 ,即-2 147 483 648 ~ 2 147 483 647 。
·smallint 型数据的存储大小为2 个字节,共16 位。其中15 位用于表示数值的大小,1 位用于表示符号。smallint 型数据存储的数值范围是-2 15 ~2 15 -1 ,即-32 768 ~ 32 767 。
·tinyint 型数据的存储大小只有1 个字节,共8 位,全部用于表示数值的大小,由于没有符号位,所以tinyint 型的数据只能表示正整数。tinyint 型数据存储的数值范围是-2 7 ~2 7 -1 ,即-256 ~255 。
B. 浮点
浮点数据类型用于存储十进制小数。在SQL Server 2000 中浮点数值的数据采用上舍入(Round up) 的方式进行存储,也就是说,要舍入的小数部分不论其大小,只要是一个非零的数,就要在该数字的最低有效位上加1 ,并进行必要的进位。由于浮点数据为近似值,所以并非数据类型范围内的所有数据都能精确地表示。
浮点数据类型包括real 型、float 型、decimal 型和numeric 型。
·real 型数据的存储大小为4 个字节,可精确到小数点后第7 位数字。这种数据类型的数据存储范围为从-3.40E+38 ~ -1.18E-38 ,0 和1.18E-38 ~ 3.40E+38 。
·float 型的数据存储大小为8 个字节,可精确到小数点后第15 位数字。这种数据类型的数据存储范围为从-1.79E+308 ~ -2.23E-308 ,0 和2.23E+308 ~ 1.79E+308 。
float 型的数据可写成float[(n)] 的形式。其中n 是1 ~15 之间的整数值,指定float 型数据的精度。当n 为1 ~7 时,实际上用户定义了一个real 型的数据,系统用4 个字节存储;当n 为8 ~15 时,系统认为它是个float 型的数据,用8 个字节存储它。这样既增强了数据定义的灵活性,又节省了空间。
·decimal 数据类型和numeric 数据类型的功能完全一样,它们都可以提供小数所需要的实际存储空间,但也有一定的限制,用户可以用2 ~17 个字节来存储数据,取值范围是-1038+1 ~ 1038-1 。
decimal 型数据和numeric 型数据的定义格式为decimal[(p,[s])] 和numeric[(p,[s])] ,其中p 表示可供存储的值的总位数( 不包括小数点) ,默认值为18 ;s 表示小数点后的位数,默认值为0 ;参数之间的关系是0 ≤s ≤p 。例如:decimal(15,5) 表示共有15 位数,其中整数10 位,小数5 位。
C. 二进制
二进制数据类型用于存储二进制数据,包括binary 型、varbinary 型和image 型。
·binary 型是固定长度的二进制数据类型,其定义形式为binary(n) ,其中n 表示数据的长度,取值为1 ~8 000 。在使用时应指定binary 型数据的大小,默认值为1 个字节。binary 类型的数据占用n+4 个字节的存储空间。
在输入数据时必须在数据前加上字符“0X ”作为二进制标识。例如:要输入“abc ”则应输入“0Xabc ”。若输入的数据位数为奇数,则系统会自动在起始符号“0X ”的后面添加一个0 。如上述输入“0Xabc ”后,系统会自动变为“0X0abc ”。
·varbinary 型是可变长度的二进制数据类型,其定义形式为varbinary(n) ,其中n 表示数据的长度,取值为1 ~8 000 。如果输入的数据长度超出n 的范围,则系统会自动截掉超出部分。
varbinary 型具有变动长度的特性,因为varbinary 型数据的存储长度为实际数值长度+4 个字节。当binnary 型数据允许null 值时,将被视为varbinary 型的数据。
一般情况下,由于binary 型的数据长度固定,因此它比varbinary 型的数据处理速度快。
·image 型的数据也是可变长度的二进制数据,其最大长度为2 31 -1(2 147 483 647) 个字节。
D. 逻辑
逻辑数据类型只有一种bit 型。bit 数据类型只占用1 个字节的存储空间,其值为0 和1 。只要输入的值为非0 ,系统都会当作1 处理。另外,bit 型不能定义为null 值。
E. 字符
字符数据类型是使用最多的数据类型,它可以用来存储各种字母、数字符号、特殊符号等。一般情况下,使用字符类型数据时,须在数据的前后加上单引号或双引号。字符数据类型包括char 型、nchar 型、varchar 型和nvarchar 型。
·char 型是固定长度的非Unicode 字符数据类型,在存储时每个字符和符号占用一个字节的存储空间。其定义形式为char[(n)] ,其中n 表示所有字符所占的存储空间,取值为1 ~8 000 ,即可容纳8 000 个ANSI 字符,默认值为1 。若输入的数据字符数小于n 定义的范围,则系统自动在其后添加空格来填满设定好的空间;若输入的数据字符数超过n 定义的范围,则系统自动截掉超出部分。
·nchar 型是固定长度的Unicode 字符数据类型,由于Unicode 标准规定在存储时每个字符和符号占用2 个字节的存储空间,因此nchar 型的数据比char 型数据多占用一倍的存储空间。其定义形式为nchar[(n)] ,其中n 表示所有字符所占的存储空间,取值为1 ~4 000 ,即可容纳4 000 个Unicode 字符,默认值为1 。
使用Unicode 标准字符集的好处是由于它使用两个字节作存储单位,使得一个存储单位的容量大大增加,这样就可以将全世界的语言文字都囊括在内。当用户在一个数据列中同时输入不同语言的文字符号时,系统不会出现编码冲突。
·varchar 型是可变长度的非Unicode 字符数据类型。其定义形式为varchar[(n)] 。它与char 型类似,n 的取值范围是1 ~8 000 。由于varchar 型具有可变长度的特性,所以varchar 型数据的存储长度为实际数值的长度。如果输入数据的字符数小于n 定义的长度,系统也不会像char 型那样在数据后面用空格填充;但是如果输入的数据长度大于n 定义的长度,系统会自动截掉超出部分。
一般情况下,由于char 型的数据长度固定,因此它比varchar 型数据的处理速度快。
·nvarchar 型是可变长度的Unicode 字符数据类型,其定义形式为nvarchar[(n)] 。由于它采用了Unicode 标准字符集,因此n 的取值范围是从1 ~4 000 。nvarchar 型的其他特性与varchar 类型相似。
F. 文本和图形
文本和图形数据类型是用于存储大量的非Unicode 和Unicode 字符以及二进制数据的固定长度和可变长度数据类型,包括text 型、ntext 型和image 型。
·text 型是用于存储大量非Unicode 文本数据的可变长度数据类型,其容量理论上为2 31 -1(2 147 483 647) 个字节。在实际应用时需要视硬盘的存储空间而定。
在SQL Server 2000 以前的版本中,数据库中一个text 对象存储的实际上是一个指针,它指向一个以8KB 为单位的数据页。这些数据页是动态增加并被逻辑连接起来的。在SQL Server 2000 中,则将text 和image 型的数据直接存放到表的数据行中,而不是存放到不同的数据页中。这样就减少了用于存储text 和image 类型的空间,并相应减少了磁盘处理这类数据的I/O 数量。
·ntext 型是用于存储大量Unicode 文本数据的可变长度数据类型,其理论容量为230-1(1 073 741 823) 个字节。ntext 型的其他用法与text 型基本一样。
·image 型是用于存储大量二进制数据的可变长度数据类型,其理论容量为231-1 (2 147 483 647) 个字节。Image 型数据的存储模式与text 型数据相同,通常用来存储图形等OLE 对象。在输入数据时,与输入二进制数据一样,必须在数据前加上起始符号“0X ”作为二进制标识。
G. 日期和时间
日期和时间数据类型代表日期和一天内的时间,包括datetime 型和smalldatetime 型。
·datetime 型是用于存储日期和时间的结合体的数据类型。它可以存储从公元1753 年1 月1 日零时起到公元9999 年12 月31 日23 时59 分59 秒之间的所有日期和时间,其精确度可达3% 秒。
datetime 型数据所占用的存储空间为8 个字节,其中前4 个字节用于存储1900 年1 月1 日以前或以后的天数,数值分正负,正数表示在此日期之后的日期,负数表示在此日期之前的日期;后4 个字节用于存储从此日零时起所指定的时间经过的毫秒数。如果在输入时省略了时间部分,则系统将默认为12:00:00:000AM ;如果省略了日期部分,系统将默认为1900 年1 月1 日。
·smalldatetime 型与datetime 型相似,但其存储的日期时间范围较小,从1900 年1 月1 日到2079 年6 月6 日。它的精度也较低,只能精确到分钟级,其分钟个位上的值是根据秒数并以30 秒为界四舍五入得到的。
Smalldatetime 型数据所占用的存储空间为4 个字节,其中前两个字节存储从基础日期1900 年1 月1 日以来的天数,后两个字节存储此日零时起所指定的时间经过的分钟数。
H. 货币
货币数据类型用于存储货币或现金值,包括money 型和smallmoney 型。在使用货币数据类型时,应在数据前加上货币符号,以便系统辨识其为哪国的货币,如果不加货币符号,则系统默认为“¥”。
·money 型是一个有4 位小数的decimal 值,其取值从-2 63 (-9 223 372 036 854 775 808) ~2 63 -1(+9 223 372 036 854 775 807) ,精确到货币单位的千分之十。存储大小为8 个字节。
·smallmoney 型货币数据值介于-2 147 483 648 ~+2 147 483 647 之间,精确到货币单位的千分之十。存储大小为 4 个字节。
I. 特定
SQL Server 2000 中包含了一些用于数据存储的特殊数据类型,包括timestamp 型和 uniqueidentifier 型。
·timestamp 数据类型提供数据库范围内的惟一值,它相当于binary(8) 或varbinary(8) ,但当它所定义的列在进行更新或插入数据行操作时,此列的值会自动更新。每个数据库表中只能有一个timestamp 型数据列。如果表中的列名为“timestamp ”,则该列的类型将被自动定义为timestamp 型。
·uniqueidentifier 数据类型用于存储一个16 位的二进制数据,此数据称为全局惟一标识符(Globally Unique Identifier ,GUID) 。此数据由SQL Server 2000 的NEWID() 函数产生,在全球各地的计算机经由此函数产生的数字不会相同。
J. 用户自定义
sysname 数据类型是系统提供给用户的,便于用户自定义的数据类型。该数据类型被定义为NVARCHAR(128) ,即它可以存储128 个Unicode 字符或256 个一般字符。
K. 新增数据类型
前面讲到过SQL Server 2000 新增了3 种数据类型:bigint 型、sql_variant 型和table 型。其中bigint 型已经在整数类型中介绍过了。
·sql_variant 型是一种存储SQL Server 支持的各种数据类型(text 、ntext 、timestamp 和sql_variant 除外) 值的数据类型。此数据类型大大方便了SQL Server 的开发工作。
·table 型用于存储对表或视图处理后的结果集。table 数据类型不适用于表中的列,而只能用于Transact-SQL 变量和用户定义函数的返回值。这一类型使得变量可以存储一个表,从而使函数或过程返回查询结果更加方便快捷。
(1) 二进制数据类型
二进制数据包括 Binary 、Varbinary 和 Image
Binary 数据类型既可以是固定长度的(Binary), 也可以是变长度的。
Binary[(n)] 是 n 位固定的二进制数据。其中,n 的取值范围是从 1 到 8000 。其存储窨的大小是 n + 4 个字节。
Varbinary[(n)] 是 n 位变长度的二进制数据。其中,n 的取值范围是从 1 到 8000 。其存储窨的大小是 n + 4 个字节,不是n 个字节。
在 Image 数据类型中存储的数据是以位字符串存储的,不是由 SQL Server 解释的,必须由应用程序来解释。例如,应用程序可以使用BMP 、TIEF 、GIF 和 JPEG 格式把数据存储在 Image 数据类型中。
(2) 字符数据类型
字符数据的类型包括 Char ,Varchar 和 Text
字符数据是由任何字母、符号和数字任意组合而成的数据。
Varchar 是变长字符数据,其长度不超过 8KB 。Char 是定长字符数据,其长度最多为 8KB 。超过 8KB 的ASCII 数据可以使用Text 数据类型存储。例如,因为 Html 文档全部都是 ASCII 字符,并且在一般情况下长度超过 8KB ,所以这些文档可以 Text 数据类型存储在SQL Server 中。
(3)Unicode 数据类型
Unicode 数据类型包括 Nchar,Nvarchar 和Ntext
在 Microsoft SQL Server 中,传统的非 Unicode 数据类型允许使用由特定字符集定义的字符。在 SQL Server 安装过程中,允许选择一种字符集。使用 Unicode 数据类型,列中可以存储任何由Unicode 标准定义的字符。在 Unicode 标准中,包括了以各种字符集定义的全部字符。使用Unicode 数据类型,所战胜的窨是使用非 Unicode 数据类型所占用的窨大小的两倍。
在 SQL Server 中,Unicode 数据以 Nchar 、Nvarchar 和 Ntext 数据类型存储。使用这种字符类型存储的列可以存储多个字符集中的字符。当列的长度变化时,应该使用Nvarchar 字符类型,这时最多可以存储 4000 个字符。当列的长度固定不变时,应该使用 Nchar 字符类型,同样,这时最多可以存储4000 个字符。当使用 Ntext 数据类型时,该列可以存储多于 4000 个字符。
(4) 日期和时间数据类型
日期和时间数据类型包括 Datetime 和 Smalldatetime 两种类型
日期和时间数据类型由有效的日期和时间组成。例如,有效的日期和时间数据包括“4/01/98 12:15:00:00:00 PM” 和“1:28:29:15:01AM 8/17/98” 。前一个数据类型是日期在前,时间在后一个数据类型是霎时间在前,日期在后。在 Microsoft SQL Server 中,日期和时间数据类型包括Datetime 和 Smalldatetime 两种类型时,所存储的日期范围是从 1753 年 1 月 1 日开始,到9999 年12 月 31 日结束( 每一个值要求 8 个存储字节) 。使用 Smalldatetime 数据类型时,所存储的日期范围是 1900 年 1 月 1 日 开始,到 2079 年 12 月 31 日结束( 每一个值要求 4 个存储字节) 。
日期的格式可以设定。设置日期格式的命令如下:
Set DateFormat {format | @format _var|
其中,format | @format_var 是日期的顺序。有效的参数包括 MDY 、DMY 、YMD 、YDM 、MYD 和 DYM 。在默认情况下,日期格式为MDY 。
例如,当执行 Set DateFormat YMD 之后,日期的格式为年 月 日 形式; 当执行 Set DateFormat DMY 之后,日期的格式为日 月有年 形式
(5) 数字数据类型
数字数据只包含数字。数字数据类型包括正数和负数、小数( 浮点数) 和整数
整数由正整数和负整数组成,例如 39 、25 、0-2 和 33967 。在 Micrsoft SQL Server 中,整数存储的数据类型是 Int ,Smallint 和 Tinyint 。Int 数据类型存储数据的范围大于 Smallint 数据类型存储数据的范围,而 Smallint 据类型存储数据的范围大于Tinyint 数据类型存储数据的范围。使用 Int 数据狗昔存储数据的范围是从 -2 147 483 648 到 2 147 483 647( 每一个值要求4 个字节存储空间) 。使用 Smallint 数据类型时,存储数据的范围从 -32 768 到 32 767( 每一个值要求2 个字节存储空间) 。使用Tinyint 数据类型时,存储数据的范围是从0 到255( 每一个值要求1 个字节存储空间) 。
精确小娄数据在 SQL Server 中的数据类型是 Decimal 和 Numeric 。这种数据所占的存储空间根据该数据的位数后的位数来确定。
在SQL Server 中,近似小数数据的数据类型是 Float 和 Real 。例如,三分之一这个分数记作。3333333 ,当使用近似数据类型时能准确表示。因此,从系统中检索到的数据可能与存储在该列中数据不完全一样。
(6) 货币数据表示正的或者负的货币数量 。
在 Microsoft SQL Server 中,货币数据的数据类型是Money 和 Smallmoney
Money 数据类型要求 8 个存储字节,Smallmoney 数据类型要求 4 个存储字节。
(7) 特殊数据类型
特殊数据类型包括前面没有提过的数据类型。特殊的数据类型有3 种,即 Timestamp 、Bit 和 Uniqueidentifier 。
Timestamp 用于表示SQL Server 活动的先后顺序,以二进投影的格式表示。Timestamp 数据与插入数据或者日期和时间没有关系。
Bit 由 1 或者 0 组成。当表示真或者假、ON 或者 OFF 时,使用 Bit 数据类型。例如,询问是否是每一次访问的客户机请求可以存储在这种数据类型的列中。
Uniqueidentifier 由 16 字节的十六进制数字组成,表示一个全局唯一的。当表的记录行要求唯一时,GUID 是非常有用。例如,在客户标识号列使用这种数据类型可以区别不同的客户。
2. 用户定义的数据类型
用户定义的数据类型基于在 Microsoft SQL Server 中提供的数据类型。当几个表中必须存储同一种数据类型时,并且为保证这些列有相同的数据类型、长度和可空性时,可以使用用户定义的数据类型。例如,可定义 一种称为 postal_code 的数据类型,它基于 Char 数据类型。
当创建用户定义的数据类型时,必须提供三个数:数据类型的名称、所基于的系统数据类型和数据类型的可空性。
(1) 创建用户定义的数据类型
创建用户定义的数据类型可以使用 Transact-SQL 语句。系统存储过程 sp_addtype 可以来创建用户定义的数据类型。其语法形式如下:
sp_addtype {type},[,system_data_bype][,'null_type']
其中,type 是用户定义的数据类型的名称。system_data_type 是系统提供的数据类型,例如 Decimal 、Int 、Char 等等。 null_type 表示该数据类型是如何处理空值的,必须使用单引号引起来,例如'NULL' 、'NOT NULL' 或者'NONULL' 。
例子:
Use cust
Exec sp_addtype ssn,'Varchar(11)',"Not Null'
创建一个用户定义的数据类型 ssn ,其基于的系统数据类型是变长为11 的字符,不允许空。
例子:
Use cust
Exec sp_addtype birthday,datetime,'Null'
创建一个用户定义的数据类型 birthday ,其基于的系统数据类型是 DateTime ,允许空。
例子:
Use master
Exec sp_addtype telephone,'varchar(24),'Not Null'
Eexc sp_addtype fax,'varchar(24)','Null'
创建两个数据类型,即 telephone 和 fax
(2) 删除用户定义的数据类型
当用户定义的数据类型不需要时,可删除。删除用户定义的数据类型的命令是 sp_droptype {'type'} 。
例子:
Use master
Exec sp_droptype 'ssn'
注意:当表中的列还正在使用用户定义的数据类型时,或者在其上面还绑定有默认或者规则时,这种用户定义的数据类型不能删除。
SQLServer 中易混淆的数据类型
SQL Server 中易混淆的数据类型
> 近来在做数据库设计,有时候真弄不清SQL2000 里的数据类型,所以摘了这篇文章。
(1)char 、varchar 、text 和nchar 、nvarchar 、ntext
char 和varchar 的长度都在1 到8000 之间,它们的区别在于char 是定长字符数据,而varchar 是变长字符数据。所谓定长就是长度固定的,当输入的数据长度没有达到指定的长度时将自动以 英文空格在其后面填充,使长度达到相应的长度; 而变长字符数据则不会以空格填充。text 存储可变长度的非Unicode 数据,最大长度为2^31-1 (2,147,483,647) 个字符。
后面三种数据类型和前面的相比,从名称上看只是多了个字母"n" ,它表示存储的是Unicode 数据类型的字符。写过程序的朋友对 Unicode 应该很了解。字符中,英文字符只需要一个字节存储就足够了,但汉字众多,需要两个字节存储,英文与汉字同时存在时容易造成混 乱,Unicode 字符集就是为了解决字符集这种不兼容的问题而产生的,它所有的字符都用两个字节表示,即英文字符也是用两个字节表示。nchar 、 nvarchar 的长度是在1 到 4000 之间。和char 、varchar 比较:nchar 、nvarchar 则最多存储4000 个字符,不论是英文还是汉字; 而char 、 varchar 最多能存储8000 个英文,4000 个汉字。可以看出使用nchar 、nvarchar 数据类型时不用担心输入的字符是英文还是汉字,较为 方便,但在存储英文时数量上有些损失。
(2)datetime 和smalldatetime
datetime :从1753 年1 月1 日到9999 年12 月31 日的日期和时间数据,精确到百分之三秒。
smalldatetime :从1900 年1 月1 日到2079 年6 月6 日的日期和时间数据,精确到分钟。
(3)bitint 、int 、smallint 、tinyint 和bit
bigint :从-2^63(-9223372036854775808) 到2^63-1(9223372036854775807) 的整型数据。
int :从-2^31(-2,147,483,648) 到2^31-1(2,147,483,647) 的整型数据。
smallint :从-2^15(-32,768) 到2^15-1(32,767) 的整数数据。
tinyint :从0 到255 的整数数据。
bit :1 或0 的整数数据。
(4)decimal 和numeric
这两种数据类型是等效的。都有两个参数:p( 精度) 和s( 小数位数) 。p 指定小数点左边和右边可以存储的十进制数字的最大个数,p 必须是从 1 到38 之间的值。s 指定小数点右边可以存储的十进制数字的最大个数,s 必须是从0 到p 之间的值,默认小数位数是0 。
(5)float 和real
float :从-1.79^308 到1.79^308 之间的浮点数字数据。
real :从-3.40^38 到3.40^38 之间的浮点数字数据。在SQL Server 中,real 的同义词为float(24) 。
SQL Server 最佳索引策略
SQL Server 为大多数数据类型只提供了两种索引类型—— 聚簇和非聚簇。SQL Server 也支持全文检索索引和XML 索引,但这些只对特定的数据类型。
为你的聚簇索引选择合适的列或列的集合是很关键的。因为表的数据物理上是按聚簇索引列的值排序的。你可以在每一个表上只创建一个单独的聚簇索引。非聚簇索引参照聚簇索引键( 数据值) 来决定每条记录的物理位置。
建议你在不经常改变而要经常查询和具有较少数据类型的列上创建聚簇索引。在很多情况下,在序号列上建聚簇索引是最好的选择,因为序号值是被经常查询的 —— 每条记录有一个唯一的序号值—— 并且它们从来不更新,而且是用SMALLINT ,INT 或BIGINT 数据类型创建的。
然而一个基于它的序号列的表从来没有被查询过的情况也不罕见。如果这样,要仔细考虑数据一般是怎样获取的,也许是通过一个外键关联到另一个表,或者是通过一个特征列。通常,你可以通过在获取数据时最经常使用的列或列的集合上创建聚簇索引来改进性能。
一些开发人员喜欢创建复合聚簇索引。这些涉及几列,它们结合起来唯一标识每一条记录。这也许听起来是个很好的做法,因为序号列没有业务意义,但是其它的 列—— 像聘用日期、部门名称和车辆识别号码—— 立即转化为应用用户可以理解的意思。然而,从性能的角度看,你应该避免采用复合聚簇索引。
再次,索引越少,SQL Server 就能越快的扫描或搜索。你可能发现对于一个小的数据集,复合索引执行的相对要好些。但是随着用户数目的增长,你肯定会遇到问题。
在你看到建立恰当的索引所到来的性能优势之后,你可能会觉得你的工作结束了。但是随着数据的增加、修改和从数据库中删除,每个索引变得支离破碎。破碎程度越高,你的索引起的作用越低。现在你需要执行一个删除你的索引碎片的计划来保证它们的有效性。
在SQL Server 的前一版本中,从大索引( 表具有几百万行记录) 中删除碎片经常要求停机。所幸SQL Server2005 支持在线索引重建,这使得你的工作相对容易。但是记住,重建索引仍然要求tempdb 数据库具有系统资源和空间。如果可能,安排在用户活动最少的时间段做索引维护。
这篇文章引自数据库性能规划。
SQL Server 数据库设计师和管理员如果想使他们的应用从开始就运行的很好,那么他们有很多选择。为了确保很好的数据库性能,在设计阶段作好的选择是很重要的。在本期的SQL Server INSIDER 杂志中,专家Baya Pavliashvili 讨论了怎样决定数据库设计,从而优化性能。设计一个数据库包括适当的:
数据模型
数据类型
索引策略
代码模块
高可用性选项