Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2009.04.19;
Скачать: [xml.tar.bz2];

Вниз

Стратегия пустых полей   Найти похожие ветки 

 
Kostafey ©   (2009-02-19 11:34) [0]

Давно думаю как правильно следует делать.

Допустим у нас есть некая база с таблицами.
Одна основная, другая справочник, привязанная к первой.

Допустим пользователь заполняет основную таблицу, он может
выбрать одно из значений справочной таблицы. А может
и не выбрать.

Для случая, когда он не выбрал можно оставлять поле null,
можно привязывать все же некоторый идентификатор справочника,
например, содержащий значение "не указано" (или что-то в этом роде).

Как правильнее делать?


 
clickmaker ©   (2009-02-19 11:39) [1]

если нужна будет локализация, то, возможно, имеет смысл, поскольку "не указано" может быть на нескольких языках.
если там будет некий ID, то логика определения не указанных значений должна быть завязана именно на проверку этого значения, а не is null, что может быть неудобно / не очевидно.


 
Ega23 ©   (2009-02-19 11:40) [2]


> Как правильнее делать?


Однозначного ответа нет.
Оба подхода имеют право на жизнь.
Лично я стараюсь на FK всегда NOT NULL накладывать. Исключение - иерархические таблицы с FK на саму себя.
Ну и первая запись - типа "Нет" или "Отсутствует" или ещё что-то...


 
Kinda   (2009-02-19 11:40) [3]

Думаю что и так и так можно, на мне всеж больше по душе присвоение значения "не указано", по нескольким причинам:
1. На справочник можно сделать внешний ключ.
2. Меньше возни потом с обработкой нуллов в запросах.


 
Kostafey ©   (2009-02-19 11:49) [4]

Могу привести еще один пример полезности записи "не указано".

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

Я сначала думал, что добавлять для этого запись в таблицу справочника
слишком притянуто за уши, но сейчас уже так не думаю :)

Спасибо за ответы!


 
Ega23 ©   (2009-02-19 12:03) [5]


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


На самом деле это большой косяк стандартного TDBLookupCombo, что он не может на null-значение НД позиционироваться.


 
KSergey ©   (2009-02-19 12:04) [6]

зачастую ключевое поле INT, однако автонумераторы в подавляющем большенстве случаев создают от нуля и далее (в положительную область). Таким образом ничто не мешает забронировать любые отрицательные значения для "особого смысла" (причем даже явно занести их в справочники)без боязни пересечения в любой инсталяции системы, и это будет много лучше NULL по причинам, указанным в [2].


 
Johnmen ©   (2009-02-19 12:09) [7]

Такое поле д.б. NULL. Другие варианты говорят о том, что значение существует. А это не так.
Об этом говорит теория реляционных БД.
И надо разделять ХРАНЕНИЕ и ОТОБРАЖЕНИЕ, а не месить всё в одно корыто :)


 
Kostafey ©   (2009-02-19 12:48) [8]

> [5] Ega23 ©   (19.02.09 12:03)


> На самом деле это большой косяк стандартного TDBLookupCombo,
> что он не может на null-значение НД позиционироваться.

Ну в моем случае это
<h:selectOneMenu ...
но не суть важно.


> [6] KSergey ©   (19.02.09 12:04)


> зачастую ключевое поле INT, однако автонумераторы в подавляющем
> большенстве случаев создают от нуля и далее (в положительную
> область). Таким образом ничто не мешает забронировать любые
> отрицательные значения для "особого смысла" (причем даже
> явно занести их в справочники)без боязни пересечения в любой
> инсталяции системы, и это будет много лучше NULL по причинам,
> указанным в [2].

А тут есть небольшой подводный камень.
MS SQL Server при добавлении новой записи в момент добаления присваивает ей
идентификатор -1.
У меня однажды возникла ситуация, когда такая запись участвовала в запросе
на выборку. Результат сначала сильно удивил...

Счет там начинается с 1, так что для служебный целей лучше использовать 0.


> [7] Johnmen ©   (19.02.09 12:09)


> Такое поле д.б. NULL. Другие варианты говорят о том, что
> значение существует. А это не так.
> Об этом говорит теория реляционных БД.
> И надо разделять ХРАНЕНИЕ и ОТОБРАЖЕНИЕ, а не месить всё
> в одно корыто :)

Угу, значит писать:

select ...
union 0, "не указано"


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


 
Ega23 ©   (2009-02-19 12:50) [9]


> Такое поле д.б. NULL. Другие варианты говорят о том, что
> значение существует. А это не так.
> Об этом говорит теория реляционных БД.
> И надо разделять ХРАНЕНИЕ и ОТОБРАЖЕНИЕ, а не месить всё
> в одно корыто :)


В данной ситуации готов поспорить.
1. Жизнь штука многогранная. Если способ хранения данных, пусть и неправильный, помогает их отображению (работе с данными) - то пуркуа бы и не па? Разумную денормализацию ещё никто не отменял, да и не видел я реальных баз, которые соответствовали бы 4-й НФ. Всегда найдётся что-то "этакое".
2. NULL - штука сама по себе не сильно приятная. Хотя бы потому, что в одних случаях надо писать where T1.ID=12, а в других is not null.  Не очень красиво получается.
3. Если я прописал в таблицу сразу после генерации некое "защищённое" значение, то не вижу причин, почему бы его не использовать.


 
Ega23 ©   (2009-02-19 12:51) [10]


> MS SQL Server при добавлении новой записи в момент добаления
> присваивает ей идентификатор -1.


ЧЕГО????????


 
Johnmen ©   (2009-02-19 12:53) [11]


> Угу, значит писать:
> select ...union 0, "не указано"

Не значит. Это ещё один пример, когда замешиваются в одно корыто ПОЛУЧЕНИЕ данных и их ОТОБРАЖЕНИЕ.

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

Например?


 
Kostafey ©   (2009-02-19 12:59) [12]

> [10] Ega23 ©   (19.02.09 12:51)

Дочего же полезно на дельфимастер иногда заглядывать :)
Понял откуда эта -1. Н-нда, забавно. :)


 
Johnmen ©   (2009-02-19 13:01) [13]


> Ega23 ©   (19.02.09 12:50) [9]

Я говорю про теорию и идеологию.
Каждый волен от этого отступать как угодно далеко, если его жизнь станет легче. Но при этом он должен осознавать и просчитывать, что будущее может (именно МОЖЕТ, т.е. не обязательно) его напрячь сильнее, чем он сэкономил.


 
Kostafey ©   (2009-02-19 13:04) [14]

> [11] Johnmen ©   (19.02.09 12:53)
>
> > Угу, значит писать:
> > select ...union 0, "не указано"
>
> Не значит. Это ещё один пример, когда замешиваются в одно
> корыто ПОЛУЧЕНИЕ данных и их ОТОБРАЖЕНИЕ.

Тогда как?

> > но тогда чтобы в базе сохранить именно null потребуется
>
> > некотороеколичество дополнительного кода, что тоже не
> очень
> > удобно.
>
> Например?

Ну схематично, если в сиписке
select ...union 0, "не указано"
тогда
<h:selectOneMenu...
вернет 0

Значит должен быть Integer = null (ето java), который мы и
сохраняем в таблицу.


 
Ega23 ©   (2009-02-19 13:05) [15]


> Но при этом он должен осознавать и просчитывать, что будущее
> может (именно МОЖЕТ, т.е. не обязательно) его напрячь сильнее,
>  чем он сэкономил.


Золотые твои слова. Вот эту цитату следует на заглавную страницу конференции "Базы" вывести. Наряду с "В DBGrid нет никаких данных!"


 
Ega23 ©   (2009-02-19 13:06) [16]


> Дочего же полезно на дельфимастер иногда заглядывать :)
> Понял откуда эта -1. Н-нда, забавно. :)


Что там у тебя за -1 появилась?


 
Медвежонок Пятачок ©   (2009-02-19 13:06) [17]

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

если нулл, то все просто, если не нулл, то в запросе потребуется дополнительно сравнивать с константой.

а если это только для отображения, то выкручиваться средствами сервера типа оркалового decode(field,null,"empty",field)


 
Johnmen ©   (2009-02-19 13:08) [18]


> Kostafey ©   (19.02.09 13:04) [14]

Я не знаю яву.


 
clickmaker ©   (2009-02-19 13:09) [19]

вообще, если есть куча справочников, то нет смысла в каждом писать "не указано". Дублирование информации.
Такие строки-константы лучше отдельно хранить. В БД или в ресурсах - другой вопрос.


 
Kostafey ©   (2009-02-19 13:10) [20]

> [16] Ega23 ©   (19.02.09 13:06)
>
> > Дочего же полезно на дельфимастер иногда заглядывать :
> )
> > Понял откуда эта -1. Н-нда, забавно. :)
>
>
> Что там у тебя за -1 появилась?


Да это просто идентификатор текущей записи. В момент добавления
он не определен, а я просто ее инициализировал -1, это было уже
давно, вот и забыл.

P.S. смеялся долго :)


 
Игорь Шевченко ©   (2009-02-19 13:11) [21]

Johnmen ©   (19.02.09 12:09) [7]


> Такое поле д.б. NULL. Другие варианты говорят о том, что
> значение существует. А это не так.
> Об этом говорит теория реляционных БД.
> И надо разделять ХРАНЕНИЕ и ОТОБРАЖЕНИЕ, а не месить всё
> в одно корыто :)


"Почему-то, иногда любят использовать поля, в которых не стоит ограничение NOT NULL. Вроде бы ничего страшного. Если встречается значение NULL, значит, его нужно интерпретировать как некоторое значение по умолчанию. Но в этом и проблема. В любом месте, где встречается это поле, нужно делать проверки или использовать функции вида isnull. Если случайно забыть, можно получить ошибку приведения типа в целевом языке или неожиданный результат в арифметических операциях в SQL. Второй вариант, как правило, не вызывает больших неприятностей. Зато первый имеет особенность вызывать через некоторое время ошибки в программе, например, если появляется новый способ добавить запись в базу, не определяя все поля.

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

Конечно, есть ситуации, когда использование NULL-значений очень удобно. В классике, они означают отсутствие значения: или оно будет определено позже, либо вообще никогда. Стоит отметить, что только таким образом можно определить пустое значение для столбца с ограничением внешним ключом.

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

http://www.gurenkov.net/articles/database_patterns_1/

Тоже мнение.


 
clickmaker ©   (2009-02-19 13:14) [22]

> И если для столбца значение NULL не является специальным,
> лучше их запретить

насчет булевых полей, кстати, да. Как-то непривычно видеть там null... типа "может быть" -)


 
Johnmen ©   (2009-02-19 13:15) [23]


> Игорь Шевченко ©   (19.02.09 13:11) [21]

Хорошее мнение.
А у нас тут лишь подмножество этого мнения - NULL в ссылочном поле. Про него и говорим.
Т.е. "для столбца значение NULL является специальным".


 
Kostafey ©   (2009-02-19 13:15) [24]

> [18] Johnmen ©   (19.02.09 13:08)

Да в этом и не суть, просто запись хранится в объекте,
идентификатор привязываемого справочника - одно из свойств
объекта. Тип числовой. А числовой тип может быть 0, но не null,
значит нужно еще отдельно объектный тип, чтобы присвоить ему
злочастный null и уже его сохраняет, словом неудобно.


 
Johnmen ©   (2009-02-19 13:18) [25]


> Kostafey ©   (19.02.09 13:15) [24]

Тогда [9] и [13].


 
Ega23 ©   (2009-02-19 13:18) [26]


> вообще, если есть куча справочников, то нет смысла в каждом
> писать "не указано". Дублирование информации.
> Такие строки-константы лучше отдельно хранить. В БД или
> в ресурсах - другой вопрос.


Ну тут уже от сущности зависит. Хотя я с тобой во многом согласен. Года 2 назад ты крайне любопытную стратегию предложил по организации такой единой "помойки". Взял на вооружение... :)


> Медвежонок Пятачок ©   (19.02.09 13:06) [17]
> если нулл, то все просто, если не нулл, то в запросе потребуется
> дополнительно сравнивать с константой.


Блин, а сравнение с NULL - это не сравнение с константой?  :)

Я, собственно, почему за такой подход: в FK всегда будет строгое значение.


 
Игорь Шевченко ©   (2009-02-19 13:20) [27]


> Блин, а сравнение с NULL - это не сравнение с константой?
>   :)


Ни в коем разе


 
Johnmen ©   (2009-02-19 13:23) [28]


> Я, собственно, почему за такой подход: в FK всегда будет
> строгое значение.

Строгое значение ничем не лучше строгого отсутствия значения :)


 
Ega23 ©   (2009-02-19 13:23) [29]


> Ни в коем разе


Да ладно.
Не вижу разницы между
select * from table where column is not null
и
select * from table where column>1


 
Johnmen ©   (2009-02-19 13:28) [30]


> Ega23 ©   (19.02.09 13:23) [29]
> Не вижу разницы между

А она есть.


 
Ega23 ©   (2009-02-19 13:28) [31]


> А она есть.


Аргументируй.


 
Johnmen ©   (2009-02-19 13:45) [32]


> Ega23 ©   (19.02.09 13:28) [31]
> Аргументируй.

Чего аргументировать?
Что
> select * from table where column is not null
возвращает только непустые, а
> select * from table where column>1
большие 1 непустые
?


 
Ega23 ©   (2009-02-19 13:48) [33]


> большие 1 непустые


Они все непустые, если NOT NULL.


 
Johnmen ©   (2009-02-19 13:50) [34]


> Ega23 ©   (19.02.09 13:48) [33]
> Они все непустые, если NOT NULL.

Непустые, и что?


 
Медвежонок Пятачок ©   (2009-02-19 14:04) [35]

Блин, а сравнение с NULL - это не сравнение с константой?  :)

null это "корзырная константа". а для некозырной надо всегда знать, что там написано вместо нула.


 
Petr V. Abramov ©   (2009-02-19 14:28) [36]


> Ega23 ©   (19.02.09 13:23) [29]

если индексов нет - почти :) одно итоже
если есть индекс

column > 1 это index range scan
column is not null - или index full scan, или table access full, в зависимости от кол-ва null`ов в столбце

по теме - мне больше нравится ссылка на "не задано", избавляет от outer join`ов
хотя в жирной таблице, где "незаполнных" значений много и имеет смысл индекс, лучше оставить null


 
Ega23 ©   (2009-02-19 14:38) [37]


> если индексов нет - почти :) одно итоже
> если есть индекс
>
> column > 1 это index range scan
> column is not null - или index full scan, или table access
> full, в зависимости от кол-ва null`ов в столбце


О! А это уже пошли тонкости реализаций конкретных СУБД.
Что, безусловно, тоже надо учитывать при выборе стратегии.


 
Sergey Masloff   (2009-02-19 14:43) [38]

Ega23 ©   (19.02.09 14:38) [37]
а что есть базы в которых null в индексах хранится? сомневаюсь

Petr V. Abramov ©   (19.02.09 14:28) [36]
Если таблица нежирная то фуллскан даже лучше. Если жирная - рост индекса крайне нежелателен. То есть NULL почти всегда лучше. Так же?


 
Ega23 ©   (2009-02-19 14:50) [39]


> а что есть базы в которых null в индексах хранится? сомневаюсь


ЕМНИП, в MSSQL если строго один раз NULL встречается - то индексируется.


 
Sergey Masloff   (2009-02-19 14:59) [40]

Ega23 ©   (19.02.09 14:50) [39]
Кажется изменяет. Но не уверен - мое общение с MSSQL окончилось на версии 7



Страницы: 1 2 3 вся ветка

Форум: "Прочее";
Текущий архив: 2009.04.19;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.57 MB
Время: 0.049 c
2-1236076969
Кузя
2009-03-03 13:42
2009.04.19
передача поинтеров в длл и обратно


6-1202301817
dreamse
2008-02-06 15:43
2009.04.19
Вопрос про испорченую кодировку при скачивании файла по Http


10-1155558493
misha_gr
2006-08-14 16:28
2009.04.19
Интеграция приложения в MS Outlook


15-1234863241
Headlong
2009-02-17 12:34
2009.04.19
Установка Delphi 6


15-1234535049
Саша
2009-02-13 17:24
2009.04.19
Кто знает, как заблокироватть доступ к сайту.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский