A varchar(1)
может хранить строку нулевой длины («пустую»).char(1)
не может, так как он будет дополнен одним пробелом.Если это различие важно для вас, вы можете отдать предпочтение varchar
.
. Помимо этого, одним из вариантов использования этого может быть, если дизайнер хочет допустить возможность того, что может потребоваться большее количество символовв будущем.
Изменение типа данных фиксированной длины с char(1)
на char(2)
означает, что необходимо обновить все строки таблицы и все индексы или ограничения, которые обращаются к этому столбцу, удаляются первыми.
Выполнение этих изменений в большой таблице в производственном процессе может быть чрезвычайно трудоемкой операцией, требующей времени простоя.
Изменить столбец с varchar(1)
на varchar(2)
гораздо проще, поскольку онизменение только метаданных (ограничения FK, которые ссылаются на столбец, должны быть удалены и воссозданы, но нет необходимости перестраивать индексы или обновлять страницы данных).
Более того, сохранение 2 байтов в строке не всегда может произойти.Если определение строки уже довольно длинное, это не всегда влияет на количество строк, которые могут поместиться на странице данных.Другой случай был бы, если при использовании функции сжатия в Enterprise Edition способ хранения данных полностью отличается от упомянутого в ответе Митча в любом случае.И varchar(1)
, и char(1)
в конечном итоге будут храниться одинаково в короткой области данных.
@ Thomas - например, попробуйте это определение таблицы.
CREATE TABLE T2
(
Code VARCHAR(1),
Foo datetime2,
Bar int,
Filler CHAR(4000),
PRIMARY KEY CLUSTERED (Code, Foo, Bar)
)
INSERT INTO T2
SELECT TOP 100000 'A',
GETDATE(),
ROW_NUMBER() OVER (ORDER BY (SELECT 0)),
NULL
FROM master..spt_values v1, master..spt_values v2
CREATE NONCLUSTERED INDEX IX_T2_Foo ON T2(Foo) INCLUDE (Filler);
CREATE NONCLUSTERED INDEX IX_T2_Bar ON T2(Bar) INCLUDE (Filler);
Для varchar
тривиально изменить определение столбца с varchar(1)
на varchar(2)
.Это изменение только метаданных.
ALTER TABLE T2 ALTER COLUMN Code VARCHAR(2) NOT NULL
Если изменение от char(1)
до char(2)
, должны быть выполнены следующие шаги:
- Удалите PK из таблицы.Это преобразует таблицу в кучу и означает, что все некластеризованные индексы необходимо обновить с помощью RID, а не ключа кластеризованного индекса.
- Измените определение столбца.Это означает, что все строки в таблице обновлены, поэтому
Code
теперь сохраняется как char(2)
. - Добавьте обратно кластерное ограничение PK.Наряду с перестройкой самого CI это означает, что все некластеризованные индексы необходимо снова обновить с помощью ключа CI в качестве указателя строки, а не RID.