SQL SERVER 表最小行的乙個糾結問題

2021-09-06 03:25:22 字數 3364 閱讀 9616

昨天乙個同事突然問我,說他在

sql 2000

資料庫建立如下表的時候,突然碰到了下面一條警告資訊。

sql指令碼和警告資訊如下:

ifobject_id(n'

log'

) is

null

begin

create

table

log(

[date

]datetime,[

thread

]nvarchar

(255),[

level

]nvarchar(50

),[logger

]nvarchar

(255),[

message

]nvarchar

(4000),[

exception

]nvarchar

(4000))

endelse

print('

該錶已經存在,請檢查資料庫');

gowarning: the 

table

'log

'has been created but its maximum row size (

17159

) exceeds the maximum 

number

ofbytes per row (

8060

). insert

orupdate

ofa row 

inthis 

table

will fail 

ifthe resulting row length exceeds 

8060

bytes.

我以前也沒有遇見過這樣的警告資訊,當時我在

sql server 2000

下面執行這段指令碼,果然有這個警告資訊,還有就是為什麼maximun 

row size 

是17159

?;當我在

sql server

2005

下面執行這段指令碼卻沒有警告資訊出現,難道

sql server 2005 

與sql server 2000在

存貯機制上面有什麼不同?

在搞清楚這些問題前,我們先來看看其它的一些相關問題,就是

sql server

2000/2005

中最大資料行都是8060位元組(對定長資料而言), 其中sql server 2000中可以使用的大小為8039位元組, 而sql server 2005可以使用的大小為8053位元組。我們可以從下面的指令碼中實驗一下(sql server 2005)

最小行大小8061 = 4000 + 4000 + 54 + 7(內部開銷)。下面我們改變下上面指令碼的資料型別,如下所示,看看在sql server 2005下的情況

ifobject_id(n'

log'

) is

null

begin

create

table

log(

[date

]datetime,[

thread

]char

(255),[

level

]char(50

),[logger

]char

(255),[

message

]char

(4000),[

exception

]char

(4000))

endelse

print('

該錶已經存在,請檢查資料庫');

那麼最小行8575是怎麼算出來的呢,我們先看這張經典資料行結構圖(引自inside sql server)

其實就是8 + 255 + 50 + 255 + 4000 + 4000 = 8568   + 7 = 8575  其中的7個位元組是這樣來的

status bits a                     1

status bits b                       1

length of fixed-length ........               2 

number of columns 2 

null bitmap 1 bit for each column         (6/8)1

由於表裡面沒有變長字段,所以其它與變長相關的位元組為0 所以為7。 那麼接下來我們看看開篇的問題為什麼maximum row size (

17159),

8 + 255* 2 + 50 * 2 + 255 * 2 + 4000 * 2 + 4000 *2   = 17128

1 + 1 + 2 + 2 + 1 + 2 + 2* 5  = 19 

那麼17128 + 19 =  17147 但是結果是17159,有點不明,查了很多資料也沒搞清楚,這個17159 是怎麼算出來的,呵呵,希望高手來解答!

select

t.name as[

table name

], i.name as[

index name

], i.minlen

asminlen

from

sysobjects

ast

join

sysindexes

asi

ont.id

=i.id

where

t.id

>

100and

t.id

=object_id( '

log')

SQL SERVER 表最小行的乙個糾結問題

昨天乙個同事突然問我,說他在 sql 2000 資料庫建立如下表的時候,突然碰到了下面一條警告資訊。sql 指令碼和警告資訊如下 object id n log is null begin create table log date datetime,thread nvarchar 255 leve...

在SQLServer2005中實現表的行列轉換

pivot和unpivot關係運算子是sql server 2005提供的新增功能,因此,對公升級到sql server 2005的資料庫使用pivot和unpivot時,資料庫的相容級別必須設定為90 可以使用sp dbcmptlevel儲存過程設定相容級別 在查詢的from子句中使用pivot和...

SQLserver 多行合併為一行

將表和插入模擬資料 create table test id int course varchar 255 insert into test values 1,語文 insert into test values 2,數學 insert into test values 3,英語 insert in...