Czy logiczne uporządkowanie kolumn w tabeli ma wpływ na ich porządek fizyczny w warstwie pamięci? Tak.
To, czy to ważne, czy nie, to inna kwestia, na którą nie mogę (jeszcze) odpowiedzieć.
W sposób podobny do opisanego w często łączonym artykule Paula Randala na temat anatomii rekordu , spójrzmy na prostą tabelę dwóch kolumn z DBCC IND:
SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;
USE master;
GO
IF DATABASEPROPERTY (N'RowStructure', 'Version') > 0 DROP DATABASE RowStructure;
GO
CREATE DATABASE RowStructure;
GO
USE RowStructure;
GO
CREATE TABLE FixedLengthOrder
(
c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
, c2 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL
, c3 CHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL
);
GO
INSERT FixedLengthOrder DEFAULT VALUES;
GO
DBCC IND ('RowStructure', 'FixedLengthOrder', 1);
GO
Powyższy wynik pokazuje, że musimy spojrzeć na stronę 89:
DBCC TRACEON (3604);
GO
DBCC PAGE ('RowStructure', 1, 89, 3);
GO
Na wyjściu z STRONY DBCC widzimy c1 wypchany znakiem „A” przed „B” c2:
Memory Dump @0x000000000D25A060
0000000000000000: 10001c00 01000000 41414141 41414141 †........AAAAAAAA
0000000000000010: 41414242 42424242 42424242 030000††††AABBBBBBBBBB...
I tylko dlatego, że pozwala otworzyć biust RowStructure.mdf
za pomocą edytora szesnastkowego i potwierdzić, że ciąg „A” poprzedza ciąg „B”:
Teraz powtórz test, ale odwróć kolejność ciągów, umieszczając znaki „B” w c1 i znaki „A” w c2:
CREATE TABLE FixedLengthOrder
(
c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
, c2 CHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL
, c3 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL
);
GO
Tym razem nasze wyjście DBCC PAGE jest inne i ciąg „B” pojawia się jako pierwszy:
Memory Dump @0x000000000FC2A060
0000000000000000: 10001c00 01000000 42424242 42424242 †........BBBBBBBB
0000000000000010: 42424141 41414141 41414141 030000††††BBAAAAAAAAAA...
Ponownie, tylko na chichoty, sprawdźmy zrzut heksadecymalny pliku danych:
Jak wyjaśnia anatomia rekordu , kolumny rekordu o stałej i zmiennej długości są przechowywane w odrębnych blokach. Logicznie przeplatane stałe i zmienne typy kolumn nie mają wpływu na zapis fizyczny. Jednak w każdym bloku kolejność kolumn jest odwzorowana na kolejność bajtów w pliku danych.
CREATE TABLE FixedAndVariableColumns
(
c1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
, c2 CHAR(10) DEFAULT REPLICATE('A', 10) NOT NULL
, c3 VARCHAR(10) DEFAULT REPLICATE('B', 10) NOT NULL
, c4 CHAR(10) DEFAULT REPLICATE('C', 10) NOT NULL
, c5 VARCHAR(10) DEFAULT REPLICATE('D', 10) NOT NULL
, c6 CHAR(10) DEFAULT REPLICATE('E', 10) NOT NULL
);
GO
Memory Dump @0x000000000E07C060
0000000000000000: 30002600 01000000 41414141 41414141 †0.&.....AAAAAAAA
0000000000000010: 41414343 43434343 43434343 45454545 †AACCCCCCCCCCEEEE
0000000000000020: 45454545 45450600 00020039 00430042 †EEEEEE.....9.C.B
0000000000000030: 42424242 42424242 42444444 44444444 †BBBBBBBBBDDDDDDD
0000000000000040: 444444†††††††††††††††††††††††††††††††DDD
Zobacz też:
Kolejność kolumn nie ma znaczenia… ogólnie, ale - ZALEŻY!
CREATE TABLE
instrukcją (z wyjątkiem tego, że kolumny klucza CI są pierwsze w sekcji). Chociaż kolejność kolumn może ulec zmianie, jeśliALTER COLUMN
zmieni się typy danych / długości kolumn. Jedyny drobny przypadek, w którym ma znaczenie, o którym mogę myśleć, to to, że kolumny na końcu sekcji o zmiennej długości z pustym łańcuchem lub wartością NULL nie zajmują wcale miejsca w tablicy przesunięć kolumn (wykazane przez Kalen Delaney w książce dotyczącej elementów wewnętrznych z 2008 r.)