|
|
|
Внешний ключ "-1" как отсутствие ссылки
|
|||
|---|---|---|---|
|
#18+
Доброго дня. Смотрю БД, которую разработали коллеги, там во многих случаях в качестве внешнего ключа используется значение -1 (не null) для обозначения отсутствия ссылки. В главной таблице записи с ID = -1 нет. Мне интуитивно понятно, что это плохо и неправильно (нужно использовать null), а вот аргументы, почему это так придумать не могу. Подскажите, чем плохо так делать и плохо ли? Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.11.2016, 11:22 |
|
||
|
Внешний ключ "-1" как отсутствие ссылки
|
|||
|---|---|---|---|
|
#18+
stuffhappens, Спросите у коллег. Если так сделано то не просто так. Видимо есть на то причины. А мы не телепаты и не можем знать что там у вас и как. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.11.2016, 11:27 |
|
||
|
Внешний ключ "-1" как отсутствие ссылки
|
|||
|---|---|---|---|
|
#18+
stuffhappensв качестве внешнего ключа используется значение -1 (не null) для обозначения отсутствия ссылки. В главной таблице записи с ID = -1 нет. Это точно внешний ключ (конструкция FOREIGN KEY) ? Если да, то как оно допускает в дочернюю таблицу записи, для которых нет значения в головной? Если нет, то так и надо говорить - коллеги по каким-то причинам не используют FOREIGN KEY. И выяснять причины. А как они дошли до жизни до такой, как контролируют ссылочную целостность? Телепатирую, что самописными триггерами, или вообще на клиенте. Если так, то в общем-то фиолетово, что за волшебные значения они себе придумали. Единственный вопрос, что приходит в голову - как они с этими минус-единицами OUTER JOIN'ы делают. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.11.2016, 11:39 |
|
||
|
Внешний ключ "-1" как отсутствие ссылки
|
|||
|---|---|---|---|
|
#18+
Cane Cat FisherЕдинственный вопрос, что приходит в голову - как они с этими минус-единицами OUTER JOIN'ы делают.Ничем не отличается с т.з. БД. Отсутствие записи подходящей по условию генерирует одну запись со всеми полями равными null, и пофиг какие значения в условии - null, -1 или вообще "left join on 'b'<'a'". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.11.2016, 11:50 |
|
||
|
Внешний ключ "-1" как отсутствие ссылки
|
|||
|---|---|---|---|
|
#18+
Cane Cat Fisher, Говоря внешний ключ - я имею в виду логическую связь таблиц, не физический объект субд. Клиентов нет, это хранилище данных. Пользователи работают с таблицами. Триггеров и ключей нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.11.2016, 11:53 |
|
||
|
Внешний ключ "-1" как отсутствие ссылки
|
|||
|---|---|---|---|
|
#18+
stuffhappens Мне интуитивно понятно, что это плохо и неправильно (нужно использовать null), а вот аргументы, почему это так придумать не могу. Не работает встроенный механизм ссылочной целостности(в лучшем случае его заменяет некий сапописный велосипед, в худшем нет вообще никакого). Это может вести к мусору в БД. + в запросах возникают "магические числа" (каждый читающий запрос должен знать, что это за -1, как понимать проверку "поле <> -1" и т.п.) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.11.2016, 12:01 |
|
||
|
Внешний ключ "-1" как отсутствие ссылки
|
|||
|---|---|---|---|
|
#18+
stuffhappensCane Cat Fisher, Говоря внешний ключ - я имею в виду логическую связь таблиц, не физический объект субд. Клиентов нет, это хранилище данных. Пользователи работают с таблицами. Триггеров и ключей нет. Для DWH у нас так и было, но на физическом уровне скрипт создания любой таблицы содержал INSERT .. VALUES (-1) в суррогатный ключ. Т.е. в любой таблице всегда была запись с -1, и которую нельзя было апдейтить (это если ETL-щики косячили). Идея была в том, что все джойны были inner. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.11.2016, 12:15 |
|
||
|
Внешний ключ "-1" как отсутствие ссылки
|
|||
|---|---|---|---|
|
#18+
что это плохо и неправильно (нужно использовать null)Чем неправильно ? Нормально, бро... :) Ну и что, что не раб. СЦ ? Нужно иметь штатную процедуру удаления, кот. и принимает решение можно удалять или нет. Причем условия могут быть сложные. Иногда просто удобно, что есть возможность удалить записи, а потом их перезалить. В случае с СЦ это можно сделать лишь удалив СЦ, с послед.восстановлением. Что не удобно. Большинство готовых систем совершенно не используют СЦ. Примеры ? Возьмите любую ERP или даже 1С. Любую Карл !!! зы: толчем воду в ступе. Уже обсуждали много раз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.11.2016, 15:16 |
|
||
|
Внешний ключ "-1" как отсутствие ссылки
|
|||
|---|---|---|---|
|
#18+
В 1С вообще нет ссылочной целостности, зато есть всякие "Пустая ссылка" и "Неопределено" и как-то вертится И NULL тоже есть местами ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.11.2016, 15:31 |
|
||
|
Внешний ключ "-1" как отсутствие ссылки
|
|||
|---|---|---|---|
|
#18+
stuffhappensМне интуитивно понятно, что это плохо и неправильно (нужно использовать null), а вот аргументы, почему это так придумать не могу. Подскажите, чем плохо так делать и плохо ли? Так делать плохо потому, что это вносит в систему большое количество дорогих в смысле последствий ошибок. Мне довелось полтора года работать с системой, написанной подобным образом, и за это время от трети до половины серьёзных проблем, которые я решал, было прямым следствием этой практики. То есть - при null-ах тот же код работал бы правильно. Причина проблем в том, что условия вида a.id = b.id и a.id = :param дают false positives, ложные срабатывания при -1, которых не давали бы при null. По-хорошему, каждое условие связи в такой модели нужно довешивать проверкой на <> -1, но программисты постоянно забывают это делать, во всяком случае если пишут запросы руками. А дальше, даже если на момент написания кода работало без явных проблем, с учётом того, что бизнес-логика со временем модифицируется, начинаются всякие интересные эффекты. Ну просто ради примера, одна из проблем, которую пришлось разгребать: а) На некую таблицу повесили триггер, обновляющий при её изменении денормалированные данные в другой таблице. б) Через полгода добавился бизнес-кейс, и в этой другой таблице разрешили иметь незаполненную ссылку на первую. При этом "денормалированное" поле становилось доступно для редактирования и заполнялось руками. в) Как оказалось, есть одна редко нажимаемая кнопка в совершенно другой части системы, результатом которой являлась ночная репликация набора связанных данных с одного сервера на другой. И в этот набор запросто попадала "пустая" запись из первой таблицы. Profit! Пользователи бегут с криками "мы вечером назначали-назначали инженеров на выезды, а утром снова приехали - и ни фига никто не назначен, им надо ехать по клиентам, а они вместо этого толпятся у нас под дверью и орут". Вывод - так можно делать либо если существует возможность проконтролировать все выполняемые SQL-и (например, если они генерируются собственным движком), либо если очень не хватает постоянного геморроя, ночных авралов и заслуженного мата от пользователей, руководства и тех, кому предстоит это разгребать. ГхостикНичем не отличается с т.з. БД. Ага, наивные чуваки, закладывавшие систему выше, тоже так думали. А я потом разбирался с интересным вопросом "целой куче договоров цены были посчитаны по курсу не на дату подписания, а на первое марта две тысячи второго года". Почему первое марта? Да это была дата создания "пустой" записи в одной из таблиц, вот она и вытаскивалась джойном куда не надо. stuffhappensКлиентов нет, это хранилище данных В хранилище данные обычно заливаются довольно небольшим ETL, который реально сделать без ошибок, а запросы строятся от центральной таблицы. Поэтому в нём такая практика не имеет таких уж резких минусов, какие я описал выше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2016, 02:32 |
|
||
|
Внешний ключ "-1" как отсутствие ссылки
|
|||
|---|---|---|---|
|
#18+
stuffhappensДоброго дня. Смотрю БД, которую разработали коллеги, там во многих случаях в качестве внешнего ключа используется значение -1 (не null) для обозначения отсутствия ссылки. В главной таблице записи с ID = -1 нет. Мне интуитивно понятно, что это плохо и неправильно (нужно использовать null), а вот аргументы, почему это так придумать не могу. Подскажите, чем плохо так делать и плохо ли? Спасибо.ну, дак, на -1 (не существующее значение primary) внешний ключ не станет, в отличии с null. как такое вам удалось? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2016, 02:40 |
|
||
|
Внешний ключ "-1" как отсутствие ссылки
|
|||
|---|---|---|---|
|
#18+
Relic Hunter, Ну создать-то создали, а при этом навесили на foreign key какое-нибудь NOVALIDATE или RELY. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2016, 14:03 |
|
||
|
Внешний ключ "-1" как отсутствие ссылки
|
|||
|---|---|---|---|
|
#18+
Злой БобрСпросите у коллег. Если так сделано то не просто так. Видимо есть на то причины. А мы не телепаты и не можем знать что там у вас и как. Может быть все довольно тривиально, например ссылочной целостности нет , а кого-то уже достал избыточный классификатор (пока найдешь нужное - задолбаешься листать), решили его почистить, а всё что с ним связано - стало жалко (статистика или ещё чего), вот и удалили лишнее в главной таблице, а в подчиненной ссылки поправили на -1, что значит голова была, но удалена (чисто для понимания), null тоже покатит, но трудно понять голову рубили или её вообще никогда не было... ИМХО скорее всего по смыслу содержимого полей там где -1 можно восстановить классификатор если чего и не получить по голове за снос окончательный, да и копия классификатора небось тоже где-то валяется в закромах... Можно в классификатор завести: -1 значит "Удалено" и успокоиться (если действительно я угадал), ну и попробовать сделать всё-таки СЦ на будущее, заодно и мусор весь всплывет наружу... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2016, 16:56 |
|
||
|
Внешний ключ "-1" как отсутствие ссылки
|
|||
|---|---|---|---|
|
#18+
vmag, это я типа с Бобром полностью согласен, чтоб не было непонимания... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2016, 16:57 |
|
||
|
|

start [/forum/topic.php?fid=32&fpage=13&tid=1540256]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
40ms |
get topic data: |
12ms |
get forum data: |
2ms |
get page messages: |
72ms |
get tp. blocked users: |
2ms |
| others: | 231ms |
| total: | 386ms |

| 0 / 0 |

Извините, этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
... ля, ля, ля ...