У меня есть StartDate и EndDate для каждой записи. Должен ли я дать NULL особое значение при использовании в этих 2 полях? - PullRequest
2 голосов
/ 12 февраля 2009

Итак, у меня есть таблица, в которой StartDate и EndDate используются для определения активности записи. Я думал об использовании NULL, чтобы избавить сопровождающих от необходимости придумывать сумасшедшие даты для некоторых записей. Например, если NULL был определен как положительный бесконечный при использовании в EndDate, сопровождающим данных не нужно было бы придумывать что-то вроде 1-1-2100 для долгоживущих записей.

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

РЕДАКТИРОВАТЬ: мнения о половине наполовину. Если бы я пояснил, что StartDate и EndDate используются исключительно с целью определения активности записи в предложении where и никогда не появляются в списке выбора, это наклонило бы шкалу? Одна тема, которую мне нужно прочитать, это, вероятно, индексация. Спасибо всем.

Ответы [ 11 ]

4 голосов
/ 12 февраля 2009

Если либо StartDate, либо EndDate вашей записи будет NULL, то выполняется следующее условие:

BETWEEN StartDate AND EndDate

никогда не будет соответствовать этой записи.

Вам нужно будет сделать следующее:

BETWEEN IFNULL(StartDate, '01.01.1000') AND IFNULL(EndDate, '01.01.3000')

, что, конечно, не годится для индексов.

Конечно, вы можете создать индекс на основе функции, но вам все равно нужно будет указать для него константу.

Резюме: если вам нужна производительность, используйте константы, не используйте NULL

3 голосов
/ 12 февраля 2009

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

Определите минимальные и максимальные константы и пусть Null будет нулевым.

Замечательные комментарии:
@ Haoest - вы правы, Null - это не то же самое, что набор Null, и мне было не ясно. Поведение SQL при обработке Nulls потребует больше кода для большего количества проверок. Результаты SQL при поиске Null могут не соответствовать интуиции программистов NULL (SQL) .
@ MBCook - отличная ссылка, хотелось бы, чтобы я сам это опубликовал - спасибо

Обновление: после того, как запрос или функция имеет нулевое значение на эту дату, вы больше не знаете, был ли назначен нулевой, потому что это означает «Макс» или потому, что нулевой уровень был распространен в запросе.

2 голосов
/ 12 февраля 2009

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

1 голос
/ 13 февраля 2009

Я бы попытался работать со значениями NULL как можно дольше.

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

Я согласен с Quassnoi, что вы не можете напрямую указать

BETWEEN StartDate AND EndDate

но вместо его предложения (которое затрудняет использование индексов / индексов), этот работает также:

(somedate >= StartDate or StartDate is null)
AND
(somedate <= EndDate or EndDate is null)

AFAIK это позволит использовать индекс, но проверить план выполнения для ваших конкретных обстоятельств.

Недостатком использования «специальных» дат начала / окончания является принудительное выполнение. Если весь ваш доступ к БД осуществляется через определенный язык программы с более или менее обязательными библиотеками, вы можете выполнить эту работу. Однако, если у вас разные пути доступа (прямой SQL, разные языки / библиотеки), это будет очень сложно сделать.

Возможен третий способ: использование значений NULL для операторов DML, а затем изменение триггера на предопределенное значение min / max. Тогда выбор может быть проще. Но использование триггера открывает другую банку с червями ...

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

1 голос
/ 12 февраля 2009

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

Мое личное предпочтение - запретить значения NULL в полях типа «Дата» и всегда использовать «высокое значение» для чего-то вроде даты окончания. Для меня это значительно упрощает все запросы, которые я должен выполнить к дате начала / окончания, и не дает мне много-много проверок NULL в нескольких запросах.

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

1 голос
/ 12 февраля 2009

Я бы предпочел использовать определенные минимальные и максимальные даты вместо нулевых. Прежде всего потому, что, по крайней мере, в C #, когда вы получаете данные из БД, вам приходится начинать работать с типами Nullable, и это меня раздражает.

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

Полагаю, суть в том, что я подхожу к этим проблемам с точки зрения юзабилити для разработчиков, а не пользователей БД, так что в этом и заключается моя точка зрения.

1 голос
/ 12 февраля 2009

Я бы определенно использовал ноль в этом случае. Хранимые процедуры и запросы не имеют большого значения.

Если у вас есть значение, например «2100-01-01», то, просто взглянув на него, я бы предположил, что это допустимое значение. Если я вижу NULL, я считаю, что он имеет особое значение (помимо отсутствия ценности, хотя иногда это все, что есть, и это нормально).

0 голосов
/ 09 июня 2011

Используйте даты NULL в вашей базе данных. Использовать DateTime? в вашем коде C #.

Избегайте использования магических ценностей.

0 голосов
/ 12 февраля 2009

если вы используете в своей базе данных даты NULL, убедитесь, что вы используете DateTime? (обнуляемый C #) в вашем коде, это сделает вашу жизнь намного проще:)

0 голосов
/ 12 февраля 2009

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

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