Траблы-грабли-бумс!
Личный опыт не всегда может использоваться в качестве критерия истинности.
Среди занимающихся альпинизмом многие могут вам рассказать, как они сами нарушали правила безопасности во время восхождений и с ними ничего не произошло. Обратным опытом никто не делится. Покойники вообще не склонны делиться опытом.
Информационные системы разрабатывают уже более пятидесяти лет, и определенный опыт в этом деле накоплен. Не следует в его анализе исходить из предположения, что до вас, такого крутого и гениального, информационными технологиями занимались только идиоты. Второе предположение, что все правила придумали из-за недостатка быстродействия и памяти, а сейчас все по-другому, тоже ложно.
Казалось бы, перечисленные ниже утверждения давно стали аксиомами, так ведь все время находятся лобачевские, которые полагают, что они без этих аксиом обойдутся. И каждый раз получают по лбу. Поэтому все-таки не пренебрегайте очевидным нижеизложенным.
– Любую систему придется изменять на всех этапах ее жизненного цикла.
– Любые обещания, что что-то не будет меняться, а уж тем более расти в объеме, никогда не выполняются.
– В больших системах не бывает маловероятных событий. Все, что может случиться, обязательно случится. Пользователи в России и Австралии обязательно нажмут на нужные кнопки одновременно, если вы этого не предусмотрели.
– Если одна и та же информация хранится в двух местах системы, то через неделю эксплуатации в этих местах будет разная информация.
– Нарушение известных правил проектирования с целью экономии времени разработки всегда приводит к увеличению времени разработки.
Я совсем не считаю, что свод правил проектирования вечен и неизменен, но если вы хотите какое-то из этих правил нарушить, то сначала поймите, почему оно появилось и какие суперпреимущества вам дает его отмена.
Еще одна очевидность, про которую забывают разработчики: удобство и скорость разработки, безусловно, важны, но все-таки система в итоге оценивается по ее потребительским свойствам. Если есть выбор, написать семь процедур или одну, но в последнем случае скорость отклика системы изменится с 0,5 с на 5 с, то писать надо семь процедур.
Впрочем, уверен, что этот раздел написал без толку. Похоже, это тоже одно из вечных правил.
Ниже приводится перечень грабель, на которые наступали и продолжают наступать настолько часто, что их рукоятки уже отполированы лбами проектировщиков.
Грабли-рекордсмены
Наверное, рукоятка таких грабель изготовлена из особо ценных и прочных пород дерева. Иначе непонятно, как они столько лет бьют по лбам горе-проектировщиков и до сих пор не сломались.
Сейчас мне кажется, что абсолютный запрет на любую семантическую интерпретацию идентификационных кодов мне внушили еще в детском саду. Вряд ли это так. Но по окончании института (хотя это произошло через пятнадцать лет после окончания детского сада, но уже тридцать лет назад) я точно знал, что в идентификационном коде не должно быть никакой семантики.
Никакой. НИКАКОЙ! НИКАКОЙ!!! Только циферки, которые однозначно определяют объект, и никакого другого смысла. Этому учили еще до появления классических работ Дейта и Кодда.
Но все-таки в каждом проекте у кого-нибудь начинает зудеть и чесаться.
«А давайте первая цифра кода у нас будет номером цеха, который выпускает изделие, вторая – номером отдела, который занимается продажей…» И что произойдет, когда у вас появится десятый цех или отдел? А когда изделие начнут в двух цехах собирать, какую цифру ставить? И как перевести производство из одного цеха в другой? Менять код изделия или запрещать перевод производства?
Да, а еще в код иногда засовывают буквы. А буква «А» есть как в русском алфавите, так и в латинском. И – увы! – для системы это РАЗНЫЕ буквы (хотя и не всегда можно это объяснить пользователю). Это создает много радости при ручном вводе новых идентификаторов и еще больше радости, если справочники и транзакции приходится загружать из другой системы. – Д. К.
«А давайте включим в id товара код группы и подгруппы…» А что вы будете делать, когда потребуется поменять код группы или подгруппы? Лопатить всю базу, разыскивая нужный id, и заменять его на другой? «А мы ничего не будем делать. Все равно в 90 % случаях группа и подгруппа будет верной». Вы этой мыслью с главбухом поделитесь. Ему очень понравится правильный расчет НДС с вероятностью 0,9. И не исключено, что на одного плохого проектировщика станет меньше.
«А давайте у нас id накладной и будет ее номером». Не давайте. Когда система встанет, накладные будут выписывать вручную, а потом в систему нужно будет ввести именно те номера, которые оказались на бумажных накладных, даже если это одинаковые номера. И накладные поставщиков неплохо завести в систему под теми номерами, под которыми они нам выданы.
И выучите, наконец, зазубрите, напишите на мониторе, сделайте татуировку на лбу: вводя любое информационное поле для любого объекта, можно ошибиться или передумать. Поэтому идентификационный код всегда—всегда!!! – должен генерироваться автоматически и не иметь никакой информационной нагрузки.
Грабли классические
Суббота, десять вечера. Из продовольственного магазина, в котором внедряется пилотный проект складской системы, звонит кладовщик. Едва не плача, он сообщает, что принял товар на склад, а секции его выдать не может, поскольку товар пропал. А если его срочно не продать, то он протухнет.
Приезжаю. Пытаюсь найти товар на складских карточках. Действительно, найти не получается. А приходная накладная есть. В ней все правильно. Смотрю отчет по товародвижению – в нем все на месте. Проверяю суммарные остатки по складу – накладная учтена. То есть товар на складе есть, а вот найти его нельзя. Правда, на этом складе уже восемь тысяч карточек, так что визуально товар не обнаружить, если даже он есть. Уточняю, что делал кладовщик.
– Это новый товар. Я его сначала завел по бумажной накладной в справочник номенклатуры, потом ввел саму накладную. А потом посмотрел на сам товар и понял, что это тефтели, а не котлеты, как написано в накладной.
– И как ты поступил?
– Исправил запись в справочнике номенклатуры. А в накладной все изменилось само.
– Кажется, я понял, – отвечаю я, подумав. – Смотри, – и набираю в строке поиска «котле». Экран прокручивается, и на нем подсвечивается строчка «Тефтели». За спиной раздается восхищенное «Ой», но я в это время уже представляю, что я сделаю с разработчиками в понедельник.
Но воскресенье, предшествующее встрече, их спасает. Я не только никому ничего не пытаюсь оторвать, я даже могу разговаривать, используя только слова литературного русского языка:
– Вы что, название товара записываете на складской карточке?
– Мы только первые пять символов записываем, чтобы поиск шел быстрее.
Тут я становлюсь даже ласковым:
– А что вы делаете, если складские карточки уже созданы, а я наименование в номенклатурном справочнике поменяю?
– Кажется, ничего не делаем.
– То есть если я завел на склад «котлеты», а потом исправил в справочнике номенклатуры название на «тефтели», то что я увижу на карточке?
– «Тефтели».
– А искать мне что нужно?
– «Котлеты»… Наверное, это не совсем правильно…
– Не совсем правильно?
– Согласен, это совсем неправильно. Мы к следующему обновлению переделаем…
Я начал именно с примера, чтобы не пугать читателя высоконаучными словами. Но в приведенном случае были нарушены принципы проектирования баз данных, описанные в классических работах 1970-х годов. Таблица базы «Складские карточки» не находится в третьей нормальной форме. Про это уже столько понаписано, что мне и добавить нечего. Появление новых СУБД и новых способов поддержания зависимостей в базе данных совершенно ничего не меняет: грабли продолжают работать даже при использовании триггеров и джобов (заданий, запускаемых автоматически в определенные моменты суток или через определенные временные интервалы).
Все попытки поддерживать целостность и непротиворечивость данных не на уровне схемы базы, а с помощью программных примочек натыкаются на одно практически непреодолимое препятствие: в достаточно сложных системах вы просто забываете это сделать для некоторых вариантов работы.
Кстати, неумелое использование перечисленных инструментов, на мой взгляд, приводит к последствиям более страшным, чем их полное неиспользование.
Грабли ленивые
Вы задумывались, что произойдет, если джоб, который стартует каждые 15 минут, в среднем работает два часа? А что будет, если выполнение триггера займет две минуты? В обоих случаях последствия могут быть разнообразными, но всегда неприятными и, что еще хуже, непредсказуемыми.