合理设计列的长度

 表1结构及数据

 1  USE testdb
 2  GO
 3  /* ***************************************
 4  堆存储_01
 5  Phoenix.Feng 2010-11-18
 6  *************************************** */
 7  IF  OBJECT_ID( ' IDF_Heap_01 'IS  NOT  NULL
 8  DROP  TABLE IDF_Heap_01
 9  GO
10  CREATE  TABLE IDF_Heap_01(
11     id  INT,
12     name  NCHAR( 2017)
13 )
14  INSERT  INTO IDF_Heap_01  VALUES( 1' phoenix ')
15  INSERT  INTO IDF_Heap_01  VALUES( 2' kevin ')
16  INSERT  INTO IDF_Heap_01  VALUES( 3' YY ')
17  INSERT  INTO IDF_Heap_01  VALUES( 4' TERRY ')

 表二结构及数据

 1  /* ***************************************
 2  堆存储_02
 3  Phoenix.Feng 2010-03-16
 4  *************************************** */
 5  IF  OBJECT_ID( ' IDF_Heap_02 'IS  NOT  NULL
 6  DROP  TABLE IDF_Heap_02
 7  GO
 8  CREATE  TABLE IDF_Heap_02(
 9     id  INT,
10     name  NCHAR( 2018)
11 )
12  INSERT  INTO IDF_Heap_02  VALUES( 1' phoenix ')
13  INSERT  INTO IDF_Heap_02  VALUES( 2' kevin ')
14  INSERT  INTO IDF_Heap_02  VALUES( 3' YY ')
15  INSERT  INTO IDF_Heap_02  VALUES( 4' TERRY ')
16  GO

我在这里创建了两张表,他们看起来似乎没有任何区别,只是第一张表中列name的字符串长度是2017,后面是2018,但是通过查看IAM分配的情况, 结果让人很是意外;

首先创建页地址转具体页码函数

IF OBJECT_ID('f_get_page') IS NOT NULL

DROP FUNCTION f_get_page

GO

CREATE FUNCTION f_get_page(@page_num BINARY( 6 ))

RETURNS VARCHAR( 11 )

AS 

BEGIN

RETURN(CONVERT(VARCHAR( 2 ),(CONVERT( INT ,SUBSTRING(@page_num, 6 , 1 )) * POWER( 2 , 8 )) + 

        (CONVERT( INT ,SUBSTRING(@page_num, 5 , 1 )))) + ' :'+ 

        CONVERT(VARCHAR( 11 ),

        (CONVERT( INT ,SUBSTRING(@page_num, 4 , 1 )) * POWER( 2 , 24 )) + 

        (CONVERT( INT ,SUBSTRING(@page_num, 3 , 1 )) * POWER( 2 , 16 )) + 

        (CONVERT( INT ,SUBSTRING(@page_num, 2 , 1 )) * POWER( 2 , 8 )) + 

        (CONVERT( INT ,SUBSTRING(@page_num, 1 , 1 )))))

END 

GO

查询语句

 1  SELECT total_pages,used_pages,data_pages,
 2        first_page,root_page,first_iam_page,
 3        dbo.f_get_page(first_page) first_page,
 4        dbo.f_get_page(root_page) root_page,
 5        dbo.f_get_page(first_iam_page) first_iam_page
 6    FROM sys.system_internals_allocation_units
 7    WHERE container_id  IN (
 8          SELECT partition_id  FROM sys.partitions    
 9              WHERE  object_id  in(
10                  SELECT  object_id   FROM sys.objects  WHERE name  =  ' IDF_Heap_01 '
11             )
12         ) 
13  GO    
14  SELECT total_pages,used_pages,data_pages,
15        first_page,root_page,first_iam_page,
16        dbo.f_get_page(first_page) first_page,
17        dbo.f_get_page(root_page) root_page,
18        dbo.f_get_page(first_iam_page) first_iam_page
19    FROM sys.system_internals_allocation_units
20    WHERE container_id  IN (
21          SELECT partition_id  FROM sys.partitions    
22              WHERE  object_id  in(
23                  SELECT  object_id   FROM sys.objects  WHERE name  =  ' IDF_Heap_02 '
24             )
25         ) 
26  GO    

这里显示查询结果:

第二张表中,name仅比第一张表大一个长度,但他所使用的数据页是前者的两倍,即一条数据一页。

其实原因很简单,表2中每行数据的大小刚好超过sql server中每页存储大小为8096一半的边界值,参考来至MSDN

你可能感兴趣的:(设计)