сваял я както давно проект простой ,а оказался что не такой он уж и простой
до сих пор не могу приудмать приемлемого решения
задача на самом дел обычная но решения все кажутся монструозными
в общем, пусть реляционная БД и есть связь, ордер-продукт
пусть мы создали ордер напихали в него продуктов,
обработали его и закрыли
а потом мы поменяли названия ордеров....или имя кастомера, или категории ордеров, или название пакета содержащего продукты
и сразу в базе появилось фуфловые ордеры
я знаю пару методов, один ужасный а дургой еще ужаснее.
а как можно сделать что-то малой кровью тут?
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Здравствуйте, Kingofastellarwar, Вы писали:
K>а как можно сделать что-то малой кровью тут?
Защита от случайных изменений — запретить редактирование ордеров со статусом "закрыт".
От преднамеренных изменений — вести лог действий пользователей: такой-то пользователь такого-то числа поменял то-то и то-то. В простейшем случае такой журнал можно вести в неструктурированном виде, т.е. обычним текстом
Не совсем ясна задача, но возможное решение — версионирование записей. То есть вместо изменения данных создаётся новая запись и помечается как активная, все старые связи сохраняются и указывают на старую (старые) запись, все новые создаются с использованием новой версии.
В принципе даже архитектуру это не должно особо затронуть — просто перейти на работу с вьюшками, и добавить им триггеры на апдейт, которые будут реализовывать всю логику.
PS. Это, конечно, сложно назвать "малой кровью", но альтернативы это либо создание отдельных архивных записей (т.е. deep-copy всех связей в отдельные таблицы, или в те же но с флагом архива), либо вообще сериализация ордера в xml со всеми зависимостями и хранение в таком виде, ну или отдельное извращение когда пишутся только изменения а запись реконструируется на лету из основы и изменений на заданный момент времени (этот изврат в реляционной БД, имхо, ничто оправдать не может).
PS2. Есть ещё вариант, когда сама база поддерживает историю записей и позволяет сделать запрос на указанный момент времени, но я с таким не работал. Вроде такое может oracle и sql server 2016.
Здравствуйте, Kingofastellarwar, Вы писали:
K>а как можно сделать что-то малой кровью тут?
Можно аккуратно проектировать базу под задачу.
Многие начинающие архитекторы, начитавшись про нормальные формы, дизайнят базы, не соответствующие задаче.
Дело в том, что, к примеру, название контрагента в справочнике контрагентов и название контрагента в документе на отгрузку — это два разных названия. Подменять одно ссылкой на другое — это нарушение условий задачи.
Более очевидный случай той же самой проблемы — это адрес доставки заказа.
Достаточно очевидно, что смена предпочтительного адреса доставки в профиле клиента не должна влиять на уже доставленные заказы — т.е. адрес надо копировать в заказ, а не ссылаться на эфемерную сущность.
Так и везде — во всех документах надо хранить и ссылку на справочник (что позволит, к примеру, найти все заказы ООО Парнас за 20 лет работы с нами, независимо от трёх переименований и двух смен форм собственности), и копию всех реквизитов. А обновлять копию нужно только при движении документа, и то не при всяком.
Это же касается и позиций заказа — мало ли что теперь у нас этот товар называется "вермут 14.8", продавался в 2001 году он как "вермут 15.0", и именно так он фигурирует в документах, на которых стоят подписи и печати. А то, что неудачно спроектированная информационная система делает с цифровым представлением этих документов, представляет собой квантовую суперпозицию статей 327 и 273 УК РФ.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Достаточно очевидно, что смена предпочтительного адреса доставки в профиле клиента не должна влиять на уже доставленные заказы — т.е. адрес надо копировать в заказ, а не ссылаться на эфемерную сущность.
Более правильный вариант — всегда ссылаться на справочник, в том числе и в профиле клиента. При обновлении просто создаётся новая запись в справочнике, а старая помечается как "устаревшая".
Здравствуйте, Cyberax, Вы писали: S>>Достаточно очевидно, что смена предпочтительного адреса доставки в профиле клиента не должна влиять на уже доставленные заказы — т.е. адрес надо копировать в заказ, а не ссылаться на эфемерную сущность. C>Более правильный вариант — всегда ссылаться на справочник, в том числе и в профиле клиента. При обновлении просто создаётся новая запись в справочнике, а старая помечается как "устаревшая".
Да, так тоже можно. Но это — полшага до темпоральных баз, где все таблицы хранят всю историю изменений.
Для адресов подобное решение естественно, т.к. в нормальных системах у клиента всегда хранится N адресов — и это видно в UI, поэтому никаких затруднений использование не вызывает.
А вот, скажем, для реквизитов компании или для описания товара такая схема — оверкилл.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.