Дръжте го на линия. Под кориците SQL Server вече съхранява MAX колоните в отделна „единица за разпределение“ от SQL 2005. Вижте Организация на таблица и индекс. Това на практика е точно същото като запазването на колоната MAX в собствената й таблица, но без какъвто и да е недостатък да го направите изрично.
Наличието на изрична таблица всъщност би било едновременно по-бавно (поради ограничението на външния ключ) и консумирайте повече място (поради дублирането на DetaiID). Да не говорим, че изисква повече код, а грешките се въвеждат чрез... писане на код.
алтернативен текст http://i.msdn.microsoft.com/ms189051.3be61595-d405-4b30-9794-755842d7db7e(en-us,SQL.100).gif
Актуализиране
За да проверите действителното местоположение на данните, прост тест може да го покаже:
use tempdb;
go
create table a (
id int identity(1,1) not null primary key,
v_a varchar(8000),
nv_a nvarchar(4000),
m_a varchar(max),
nm_a nvarchar(max),
t text,
nt ntext);
go
insert into a (v_a, nv_a, m_a, nm_a, t, nt)
values ('v_a', N'nv_a', 'm_a', N'nm_a', 't', N'nt');
go
select %%physloc%%,* from a
go
%%physloc%%
псевдо колоната ще покаже действителното физическо местоположение на реда, в моя случай това беше страница 200:
dbcc traceon(3604)
dbcc page(2,1, 200, 3)
Slot 0 Column 2 Offset 0x19 Length 3 Length (physical) 3
v_a = v_a
Slot 0 Column 3 Offset 0x1c Length 8 Length (physical) 8
nv_a = nv_a
m_a = [BLOB Inline Data] Slot 0 Column 4 Offset 0x24 Length 3 Length (physical) 3
m_a = 0x6d5f61
nm_a = [BLOB Inline Data] Slot 0 Column 5 Offset 0x27 Length 8 Length (physical) 8
nm_a = 0x6e006d005f006100
t = [Textpointer] Slot 0 Column 6 Offset 0x2f Length 16 Length (physical) 16
TextTimeStamp = 131137536 RowId = (1:182:0)
nt = [Textpointer] Slot 0 Column 7 Offset 0x3f Length 16 Length (physical) 16
TextTimeStamp = 131203072 RowId = (1:182:1)
Всички стойности на колони, с изключение на TEXT и NTEXT, се съхраняват на линия, включително типовете MAX.
След промяна на опциите на таблицата и вмъкване на нов ред (sp_tableoption не засяга съществуващите редове), типовете MAX бяха изгонени в собственото си хранилище:
sp_tableoption 'a' , 'large value types out of row', '1';
insert into a (v_a, nv_a, m_a, nm_a, t, nt)
values ('2v_a', N'2nv_a', '2m_a', N'2nm_a', '2t', N'2nt');
dbcc page(2,1, 200, 3);
Обърнете внимание как колоните m_a и nm_a вече са текстови указател в единицата за разпределение на LOB:
Slot 1 Column 2 Offset 0x19 Length 4 Length (physical) 4
v_a = 2v_a
Slot 1 Column 3 Offset 0x1d Length 10 Length (physical) 10
nv_a = 2nv_a
m_a = [Textpointer] Slot 1 Column 4 Offset 0x27 Length 16 Length (physical) 16
TextTimeStamp = 131268608 RowId = (1:182:2)
nm_a = [Textpointer] Slot 1 Column 5 Offset 0x37 Length 16 Length (physical) 16
TextTimeStamp = 131334144 RowId = (1:182:3)
t = [Textpointer] Slot 1 Column 6 Offset 0x47 Length 16 Length (physical) 16
TextTimeStamp = 131399680 RowId = (1:182:4)
nt = [Textpointer] Slot 1 Column 7 Offset 0x57 Length 16 Length (physical) 16
TextTimeStamp = 131465216 RowId = (1:182:5)
За целите на завършването можем също така да премахнем едно от полетата без максимум от реда:
update a set v_a = replicate('X', 8000);
dbcc page(2,1, 200, 3);
Обърнете внимание как колоната v_a се съхранява в хранилището с препълване на ред:
Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4
v_a = [BLOB Inline Root] Slot 0 Column 2 Offset 0x19 Length 24 Length (physical) 24
Level = 0 Unused = 99 UpdateSeq = 1
TimeStamp = 1098383360
Link 0
Size = 8000 RowId = (1:176:0)
Така че, както други вече коментираха, типовете MAX се съхраняват на линия по подразбиране, ако пасват. За много проекти на DW това би било неприемливо, защото типичните зареждания на DW трябва да сканират или поне да сканират диапазона, така че sp_tableoption ..., 'large value types out of row', '1'
трябва да се използва. Обърнете внимание, че това не засяга съществуващите редове, в моя тест не дори при възстановяване на индекс , така че опцията трябва да се включи по-рано.
За повечето зареждания от тип OLTP обаче фактът, че MAX типове се съхраняват на линия, ако е възможно, всъщност е предимство, тъй като моделът за OLTP достъп е да се търси и ширината на реда оказва малко влияние върху него.
Независимо от това, по отношение на първоначалния въпрос:отделна таблица не е необходима. Включване на large value types out of row
опцията постига същия резултат при безплатна цена за разработка/тест.