из-за нуллов?Ivan_Pisarevsky писал(а):Почему народ упорно не желает юзать внешние таблицы?
Применение null
-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34
Во-первых, давайте обойдёмся без "падонкаффского" языка.Merlin писал(а):Вапервых, нулл - это не значение. Вавтарых - элементарно, Ватсон. Дата события, которое есчо не наступило.
Во-вторых, "ещё не наступило" - это вы сами придумали интерпретацию, база о ней ничего не знает.
В-третьих, "нулёвую" дату во внешней таблице представить просто - пустой строкой, это с текстовыми полями проблема.
В-четвёртых, без null легко можно обойтись, вынеся такие поля в отдельную, детализирующую, таблицу.
Например:
Код: Выделить всё
CREATE TABLE EVENTS (
ID INTEGER NOT NULL,
EVENT_DATE DATE NOT NULL);
CREATE TABLE TABLE1 (
ID INTEGER NOT NULL,
...
EVENTID INTEGER NOT NULL DEFAULT 0);
Дату можно получить, поискав в EVENTS, и если записи нет - вот вам и "ещё не наступило".
Вот тока не нада меня учить ни хорошим манерам, ни проектированию, лана? Я ничего не придумываю, а отражаю реальную действительность как она есть. А база - она вообще ничего не знает, не её ума дело - что-либо знать. Ну и прикинь теперь элементарные запросы с использованием этой искусственной кочерги 1:1. Везде совершенно лишний и ненужный левый джойн, отнюдь производительности не прибавлящий, особенно на фильтрациях и сортировках по этому полю. Особенно если учесть, что в хорошей базе среднестатистический запрос и так цепляет 10-15 таблиц, а этот лефт ещё попотеешь впихнуть в цепочку иннеров чтоб не сбить оптимизатор с толку и получить оптимальную последовательность соединений. 1:1 из-за одного атрибута - нонсенс, если речь не о длинном варчаре, конечно. На каждый датный атрибут по таблице - это сильный ход, ничего не скажешь
Это не сарказм. Я реально посмеялся.WildSery писал(а):Это сарказм? Тогда обоснуйте крайнюю необходимость поля со значением null.
Камрад Merlin правильно расписал. Добавлю свою толику.
Такая простая вещь, как журнал регистрации каких-нибудь заявок. У меня, например, в одном 5 (пять) timestamp'ов, из которых not null только один - дата регистрации. Остальные заполняются по мере ее обработки. Джойн тут совершенно неуместен, так же как и строковый тип (увеличенный размер записи), плюс проблема с сортировкой и отбором.
P.S. Не хотел разводить тут оффтоп, но пришлось. Поэтому буду благодарен, если ты в отдельной теме в разделе, например, "Пятница", проведешь мастер-класс, как писать базы твоим стилем. Со скриптами реальных баз данных.
-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34
Коллега, с Вашими безапелляционными заявлениями, отдающими юношеским максимализмом, скажите спасибо, что Вас в иносказательной форме направляют на путь истинный, а не грубо шлют лесом. "НУЛЛ" это такой же инструмент, как скажем топор, им можно пойти и дров наколость, а можно себе пальцы отрубить и вопить потом на всех углах, что топор вредный инструмент.WildSery писал(а):если в таблице есть null - значит, БД плохо спроектирована
Например у меня в таблице заголовков накладнух есть поле "примечание", которое в 90% пустует и я его со спокойной совестью храню в виде "нулл", а бывает туда надо что-нидь вписать, зачем сюда еще какое-то педали в виде доп таблиц?
А ненаступившие события я храню в виде большой даты, которая точно в ближайшую тыщу лет не наступит, просто я прикинул так и эдак и пришел к выводу, что мне так удобней, применительно, к примеру, к неизрасходованному товару на складе, он у меня закреплен за специально обученной накладнухой, которая будет израходована в махнадцатом году. А если в другом месте мне будет выгодней хранить ненаступившее событие в виде нулл-а, то я так и сделаю.
Я вовсе не так категоричен, как вам могло показаться, а всего лишь поиронизировал над суждением, что внешние таблицы из-за null неюзабельны. И в моей базе тоже есть null. И даже много где
Есть и даты далёким будущим, т.к. промежутки удобно выбирать по вывернутому условию, типа where :date_val between datestart and dateend
Есть и даты далёким будущим, т.к. промежутки удобно выбирать по вывернутому условию, типа where :date_val between datestart and dateend
По-моему, неудачный пример. Чем вас пустая строка вместо null не устроила?Например у меня в таблице заголовков накладнух есть поле "примечание", которое в 90% пустует и я его со спокойной совестью храню в виде "нулл", а бывает туда надо что-нидь вписать
-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34
Все нормально юзабельно, просто надо помнить о нуллах и не забыть их адекватно обработать, простейший рецепт выше есть.WildSery писал(а):Я вовсе не так категоричен, как вам могло показаться, а всего лишь поиронизировал над суждением, что внешние таблицы из-за null неюзабельны.
Это вполне адекватный пример когда не стоит уделять столько внимания нуллам, они мне не мешают и аллергией я не страдаю. В этом конкретном случае нуллы можно и искоренить, только выгода от этого никак трудозатрат не окупит, потому как выгода эфемерна от этого.WildSery писал(а):По-моему, неудачный пример. Чем вас пустая строка вместо null не устроила?
Грабельки положил. Если когда-нить возникнет потребность в конкатенации с чем-нить (скажем, комментария в накладной и в связанном счёте), придётся мудохаться с коалеской и помнить про это. Спокойней дефолт пустая строка засадить и забыть.Ivan_Pisarevsky писал(а): Например у меня в таблице заголовков накладнух есть поле "примечание", которое в 90% пустует и я его со спокойной совестью храню в виде "нулл"
А тут грабельки противоположного сорту - отсёк себе возможность искать на "больше", только диапазоном. Нулл именно в датах как раз удобен, именно потому, что в этом случае он отражает реальну действительность, данную нам в ощущениях. Есть, скажем, заказ, но он ещё не подтверждён. Событие ещё не наступило и даты подтверждения именно нет, ни под какие условия значение поля в записи не подпадает автоматически потому что значения-то и нету, в отличие от сомнительности смысла нулла в других типах. И, соответственно, в датах неудобно его отсутствие, в других типах присутствие.Ivan_Pisarevsky писал(а): А ненаступившие события я храню в виде большой даты, которая точно в ближайшую тыщу лет не наступит
Уважаемый, вы конкретно написали:WildSery писал(а):Я вовсе не так категоричен, как вам могло показаться, а всего лишь поиронизировал над суждением, что внешние таблицы из-за null неюзабельны. И в моей базе тоже есть null. И даже много где
Противоречите сами себе! В следующий раз подумайте, прежде чем ляпнуть подобное, да еще таким тоном. Дабы у читателей не вызывать сомнения в вашей дееспособности.WildSery писал(а):если в таблице есть null - значит, БД плохо спроектирована
С точки зрения облегчения своего труда - верно. А с логической - имхо, не совсем... Поэтому в своем генераторе запросов сделал функцию шаблона коалески и забыл про null . Запросы, правда, здоровые получаются , особенно когда строка адреса собирается...Merlin писал(а):Грабельки положил. Если когда-нить возникнет потребность в конкатенации с чем-нить (скажем, комментария в накладной и в связанном счёте), придётся мудохаться с коалеской и помнить про это. Спокойней дефолт пустая строка засадить и забыть.
-
- Заслуженный разработчик
- Сообщения: 644
- Зарегистрирован: 15 фев 2005, 11:34
>Грабельки положил. Если когда-нить возникнет потребность в конкатенации с чем-нить (скажем, комментария в накладной и в связанном счёте)...
Скорее теоретически, на практике в данном конкретном случае - нет. Это поле ни в каких отборах, джойнах, склейках не участвует и не будет, поэтому я и забил на него. Где вероятность описаных грабель есть стараюсь сразу принять адекватные меры, например описаные тобой выше про нот нулл+дефалт значение.
>А тут грабельки противоположного сорту...
Тут можно много спорить, но сделано осмысленно, в результате скорость выборок и простота запросов на хорошом уровне. Все просто и убойно, как двуствольный дробовик, и никаких мега процедур для копошения в этих датах не применяется.
Скорее теоретически, на практике в данном конкретном случае - нет. Это поле ни в каких отборах, джойнах, склейках не участвует и не будет, поэтому я и забил на него. Где вероятность описаных грабель есть стараюсь сразу принять адекватные меры, например описаные тобой выше про нот нулл+дефалт значение.
>А тут грабельки противоположного сорту...
Тут можно много спорить, но сделано осмысленно, в результате скорость выборок и простота запросов на хорошом уровне. Все просто и убойно, как двуствольный дробовик, и никаких мега процедур для копошения в этих датах не применяется.
Простота запросов, говорите. Вместо 'where date_field is null' вы пишете 'where date_field = date_constant'. Ну или :somedate. Смотря на первый вариант, вы понимаете - отбор накладных, которые еще не оплачены (если это дата оплаты). Во втором варианте - действие непонятно.Ivan_Pisarevsky писал(а):Тут можно много спорить, но сделано осмысленно, в результате скорость выборок и простота запросов на хорошом уровне. Все просто и убойно, как двуствольный дробовик, и никаких мега процедур для копошения в этих датах не применяется.
Плюс есть такая вещь, как валидность даты. Если дата накладной датируется каким-нибудь 3457 годом, непонятно, это сбой или ваша та самая "магическая" дата?
"в результате скорость выборок и простота запросов на хорошом уровне". Хотите сказать, из-за отказа от Null скорость выполнения стала быстрей, чем с Null?
Я себе не противоречу и не утверждал, что моя база спроектирована хорошо. И если уж с иронии (с которой я и утверждал, мой смайлик вы не процитировали) переходить на суровую действительность, то null кроме как для дат, ни для чего неприменим. С null вы расставляете грабли для себя - вычисления, конкатенация, индексы, агрегаты...CyberMax писал(а):Противоречите сами себе! В следующий раз подумайте, прежде чем ляпнуть подобное, да еще таким тоном. Дабы у читателей не вызывать сомнения в вашей дееспособности.
Кто-то тут говорил о топоре и умении им пользоваться. Им хорошо рубить. А ещё можно забить гвоздь. Но лучше молотком.
Вы невнимательны. Я привёл такой пример. Если некие события в таблице хранятся диапазонами datebeg..dateend, и постоянная задача выяснить, в какой диапазон(ы) входит дата :date_in, то это элементарно выясняется запросом select * from table where :date_in between date_beg and date_end."в результате скорость выборок и простота запросов на хорошом уровне". Хотите сказать, из-за отказа от Null скорость выполнения стала быстрей, чем с Null?
Мда. Какая может быть ирония при проектировании. Здесь не состязание в остроумии. Ладно, проехали. Вернемся к полям.
Открываю "Руководство разработчика" Х. Борри. Какие категории типов данных есть?
1. Числовые.
Варианты использования:
а. Просто значение. Null необходим, если это, например, номер корпуса, количество квартир в доме, количество этажей. Их не может быть 0, а именно либо незаполненно либо больше 0.
б. Ссылка на мастер-таблицу. Not Null.
в. Ссылка на деталь-таблицу. Например, на диспетчера, мастера, слесаря. Может быть не заполнено вообще. Ссылка на запись с "пустым" работником не применима, так как работник НЕ УКАЗАН и работник ПУСТОЙ - две разные вещи.
Здесь Null нужен.
2. Дата. Уже обсуждалось. Null нужен.
3. Символьный тип. Поле примечания, поле телефона, ФИО и прочее. Null нужен.
4. BLOB. Тут тоже все понятно. Null нужен.
Вывод: Null нужен со всеми типами данных.
Для каждой задачи - свое. Где надо - я ставлю ограничение Not Null, где не надо - не ставлю. А вы все под одну гребенку гребете.
Открываю "Руководство разработчика" Х. Борри. Какие категории типов данных есть?
1. Числовые.
Варианты использования:
а. Просто значение. Null необходим, если это, например, номер корпуса, количество квартир в доме, количество этажей. Их не может быть 0, а именно либо незаполненно либо больше 0.
б. Ссылка на мастер-таблицу. Not Null.
в. Ссылка на деталь-таблицу. Например, на диспетчера, мастера, слесаря. Может быть не заполнено вообще. Ссылка на запись с "пустым" работником не применима, так как работник НЕ УКАЗАН и работник ПУСТОЙ - две разные вещи.
Здесь Null нужен.
2. Дата. Уже обсуждалось. Null нужен.
3. Символьный тип. Поле примечания, поле телефона, ФИО и прочее. Null нужен.
4. BLOB. Тут тоже все понятно. Null нужен.
Вывод: Null нужен со всеми типами данных.
Камрад, я вас никак не понимаю. Откуда опять такая категоричность?WildSery писал(а):то null кроме как для дат, ни для чего неприменим. С null вы расставляете грабли для себя - вычисления, конкатенация, индексы, агрегаты...
Для каждой задачи - свое. Где надо - я ставлю ограничение Not Null, где не надо - не ставлю. А вы все под одну гребенку гребете.
1. Вообще-то я не вам это писал.WildSery писал(а):Вы невнимательны. Я привёл такой пример. Если некие события в таблице хранятся диапазонами datebeg..dateend, и постоянная задача выяснить, в какой диапазон(ы) входит дата :date_in, то это элементарно выясняется запросом select * from table where :date_in between date_beg and date_end.
2. А если select * from table where (:date_in between date_beg and date_end) or (date_end is null)? Что логичнее.