Можно ли иметь такие нулевые значения?
Это субъективно.Вопрос: можете ли вы работать с этим?Вероятно, да.Но может ли это гарантировать целостность?Нет.
Так что может пойти не так?Вы можете установить оба внешних ключа или оставить оба значения NULL - и БД не будет жаловаться.Ни в том, ни в другом случае вы не знаете, кто обновил элемент.
Другой подход заключается в том, чтобы всегда устанавливать user_id
(NOT NULL) и разрешать client_id
необязательно.Если client_id
НЕДЕЙСТВИТЕЛЕН, вы знаете - он обновляется пользователем.Если это не NULL, тогда вы знаете - он обновляется клиентом.
Затем вы можете получить имя с помощью:
select at.*, coalesce(c.name, u.name) as updated_by
from app_audit at
join user_t u on u.id = at.user_id
left join client_t c on c.id = at.client_id
Но все равно может пойти не так.Вы можете сохранить идентификатор клиента, который не является «владельцем» приложения.То же относится и к user_id
.Из-за дизайна (audit-trail -> app -> client -> user) и client_id
, и user_id
функционально зависят от app_id
.Поэтому на самом деле все, что вам нужно, это app_id
в качестве внешнего ключа и логический флаг, который сообщает вам, обновляется ли он пользователем или клиентом.Затем вы получите данные с помощью:
select at.*, coalesce(u.name, c.name) as updated_by
from app_audit at
join app_t a on a.id = at.app_id
join client_t c on c.id = a.client_id
left join user_t u on u.id = c.user_id and a.updatet_by_user = 1
Относительно вашего комментария:
Я не верю в такие вещи, как «наилучший подход» или «наилучшая практика», когда проблема"достаточно сложный".Тогда возникает вопрос - Лучший для чего?Обычно у вас есть несколько целей, таких как четкость , простота , удобство использования , гибкость , надежность , производительность и, возможно, еще немного.«Лучший подход» к гибкости может стать кошмаром для производительности и наоборот.
Более широко используемый термин - " хорошая практика ".И нормализация базы данных считается хорошей практикой .Добавление user_id
и client_id
вводит функциональных зависимостей для не ключа-кандидата , что нарушает 3NF .
С другой стороны, без этих столбцов вам потребуется еще одно JOIN в ваших запросах SELECT.Но пока это не важно, мне было бы все равно.