Является ли чрезмерное использование пустых столбцов в базе данных «запахом кода»? - PullRequest
18 голосов
/ 24 июня 2009

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

Это нормальная практика в мире баз данных? Я просто скромный программист, а не администратор баз данных, но я думаю, вы захотите свести к минимуму пустые поля, только там, где они имеют смысл.

Является ли это "запахом кода", если большинство столбцов обнуляемы?

Ответы [ 17 ]

16 голосов
/ 24 июня 2009

Значения по умолчанию обычно являются исключением, а NULL - нормой, по моему опыту.

Правда, нули раздражают.

Это также чрезвычайно полезно, потому что ноль - лучший показатель «НЕТ ЗНАЧЕНИЯ». Конкретное значение по умолчанию вводит в заблуждение, и вы можете потерять информацию или ввести в заблуждение в будущем.

13 голосов
/ 24 июня 2009

Любой, кто разработал приложение для ввода данных, знает, как часто некоторые поля являются неизвестными во время ввода - даже для столбцов, критичных для бизнеса, для ответа @Chris McCall.

Однако «запах кода» - это всего лишь показатель того, что что-то может быть закодировано неаккуратно. Вы используете запахи, чтобы идентифицировать вещи, которые требуют дополнительного изучения, а не вещи, которые должны быть изменены.

Так что, да, если вы видите столбцы, которые можно обнулять, так последовательно, вы правы, чтобы быть подозрительным. Это может означать, что кто-то ленился или боится однозначно объявить NOT NULL столбцы. Вы можете оправдать свой собственный анализ.

9 голосов
/ 24 июня 2009

Я из лагеря Extreme NO: я все время избегаю NULL. Оставляя в стороне фундаментальные соображения о том, что они на самом деле означают (поскольку общаясь с разными людьми, вы получите разные ответы, такие как «нет значения», «неизвестное значение», «отсутствует», «мой рыжий кот по кличке Нуль»), худшая проблема Значение NULL заключается в том, что они часто загадочным образом портят ваши запросы.

Я потерял счетчик количества раз, которое мне приходилось отлаживать чей-то запрос (хорошо, может быть, 9) и отследил проблему до соединения с NULL. Если вашему коду необходим ISNULL для восстановления объединений, скорее всего, вы также потеряли с ним применимость индекса и производительность.

Если вам нужно сохранить значение «отсутствует / неизвестно / пусто / кошка» (а это то, чего я предпочитаю избегать), то лучше об этом явно заявить.

Специалисты в NULL могут не согласиться. Использование NULL имеет тенденцию разбивать толпы SQL по центру.

По моему опыту, интенсивное использование NULL положительно коррелировало со злоупотреблением базой данных, но я бы не стал разбивать это на каменные таблички, как какой-то Закон Природы. Мой опыт - это только мой опыт.

РЕДАКТИРОВАТЬ: Дополнительные мысли. Вполне возможно, что те, кто противостоят нулевым расистам, как я, более заинтересованы в нормализации, чем те, кто выступает за NULL. Я не думаю, что бешеные нормализаторы были бы слишком довольны рваными краями на своих столах, которые могут принимать значения NULL. Много нулей может указывать, что разработчики баз данных не находятся в тяжелой нормализации. Таким образом, вместо того, чтобы NULL предлагать код как «плохой», он может альтернативно предложить философскую позицию разработчиков по нормализации. Может быть, это достигает. Просто мысль.

7 голосов
/ 24 июня 2009

Не знаю, считаю ли я это всегда плохой вещью, но если столбцы добавляются, потому что одна запись (или, может быть, несколько) должна иметь значения, а большинство нет, то это указывает на довольно плоскую таблицу состав. Если вы видите имена столбцов, такие как «addr1», «addr2», «addr3», то воняет!

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

6 голосов
/ 24 июня 2009

Я думаю, что следует избегать пустых столбцов. Везде, где семантика домена позволяет использовать значение, которое четко указывает на отсутствующие данные, его следует использовать вместо NULL.

Например, давайте представим таблицу, которая содержит поле Comment. Большинство разработчиков помещают здесь значение NULL, чтобы указать, что в столбце нет данных. (И, надеюсь, проверочное ограничение, запрещающее строки нулевой длины, чтобы у нас было общеизвестное «значение», указывающее на отсутствие значения.) Мой подход обычно противоположен. Столбец Comment равен NOT NULL, а строка нулевой длины указывает на отсутствие значения. (Я использую проверочное ограничение, чтобы убедиться, что строка нулевой длины действительно является строкой нулевой длины, а не пробелами.)

Итак, зачем мне это делать? Две причины:

  1. NULL s требует специальной логики в SQL, и эта техника избегает этого.
  2. Многие клиентские библиотеки имеют специальные значения для указания NULL. Например, если вы используете Microsoft ADO.NET, константа DBNull.Value указывает на NULL, и вы должны проверить это. Использование строки нулевой длины в столбце NOT NULL устраняет необходимость.

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

Что бы вы ни делали, будьте добры к тем, кто будет использовать ваши столы. Будьте последовательны . Позвольте им с уверенностью SELECT. Позвольте мне объяснить, что я имею в виду под этим. Недавно я работал над проектом, база данных которого не была разработана мной. Почти каждый столбец обнулялся и не имел ограничений. Не было последовательности в том, что означало отсутствие стоимости. Это может быть NULL, строка нулевой длины или даже куча пробелов, и часто это так. (Как этот суп ценностей попал туда, я не знаю.)

Представьте себе некрасивый код, который разработчик должен написать, чтобы найти все эти записи с пропущенным полем Comment в этом сценарии:

SELECT * FROM Foo WHERE LEN(ISNULL(Comment, '')) = 0

Удивительно, но есть разработчики, которые считают это вполне приемлемым, даже нормальным, несмотря на возможные последствия для производительности. Лучше было бы:

SELECT * FROM Foo WHERE Comment IS NULL

Или

SELECT * FROM Foo WHERE Comment = ''

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

4 голосов
/ 24 июня 2009

Короче, я бы сказал, да, это, вероятно, запах кода.

Является ли столбец обнуляемым или нет, очень важно и должно быть определено тщательно. Вопрос должен оцениваться по каждому столбцу. Я не верю ни в одно из «лучших практик» по умолчанию для NULL. «Лучшая практика» для меня - тщательно рассмотреть вопрос об обнуляемости во время проектирования и / или рефакторинга стола.

Для начала, ни один из ваших столбцов первичного ключа не будет обнуляемым. Затем я сильно склоняюсь к NOT NULL для всего, что является внешним ключом.

Некоторые другие вещи, которые я считаю:

Критерии, где NULL следует строго избегать: money столбцы - есть ли действительно вероятность того, что эта сумма будет неизвестна?

Критерии, где NULL могут быть обоснованы чаще всего: datetime столбцы - зарезервированные даты отсутствуют, поэтому NULL - ваш лучший вариант

Другие типы данных: char / varchar столбцы - для кодов / идентификаторов - NOT NULL почти исключительно int столбцов - в основном NOT NULL, если это не что-то вроде "числа детей", где вы хотите различить неизвестный ответ.

2 голосов
/ 24 июня 2009

Боюсь, они (очень распространенный) запах. Посмотрите на C.J. Дата написания по теме.

2 голосов
/ 24 июня 2009

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

1 голос
/ 24 июня 2009

По моему опыту, это проблема, когда Null и Not Null не совпадают с обязательным / не обязательным полем.

Скорее всего, это все необязательные поля. Если на бизнес-уровне или уровне пользовательского интерфейса вы обнаружите, что эти поля являются обязательными, я думаю, это означает, что модель данных отошла от модели бизнес-объектов и является признаком чрезмерно консервативных политик изменения БД или недосмотра.

Если вы запустите генератор данных образца для своих данных, а затем попытаетесь загрузить данные, которые действительны в соответствии с SQL, вы сразу же узнаете, соответствуют ли правила.

1 голос
/ 24 июня 2009

Я так думаю. Если вам не нужны данные, это не важно для вашего бизнеса. Если это важно для вашего бизнеса, оно должно быть обязательным.

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