вторник, февраля 26, 2008

Ноль это бесконечность, а минус единица это ноль

В некотором отделе некоторой компании разрабатывали продукты, да не простой а коробочные. Целые отдел маркетинга днями и ночами продукты те толстым буржуям продавал, да лицензии для них генерировал. И были те лицензии не простые, а с ограниченным сроком годности. Кому на месяц, кому на полгода, а кому и год. Жили они так не тужили, пока отдел маркетинга не задумался, а что это мы продукты по одному продаем, несолидно. Cтали они продукты на части разбирать в ящики складывать и ящики продавать. А на ящиках тех златом, али серебром писать слова иностранные. Все бы ничего, да продукт-то программный, а значит ящики — фикция одна. Дело только в лицензиях, в которых для каждой части строчка отдельная добавилась. А в строчке той цифирь, означающая сколько частей в ящике. Тут бы им жить поживать, да встретился местный барин на какой-то конференции с барином иностранным, другом старым. Тот-то ему и пожаловался: «Мы, — говорит, — друзья старые, а твои архаровцы меня заставляют на каждую новую часть отдельную лицензию делать. А у меня этих лицензий уже два камаза с прицепом» Призвал барин программистов пред светлы очи и повелел бесконечную лицензию выдумать. Но поскольку призывал он всех по отдельности, разные продукты разное выдумали, потому как нет такой цифири «бесконечность». Один решил вместо бесконечности «0» писать, все равно на ноль штук лицензия не нужна. Другой решил, что ноль ему пригодится и «-1» под такое дело зарезервировал. Ну а третий долго не думая самое большое число, которое знал, использовал. Долго ли, коротко ли, придумал отдел маркетинга новую забаву. Теперь пока лицензия не кончилась, ее стало можно переоформить: частей добавить или изъять. Ну а раз изъять, то и нули в строках стали возможны. Пришлось программистам еще раз напрячься, да ноль выдумать. Ну а когда стали правила лицензирования в отдельный продукт собирать, запестрел он правилами вроде «если продукт один ноль это бесконечность, а минус единица это ноль, а ежели другой, то все наоборот». И набралась таких правил толстая книга. Мораль, прежде чем изобретать велосипед, посмотри уже изобретенные, да посоветуйся с коллегами.

вторник, февраля 19, 2008

У каждого бага есть имя, фамилия и отчество

Был такой замечательный человек, Лазарь Моисеевич Каганович. Сейчас как-то принято ругать всю сталинскую эпоху скопом, поэтому Лазаря Моисеевича чаще всего вспоминают как в связи со "сталинскими" репрессиями, коллективизацией сельского хозяйства на Украине и сносом старых зданий в Москве. Умер Каганович в 1991 году, в возрасте 97 лет, совсем немного недотянув до развала СССР. Так вот, в бытность свою наркомом путей сообщения, Каганович произнес замечательную фразу: "У каждой аварии есть имя, фамилия и отчество". Слово не разошлось с делом, начались служебные расследования и многие нерадивые, как тогда было заведено, были обвинены во вредительстве и отстранены. Результат: в начале Войны при эвакуации, несмотря на страшную перегрузку всей транспортной системы, не произошло ни одной серьезной аварии. На мой взгляд, это самый выдающийся результат, который вообще возможен. К сожалению эту замечательную фразу в последнее время забыли и уж тем более не принимают как руководство к действию. Сейчас принято считать, что бывают ситуации, в которых никто не виноват. Они как-бы происходят сами собой, безо всякого человеческого вмешательства либо считаются просчетом всего коллектива, всего общества. Рванула чернобыльская АЭС, виновата "некомпетентность". Застрелился новобранец, виноваты "деды". Выпустили релиз с блокером, виновата команда. И как-то так получается, что никто конкретно и не виноват. А раз никто не виноват, так действительно накосячивший никогда не осознает совей ошибки и обречен повторять ее снова и снова.

пятница, февраля 01, 2008

Primary keys in life

Те, кто изучал реляционные базы данных в теории обычно убеждены в том, что некоторые виды объектов по самой своей природе обладают некоторым привычным ключом. Обычно приводят такие примеры: человек — серия и номер паспорта или номер социального страхования или ИНН; книга — ISBN и так далее. На первый взгляд кажется, что эти поля подходят для первичного ключа. При некоторых допущениях так и есть. Однако так ли это на самом деле? Рассмотрим того же человека:
  • Серия и паспорт человека меняется как минимум трижды в течение жизни;
  • У книги может быть как несколько номеров ISBN, так и не быть ни одного;
  • Бывают люди без ИНН и номера социального страхования
Однако на этом проблему не заканчиваются. Что будет если нам придется импортировать данные из сторонних систем? Можем ли мы использовать первичные ключи для этого? Предположим, мы импортируем список людей содержащий имена, даты рождения, данные паспорта и СНИЛС. Совпадение каких полей может служить однозначной идентификации? Правильный ответ: только совпадение всех полей позволяет однозначно связать две записи. Рассмотрим пример подробнее. У нас есть несколько кластеров данных в каждой записи: 1. Тройка фамилия-имя-отчество 2. Дата рождения 3. Данные паспорта (серия-номер-дата выдачи-выдавший орган) 4. Номер социального страхования СНИЛС Я намеренно упустил из виду существование других документов удостоверяющих личность, лиц без гражданства, иностранных граждан и т.п. Будет достаточно одного простейшего случая. Из предметной области мы знаем:
  • У человека может измениться фамилия, что происходит довольно часто, имя или отчество, что происходит занчительно реже;
  • В особых случаях у человека может измениться дата рождения;
  • Смена фамилии, имени или даты рождения влечет смену документа удостоверяющего личность
  • Человек может получить новый паспорт с совершенно другими данными, никак не связанными с предыдущим;
  • Человек может получить другой номер ИНН, что происходит довольно редко, но происходит;
  • Человек может получить другой СНИЛС, что происходит довольно регулярно;
  • При внесении данных в базу возможны ошибки оператора;
  • На больших объемах данные проявляется "эффект больших чисел": разные люди с частично совпадающими данными.
Этого уже достаточно чтобы понять — никакого первичного ключа здесь нет. Более того, как только нам потребуется вносить данные в систему мы непременно столкнемся с проблемой идентификации, которую невозможно разрешить автоматически. Единственный выход — система синхронизации на основе правил и ручного анализ спорных случаев оператором. Любые попытки изобрести первичный ключ из любой комбинации полей приведут к отсечению части вполне законных use cases предметной области, как это произошло здесь