2010-08-09 3 views
5

Я работаю по схеме рефакторинга базы данных (SQL Server 2008) и собираю аргументы для изменения столбцов NCHAR(1) (которые сохраняют значения Y|N) до BIT. Все понимают, что это необходимо и не знают, почему это происходит, но это изменение влияет на производственную базу данных, поэтому требуются веские аргументы. Таблица хранит адресный каталог (до 1 м записей).NCHAR (1) vs BIT

Первый аргумент, который я нашел - каждый nchar fields принимает 2 байта, каждый 8 bit fields - 1 байт (следующий 8 - дополнительный 1 байт).

Что дальше? Возможно, некоторые проблемы производительности индексов?

+0

Удивительно, почему первоначальный дизайнер решил, что юникод должен был хранить только «N» и «Y»!Я подозреваю, что сравнения, скорее всего, будут более быстрыми в полях бит, чем поля «nchar», но не знают об этом. –

+6

Очевидно, что преимущество «NCHAR (1)» заключается в том, что вы можете его расширять - [при необходимости] (http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx) - удерживать * другие * булевы значения. ;-) –

+0

@Dean Harding: LOL. Я когда-то имел [PHB] (http://en.wikipedia.org/wiki/Pointy-haired_Boss), настаивая на том, что мы можем поместить 2 в бит поле, так как это была только одна цифра. –

ответ

4

Поле бит помогает вашей логике, автоматически применяя то, что в настоящее время является неявным бизнес-правилом (т. Е. Этот столбец может содержать только «Y» или «N»). Если вы применяете это правило программно, вы можете сэкономить, исключив эти накладные расходы. Индексирование битового столбца само по себе имеет мало значения из-за низкой мощности, но может быть полезно как часть составного индекса.

Смотрите также:

10

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

Вы проверили, влияет ли использование nchar (1) на производительность, или вы попадаете в ловушку преждевременной оптимизации? Здесь речь идет только о миллионах записей.

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

+0

+1 - Чтобы изменить все сохраненные процедуры и такие, чтобы учитывать новую логику, вероятно, стоило бы LOT больше, чем дополнительное пространство. – JNK

+1

+1, это еще не конец света, и если он не сломан, не исправляйте его. Первоначально разработчик мог иметь в виду тройственные варианты, такие как M, возможно. –

+0

Согласовано. И вы не можете индексировать поле BIT в SQL Server. Ваши составные индексы, вероятно, не приносят вам много пользы, так как в вашем поле NCHAR есть только два значения, но если они тогда, вы попадаете в мир с болью, меняя его. – mattmc3

6

Одной из распространенных причин, по которым найти NCHAR (1), а не бит, является то, что Oracle не поддерживает бит типа. Если у вас есть разработчик Oracle или Oracle, или база данных, используемая для работы в Oracle, вы увидите это много. На сервере Sql в этом нет необходимости.

Тем не менее, я обнаружил, что в большинстве мест, где у меня есть поле бит (или NCHAR (1) в Oracle), что я действительно want - это datetime, которое указывает не столько значение флага, сколько точно это стало правдой. Это не всегда так, но когда я вспоминаю старый код, который я написал, я бы предположил, что 4 из 5 раз использовал бит поле, которое я должен использовать datetime.

+0

И делать сравнения datetime в ваших запросах, где могли бы выполняться бит-сравнения? Я предпочитаю использовать как дату, так и бит. datetime, чтобы узнать, когда он стал истинным (или ложным) и самим битовым полем для запросов. – Jeroen

+2

@Jeroen - правильность сначала, исполнение второе. Но большую часть времени я просто проверяю, что это не NULL в любом случае, и это примерно так же быстро, как бит-проверка. –

+0

@Joel: Интересный момент. Спасибо – Jeroen

1

Является ли поле широко использовано в запросах Where fld = 'Y'?

Если так, я бы подумал о проведении теста, чтобы увидеть, будет ли его изменение на бит влияет на производительность.

Изменение его сейчас только потому, что оно должно быть полем бит, так как вы храните логические значения в таблице записей 1m +, для меня это тоже не очень хорошая идея, и я бы пошел с ответом @ Andrew.

3

Создание битового поля, добавить вычисляемый столбец, который эмулирует NCHAR для (1) в настоящее время.

Что не использовать NCHAR:

  • Y против y против некоторого unicode Y
  • Накладные проверки Y или N
  • изначально не "правда" о "ложной" (например, не отображаются непосредственно to .net boolean)
  • Y и N являются английскими. Ja/Nein, Oui/Non и т. Д.

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

  • меньше
  • типа данных в безопасности (например, проверка не требуется)
  • карты для клиента, означающие непосредственно
  • независимо от региона

Сказать, что мы используем smalldatetime "WhenInactive" поле в качестве поля «IsActive». NULL = активен.

2

Если вы используете Linq2SQL или Entity Framework BIT столбец переведут в bool, но NCHAR(1) переведут в string.

1

Использование Bit:

  • Логическое представление/выразительность намерения - так как логические состояния не всегда последовательно, как expressable Yes or No, который затем означает, что вы бы или должны были бы быть непоследовательным в модельных битов, или неинтуитивно, например True/False (T/F), On/Off (?O/F), Open/Closed(O/C) т.д.

  • Ссылочная целостность - ненулевое бит может быть ограничено только 0 or 1. Если вы не добавите ограничений, то ваш *char(1) может быть Y, N, X или .

  • Bits can be packed, поэтому могло иметь меньшую память.

  • Re: Производительность: индексирование столбцов бит (или нескольких состояний CHAR) обычно является отходами, если в данных нет высокой селективности 0 или 1. В этом случае хорошей идеей будет filtered index по избирательному значению.

(Перенесенные из deleted answer here)

0

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

Смежные вопросы