Подтвердить что ты не робот

Есть ли смысл в SQL Data Type VARCHAR (1)?

Я столкнулся с множеством полей VARCHAR (1) в базе данных, с которой мне недавно приходилось работать. Я закатил глаза: очевидно, дизайнер не имел понятия. Но, возможно, я тот, кому нужно что-то узнать. Есть ли какая-то возможная причина использовать тип данных VARCHAR (1), а не CHAR (1)? Я бы подумал, что RDMS автоматически преобразует одно в другое.

База данных - это MS SQL 2K5, но она появилась из Access в тот же день.

4b9b3361

Ответ 1

Да, есть смысл.

  • Легче для него быть определяемым на языке. Согласовано и проще определить varchar, чтобы разрешить 1-8000, чем сказать, что это должно быть 2+ или от 3+ до 8000.

  • Вариационный аспект VARCHAR (1) - именно это. Он может быть не оптимальным для хранения, но передает конкретное значение, что данные являются либо 1 char (класс класса), либо пустой (внешняя активность) вместо NULL (неизвестный/еще не классифицированный).

Хранение играет очень небольшую роль в этом - глядя на схему базы данных для CHAR (1), вы почти ожидаете, что она всегда должна иметь значение 1 char, например, кредитные карты должны иметь 16 цифр. Это просто не относится к некоторым данным, где он может быть одним или необязательным.

Существуют также различия в использовании комбинации VARCHAR (1) vs CHAR (1) + NULL для тех, кто говорит tri-state [1- char | 0- char | NULL] совершенно бесполезен. Он позволяет выполнять инструкции SQL, такие как:

select activity + '-' + classroom
from  ...

что в противном случае было бы более сложным, если вы используете CHAR (1) + NULL, который может передавать одну и ту же информацию, но имеет тонкие отличия.

Ответ 2

AFAIK, №.

a VARCHAR(1) требует хранения 3 байта (размер хранилища - фактическая длина введенных данных + 2 байта. Ref.

a CHAR(1) требуется 1 байт.

С точки зрения хранения: эмпирическое правило, если оно меньше или равно 5 символам, рассмотрите использование столбца с фиксированной длиной char.

Поводом для избежания varchar (1) (кроме того, что они передают плохое дизайнерское обоснование, IMO) при использовании Linq2SQL: LINQ to SQL и varchar (1) поля

Ответ 3

A varchar(1) может хранить строку с нулевой длиной ( "пустой" ). A char(1) не может, поскольку он будет дополнен одним пространством. Если это различие важно для вас, вы можете одобрить varchar.

Кроме того, одним из вариантов использования может быть, если дизайнер хочет разрешить возможность того, что в будущем может потребоваться большее количество символов.

Изменение типа фиксированной длины от char(1) до char(2) означает, что все строки таблицы должны быть обновлены, а все индексы или ограничения, которые обращаются к этому столбцу, будут удалены первыми.

Внесение этих изменений в большую таблицу в процессе производства может быть чрезвычайно трудоемкой, что требует времени простоя.

Изменение столбца от varchar(1) до varchar(2) намного проще, поскольку это изменение только метаданных (ограничения FK, которые ссылаются на столбец, нужно будет отбросить и воссоздать, но не нужно перестраивать индексы или обновлять страницы данных).

Кроме того, сохранение 2 байта в строке может не всегда материализоваться. Если определение строки уже довольно длинное, это не всегда будет влиять на количество строк, которые могут помещаться на странице данных. Другим случаем было бы использование функции сжатия в Enterprise Edition способом хранения данных совершенно иначе, чем в случае Mitch в любом случае. Как 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);

При a 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.