пятница, 23 августа 2013 г.

Десять заповедей разработчика

Здесь перечислены общие рекомендации по избежанию наиболее популярных граблей, по которым так любят ходить разработчики баз данных. Хочу лишь отметить один факт — нарушение перечисленных требований приводит к резкому увеличению времени разработки, росту количества ошибок, неоправданным сложностям в сопровождении и в конечном итоге, к провалу всего проекта.

1. Стандартные имена.

Не парьте мне мозги.
Одной сущности должно соответствовать всегда одно имя — это правило, в котором не может быть исключений.
Написание имен должно быть максимально стандартизировано. Регистр букв также важен, даже если средство разработки его не учитывает (зато регистр хорошо учитывается людьми, хотя многие об этом и не подозревают).
Лучше всего использовать слова английского языка, без сокращений. Большинство средства разработки не поддерживает идентификаторы, состоящие из букв других языков — и правильно делает.
Немногочисленные стандартные аббревиатуры и сокращения должны быть описаны в специальном словаре.
Пример: Если типу объекта соответствует имя ObjectType, то в обращении не должно быть имен вроде ObjType, Objecttype или OBJ_TYPE.
Использование стандартных имен позволяет сэкономить кучу времени, необходимого на поиск нужного имени, а также избежать возможных недоразумений.

2. Отсутствие загадочных значений.

Что это за хрень?
Часто неопытные разработчики используют какие-нибудь поля для хранения значений вроде 0, 1, 2 и т.п. Эти поля не ссылаются на другую таблицу, зато используются где-нибудь в выражениях:
if State = 2 then ... else ...
Все ведь понятно, не правда ли?
Немногим лучше выглядит и такой вариант: «U», «T», «S».
Кто угадает, что здесь означает «U»?
Правильным решением будет создание отдельной таблицы (Id, Code, Name, Note), содержащей набор возможных значений для этого поля.
В поле же надо хранить идентификатор (Id) значения из этой таблицы, при необходимости используя код и наименование значения.
Отсутствие загадочных значений освобождает память разработчика от ненужного мусора и уменьшает вероятность возникновения ошибок и непонимания.

3. Поменьше ограничений.

Не создавай граблей на пустом месте.
Таблицы и поля стоит создавать с достаточно большим запасом прочности, чтобы не было потом мучительно больно.
Если в задании написано, что какой-нибудь код содержит 17 символов, совсем необязательно понимать это буквально и объявлять поле как char(17). Ведь завтра требования могут измениться, и уже понадобится 22 символа или больше. Гораздо лучше выглядит varchar(120), а места оно занимает не больше.
Когда создается таблица с предполагаемым числом записей не больше нескольких тысяч, вполне разумным кажется использование smallint (2-хбайтовое целое) поля в качестве первичного ключа.
А что же будет, если количество записей все-таки превысит 32 тысячи?
Придется менять первичный ключ в этой таблице и все внешние ключи, ссылающиеся на нее.
Этого можно было бы избежать, сразу сделав первичный ключ размеров в 4 байта.
Кажется, что всегда можно легко произвести любые необходимые изменения в структуре базы данных, однако это далеко не так.
База может находиться в круглосуточной работе, в репликации, может быть уже заполненной многомиллионными данными и т.п.
И экономия на байтах здесь не уместна.
Отсутствие мелочных ограничений позволяет разработчику не думать о них и создавать более устойчивые и гибкие структуры.

4. Одинаковые ключи.

Надо быть проще.
В качестве первичных ключей для всех таблиц сущностей лучше всего использовать суррогатные ключи достаточно большого размера (4—16 байт). При этом, все такие ключи должны быть одного типа.
Благодаря этому, многие проблемы уходят и никогда не возвращаются (разве что в кошмарах).
Так как ключ суррогатный, то отпадает необходимость поиска и использования естественного ключа (часто составного).
Из-за большого размера ключа не возникает ситуация его переполнения.
Наличие у всех сущностей идентификатора одного типа позволяет организовать стандартную работу с этими сущностями.
Единственной проблемой может стать наличие двусторонней репликации между базами данных. Но это легко решается использованием глобального идентификатора в качестве ключа либо разделением диапазонов выделенных для ключей в разных БД.
Одинаковые ключи дают возможность работать с разными сущностями одинаковыми методами, часто используя один и тот же код.

5. Независимость данных.

Надо быть гибче.
Нормализация и еще раз нормализация — вот залог жизнеспособности любой базы данных.
Как учат классики, все отдельные сущности должны быть выделены в отдельные таблицы. При этом связь с ними осуществляется по первичному ключу.
Одинаковые сущности, наоборот, сводятся в одну таблицу.
Зависимости между разными сущностями должны быть минимальны.
Из-за несовершенства SQL (и особенно его реализаций), полностью нормализованная БД может оказаться плохо приспособленной к получению сложных запросов. Поэтому, в исключительных случаях, допускается некоторое дублирование информации для ускорения выборок.
Независимость отдельных сущностей может упростить проект и добавить ему гибкости.

6. Неповторяющийся код.

Долой Copy&Paste!
Казалось бы, тривиальное правило, гласящее, что повторяющийся код надо выносить в отдельные функции, знает даже самый неграмотный программист. Однако в случае с SQL все не так просто.
Дело в том, что SQL изначально не предназначен для создания функций, процедур, триггеров и, соответственно, не предполагает для них никакого стандарта. Поэтому у всех SQL-серверов есть свои собственные расширения для написания бизнес-логики. Эти расширения не совместимы друг с другом, а их уровень варьируется от достаточно высокого до совершенно убогого (лишь бы было).
Иногда даже опытные разработчики, впервые столкнувшись с неадекватными SQL-расширениями, впадают в какой-то ступор и забывают все свои навыки, пытаясь использовать навязанные им приемы работы. При этом, часто пишут кучу однообразных триггеров и процедур, выполняющих одинаковые действия для разных таблиц.
Тем не менее, правило повторного использования кода никто еще не отменял, и обычно его везде можно применять, хотя и не всегда очевидным образом (например, передавая имя таблицы в качестве параметра).
Повторное использование улучшает качество кода и рекомендуется к применению везде, даже если средство разработки этого не поощряет.

7. Обработка ошибок.

Invalid programmer is detected. Abort, Remove, Must Die?
Такое же стандартное правило, как и предыдущее — если хочешь, чтобы программа делала то, что нужно, необходимо проверять результат выполнения каждой функции (и каждого SQL-оператора).
В клиентском приложении должны везде проверяться коды ошибок вызываемых функций. При возникновении ошибки, ее стоит записать в лог-файл, а пользователю должно быть показано уже обработанное внятное сообщение на человеческом языке.
То есть вместо «Network link failur» надо вывести «У вас сеть отвалилась, дальнейшая работа невозможна».
Если в приложении все более-менее понятно, то при написании процедур на SQL-сервере разработчики, видимо, надеются, что сервер сам прекратит выполнение процедуры при возникновении ошибки. Как бы не так.
После каждого SQL-оператора обязательно должен проверяться и обрабатываться код последней ошибки.
Правильность работы программы не может быть обеспечена без тотальной обработки ошибок.

8. Короткие транзакции.

Скажи блокировкам — НЕТ!
Большинство SQL-серверов используют технологию блокировок при любой модификации данных. То есть, данные, измененные в транзакции одним из пользователей, недоступны для других пользователей до завершения этой транзакции.
Совсем избежать блокировок нельзя, однако можно уменьшить продолжительность транзакций.
Для этого перед выполнением транзакции для нее должны быть уже подготовлены все необходимые данные. Внутри транзакции не должно быть никаких обращений к внешним устройствам (файлам, сети и т.п.) — только к базе данных.
Ситуация, когда внутри транзакции происходит диалог с пользователем, тем более недопустима.
Короткие транзакции дают возможность большему числу пользователей одновременно работать с базой данных, не конфликтуя друг с другом.

9. Наличие метаданных.

Кому нужна база без головы?
Метаданные описывают структуру базы данных и взаимосвязи ее объектов.
При некоторых манипуляциях с базой данных может потребоваться информация о том, какие сущности хранятся в этой базе, в каких таблицах и полях, как они связаны друг с другом.
Частично эту информацию можно получить из системного каталога SQL-сервера.
Но системный каталог предназначен скорее не для разработчика, а для внутреннего использования самим сервером, поэтому найти там что-либо весьма проблематично. При этом, его структура может меняться даже в разных версиях одного сервера, не говоря уже об отсутствии какой-либо совместимости с другими SQL-серверами.
Даже довольно неполные метаданные имеют широкую область применения. Но чаще всего они используются для упрощения собственной работы программистов, вплоть до автоматической генерации приложения и объектов БД.
Наличие метаданных дает полную информацию о базе данных, облегчая разработчикам решение многих задач.

10. Хранение истории.

Кто владеет прошлым — тот владеет будущим.
Большинство объектов, хранящихся в базе данных, могут меняться с течением времени.
К сожалению, почти все современные СУБД не хранят историю изменений и не позволяют получить состояние объектов на определенную дату. Об этом должен позаботиться разработчик базы данных.
Только база данных, которая хранит всю историю изменений всех своих объектов, может претендовать на полноту и завершенность. Иначе простейший запрос, вроде «Дайте список объектов в том виде, в котором они были на 01.04.1997 г.», так и останется без ответа.

Любая база данных, хранящая изменяемые объекты, должна содержать полную историю всех их изменений. 

среда, 8 мая 2013 г.

Русский рывок

По своей профессии я весьма далек от политики и экономики и являюсь чистым технарем. Более 50 лет я занимаюсь созданием принципиально новых средств вычислительной техники или, как сейчас принято говорить, развитием компьютерных технологий. Недавно меня попросили написать статью об истории создания и развития того направления вычислительной техники, которым я занимаюсь всю жизнь. В ходе работы над этой статьей, систематизируя свои воспоминания и изучая ряд исторических материалов, я неожиданно для себя обнаружил, что в советской истории существует период феноменального развития науки, техники и экономики в целом.

Начиная с середины сороковых годов создается целый ряд инновационных отраслей, таких, как атомная, ракетная, вычислительная техника, электроника, где мы, как минимум, не уступали США, а зачастую и опережали. Все остальные страны были далеко позади.

Если атомная бомбы появилась в СССР в 1949 году, через 4 года после США, то первая в мире водородная бомба РДС-6 была уже советской. Первая в мире атомная электростанция была введена в эксплуатацию в СССР летом 1954 года, на год раньше, чем в Англии, и на 2 года раньше, чем в США. Только в СССР были созданы атомные ледоколы («Ленин» — 1959 г.). Единственный в мире самолет с атомным двигателем М-50А, поднявшийся в небо в 1960 году, был создан в СССР в ОКБ В.М. Мясищева. Лишь атомные подводные лодки появились в США в 1955 году, на 3 года раньше, чем в СССР.

Достижения СССР в ракетной технике и космонавтике, начиная с первого спутника, запущенного в октябре 1957 года, общеизвестны.

Уже в 1948 году, когда в США и Англии только разрозненные коллективы занимались разработкой единичных образцов компьютеров и в мире не было еще ни одного действующего изделия, в СССР по инициативе Сталина были созданы Институт точной механики и вычислительной техники (ИТМ и ВТ) АН СССР и Специальное конструкторское бюро N245(«СКБ-245»), как было написано в постановлении Правительства: «...для разработки и внедрения в производство средств вычислительной техники для систем управления оборонными объектами». В 1951 году создается первая советская цифровая вычислительная машина МЭСМ — сразу как промышленный образец. Следует заметить, что первые промышленные компьютеры в США (UNIVAC 1) и в Англии (Ferranti Mark 1) также появились в том же 1951 году. В 1953 году начинается серийное производство машин БЭСМ, «Стрела» и М-2 (для военных применений), которые находились на уровне лучших американских компьютеров того времени и существенно превосходили компьютеры других стран.

Следует отметить, что в 50-х годах и советская электроника была на высоком уровне. Промышленное производство полупроводниковых транзисторов в США началось в марте 1958 года фирмой Fairchild Corp. при цене $150 за штуку. А информация о характеристиках отечественных «кристаллических триодов» была помещена в шестом номере популярного журнала «Радио» за 1955 год, а в 1956 году, на два года раньше, чем в США, началось промышленное производство. Осенью 1957 года я, будучи студентом третьего курса ЛЭТИ, занимался на кафедре автоматики и телемеханики практической разработкой цифровых устройств на транзисторах П-16. К этому времени транзисторы в СССР были не только общедоступны, но и дешевы (в пересчете на американские деньги менее доллара за штуку).

Еще более поразительны успехи экономики в целом несмотря на полное отсутствие внешних кредитов и минимальные объемы нефтяных денег (газовых денег тогда не было). Уже в 1947 году промышленный потенциал СССР был полностью восстановлен, а в 1950 году он вырос более чем в 2 раза по отношению к довоенному 1940 году. Ни одна из стран, пострадавших в войне, к этому времени не вышла даже на довоенный уровень несмотря на мощные финансовые вливания со стороны США. Например, Япония достигла довоенного уровня лишь в 1955 году, хотя, если не считать ядерных бомбардировок, серьезных разрушений там не было. Лимитированное распределение продуктов по карточкам было отменено в СССР в 1947 году, а в Англии, несмотря на помощь США, лишь в 1954 году. В сентябрьском номере журнала «Нейшнл бизнес» ("National Business") за 1953 г. в статье Герберта Гарриса «Русские догоняют нас» отмечалось,что СССР по темпам роста экономической мощи опережает любую страну и что в настоящее время темпы роста в СССР в 2-3 раза выше, чем в США. Годом ранее кандидат в президенты США Стивенсон оценивал положение таким образом, что если темпы роста производства в сталинской России сохранятся, то к 1970 г. объем русского производства в 3-4 раза превысит американский. Заметим, что темпы роста советской экономики в послевоенный период были намного выше, чем в довоенный.

Но начиная с середины 50-х годов, ситуация резко меняется. Снижаются темпы роста, а в ряде областей возникают настоящие провалы. Вот как сказал об этом в 1991 году японский миллиардер Хероси Теравама, обращаясь к советским экономистам: «Вы не говорите об основном, о вашей первенствующей роли в мире. В 1939 году вы, русские, были умными, а мы, японцы, дураками. В 1949 году вы стали еще умнее, а мы были пока дураками. А в 1955 году мы поумнели, а вы превратились в пятилетних детей. Вся наша экономическая система практически полностью скопирована с вашей, с той лишь разницей, что у нас капитализм, частные производители, и мы более 15% роста никогда не достигали, а вы же при общественной собственности на средства производства достигали 30% и более. Во всех наших фирмах висят ваши лозунги сталинской поры». Из приведенного высказывания можно сделать ряд выводов. В 1939 году в СССР был разработан новый метод повышения эффективности экономики (МПЭ). МПЭ использовался в большинстве отраслей народного хозяйства. МПЭ являлся эффективным как для социалистического, так и для капиталистического уклада экономики, но для социалистического уклада эффективность МПЭ была выше более, чем в 2 раза. В 1955 году Япония заимствовала МПЭ, что и обеспечило ее бурный экономический рост за счет, прежде всего, инновационных технологий («японское чудо»), а СССР в том же году отказался от МПЭ, что обусловило последующую деградацию экономики. Итак, в СССР с 1939 по 1955 год применялся волшебный метод, обеспечивший беспрецедентный взлет экономики. Об этом методе в настоящее время не известно абсолютно ничего, хотя в те времена в СССР он применялся повсеместно.

Моя трудовая деятельность началась в 1958 году, когда МПЭ уже был ликвидирован, но я хорошо помню рассказы сослуживцев, работавших в те времена, когда МПЭ действовал. МПЭ являлся совокупностью хорошо продуманных материальных и моральных стимулов для активизации творческой активности масс, направленной на снижение себестоимости и повышение качества (улучшения характеристик) разрабатываемой или уже производимой продукции. Система стимулов варьировалась в зависимости от отрасли и типа предприятия. Однако в любом варианте эти стимулы не распространялись на начальников любого ранга. Возможно, для руководящих работников была отдельная система стимулов, но мне об этом неизвестно.

Материальные стимулы в организациях, занимавшихся разработками новой техники, заключались в коллективных и индивидуальных премиях, выплачиваемых сразу после приемки разрабатываемого изделия государственной комиссией (буквально в тот же день), если в акте комиссии отмечалось улучшение характеристик изделия по отношению к техническому заданию. Для каждой характеристики, включая время разработки изделия и стоимость разработки, имелась определенная премиальная шкала, известная разработчикам еще до начала проектирования. Например, за каждый сэкономленный килограмм веса изделия в ОКБ-590, где мне пришлось работать, выплачивалось 500 рублей (половина месячного оклада инженера). Эту премию получали все члены коллектива, участвующего в проекте, в одинаковом размере независимо от должности. Существовали и индивидуальные премии, необходимым условием выплаты которых являлось наличие рационализаторских предложений или заявок на изобретение, благодаря которым и стало возможным улучшение характеристик изделия. За каждую новацию авторам выплачивалась дополнительная сумма, кратная вознаграждению, полученному каждым членом коллектива, что не отменяло и обычных вознаграждений за экономический эффект, полученный от внедрения изобретения или рационализаторского предложения. Руководитель проекта, как правило, не занимавший административной должности, также получал дополнительную премию. Моральные стимулы заключались в том, что лица, обеспечившие коллективу получение таких премий, ускоренно продвигались по службе и в основном из их числа назначались руководители проектов. Одновременно применялись и обычные квартальные и годовые премии. Необходимо отметить и хороший моральный климат в научно-технических коллективах. К людям, способным к творческой работе, коллеги относились бережно, стараясь освободить их от рутинной работы без всяких указаний начальства, так как успехи одного распространялись на всех. Иными словами, человек человеку был другом. Здесь разработчики метода учли печальный опыт стахановского движения, когда успех одного больно бил по карману и статусу других и в коллективе начинался разлад.

При относительно небольших затратах эффективность МПЭ была исключительно высока во всех отраслях народного хозяйства. Даже в армии во время войны существовала жесткая шкала денежных выплат и наград за личное уничтожение техники или живой силы противника, а также нанесение иного урона (например, взятие в плен офицеров противника, обладающих важной информацией). В оборонной промышленности в годы войны одновременно с напряженной производственной деятельностью велась непрерывная работа по совершенствованию технологических процессов. Так, за 4 военных года себестоимость производства большинства образцов вооружений (самолеты, танки и т.д.) была снижена в 2-3 раза. Даже винтовка Мосина, разработанная еще в XIX веке, подешевела в 1,6 раза. МПЭ позволял в максимальной степени использовать творческую активность рядовых исполнителей и выявлять яркие таланты. МПЭ применялся и в сельском хозяйстве на уровне совхозов и МТС (машинно-тракторных станций). Об этом говорит известный факт, что М.С. Горбачев получил в семнадцатилетнем возрасте орден за уборку урожая.

Главной особенностью МПЭ являлось то, что при его использовании не только повышалась творческая активность большого числа людей и выявлялись таланты, но также изменялась психология всех членов коллектива, а также взаимоотношения в коллективе. Любой член коллектива осознавал свою значимость для общего процесса и с готовностью выполнял любую часть работы, даже в том случае, если эта работа не соответствовала его статусу. Взаимная доброжелательность, стремление оказать помощь друг другу были совершенно типичными чертами. По сути, каждый член коллектива считал себя личностью, а не винтиком сложного механизма. Изменялись и взаимоотношения начальников с подчиненными. Вместо приказов и указаний начальник стремился разъяснить каждому подчиненному, какую роль в общем деле играет та работа, которая ему поручается. По мере становления коллективов и формирования новой психологии сами материальные стимулы отходили на задний план и уже не являлись главной движущей силой. Полагаю, что разработчики МПЭ рассчитывали именно на такой эффект.

Все вышеизложенное я знаю не по рассказам очевидцев, а по личным впечатлениям. Хотя я пришел в ОКБ-590 в 1958 году, через 3 года после отмены МПЭ, но психология — вещь инерционная, и она сохранялась длительное время даже при отсутствии внешних стимулов. Первые три года я работал в лаборатории цифровых систем, где начал свою деятельность с нижней ступеньки — настройщика узлов бортовой цифровой вычислительной машины. Эта специальность считалась рабочей, и настройщики (два человека) работали на сдельной оплате, получая значительно больше инженеров, в то время как я работал на фиксированном окладе техника. Мое появление неизбежно приводило к финансовым потерям двух других настройщиков, поскольку число узлов было ограничено лишь опытными образцами, после изготовления которых настройщики занимались лишь ремонтом при существенно меньшей оплате. Тем не менее меня приняли очень тепло и в течение месяца знакомили с тонкостями процесса настройки. Отношение ко мне не изменилось и через пару месяцев, когда я стал настраивать в несколько раз больше узлов, чем мои коллеги, и впоследствии, когда закончилась массовая настройка узлов. То есть для обычных рабочих парней общее дело коллектива лаборатории (создание опытных образцов БЦВМ) было важнее их личных финансовых интересов.

Работа в качестве настройщика продолжалась недолго. Уже через несколько месяцев меня стали привлекать к инженерной работе, причем не только в качестве помощника. Характерной чертой лаборатории было полное отсутствие субординации. Все друг к другу обращались по именам, в том числе и к начальнику лаборатории. Этому способствовала и небольшая разница в возрасте сотрудников лаборатории, самому старшему из которых было менее 35 лет. Начальник лаборатории или руководитель группы не просто выдавали задание, а стремились донести до каждого члена коллектива цели этого задания и его роль для решения общей задачи. Рабочий день продолжался с 9 утра до 10-11 вечера, причем на чисто добровольной основе и без какой-либо дополнительной оплаты. Зато никто не контролировал время прихода и ухода сотрудников, что для режимных предприятий было совершенно нетипично.

В мае 1961 года меня перевели в лабораторию аналоговых систем и назначили руководителем важнейшего для организации (да и для страны) проекта. Эта лаборатория функционировала с момента основания организации в 1945 году. Поэтому сотрудники здесь были старше по возрасту. Но атмосфера была такая же. Лишь к начальнику лаборатории все обращались по имени и отчеству, но не из-за его должности, а из-за возраста и опыта. Он провел всю войну на фронте, и прямо из армии его откомандировали в только что образованное ОКБ. Из всего коллектива только я знал, что и как надо делать, поскольку являлся единственным специалистом в области цифровой техники. И ведущие инженеры с 10-15-летним стажем без какого либо внутреннего сопротивления выполняли роль подсобных рабочих, поскольку понимали, что это необходимо для дела. Снова напомню, что к этому времени никаких стимулов уже не было. И третье подразделение нашего конструкторского бюро, с которым мне приходилось тесно взаимодействовать, работало в таком же стиле.

Еще одна деталь. За все время работы в ОКБ-590 (в январе 1963 года оно было ликвидировано, а все сотрудники вместе с тематикой переведены в ОКБ-680, впоследствии НПО "Электроавтоматика") я ни разу не слышал слово "партия". Комната месткома была, а парткома не было. Только в 1963 году в новой организации я узнал, что в лаборатории было довольно много членов партии, и меня сразу же попытались сагитировать на вступление, но я уклонился. Иначе мне не удалось бы в 1964 году покинуть эту организацию. Кстати, начальник ОКБ-590 В.И. Ланердин был беспартийным. Говорили, что на пост начальника ОКБ Ланердина назначил лично Сталин, а до этого во время войны он работал в США, отвечая за поставки в СССР авиационной техники по ленд-лизу. К моменту назначения ему было не более 35 лет.

В.А. Торгашев