Comments 32
Ещё одна беда многих проектов — дублирование кода. Нужно изначально заложить в архитектуру приложения как можно больше защиты против этого.
Третья беда — отсутствие продуманной процедуры обновления от версии к версии с возможностью отката и отсутствие скриптов для для разворачивания базы данных с нуля.
Частая ошибка — неправильный выбор типа данных для ключа в базе данных. Из-за чего возникают ошибки когда таблица перерастает определённый размер (к примеру 32000 записей для int), либо возникают проблемы с масштабированием. К этой же проблеме отнесём и автогенерацию первичных ключей, которая опять же либо выглядит как костыль, либо страдает от проблем с масштабированием. Логичным выходом является использование GUID, но он медленный и очень неудобен в отладке и написании SQL запросов для поддержки и анализа проблем.
Ошибки выбора типов данных встречаются не только для первичных ключей. Это очень большая проблема для строк (Юникод или однобайтовые строки), для дробных значений (к примеру знаю одну программу для ломбардов, которая считает деньги в float типе, а учитывая то, что проценты считаются по дням и в результате генерируется много записей с небольшими суммами, то ошибка быстро накапливается и приводит к расхождению на несколько рублей в сутки для всего ломбарда). Другая проблема — недостаточная точность. Часто считается, что точности 2 знака после запятой для хранения денег достаточно, но фактически есть операции, где важны значения до 5ого знака. К примеру та же пеня.
Ещё одна ошибка архитектуры — «сделаем прототип, а потом переделаем». Это не работает. Всегда пишите так, как будто этот код — критически важен для проекта. Видел случаи когда пилили прототип, а потом заказчик сказал идти в продакшн. И его можно понять — перед ним рабочая система, но вы говорите ему, что нужно всё переделать и ещё и заплатить за это…
Частая проблема, которую можно видеть особенно в старых проектах, это любовь к универсальным решениям. Вплоть до форм, конфигурируемых с помощью xml и генерации SQL запросов на лету. Это работает для простейших задач, но порождает проблемы удобства использования для клиентов, снижает безопасность системы и порождает различные костыли.
Согласна про излишнюю универсальность. Тут очень важно уметь правильно остановится. Иногда решение усложняется в разы, потому что пытаются заложить универсальность, под случаи, которые происходят в 0,03% случаев и в итоге вся система работает медленнее и не если бы только медленнее, но и сложнее.
Всегда пишите так, как будто этот код — критически важен для проекта.Казалось бы хороший совет, но он не работает.
Высокий приоритет везде = отсутствие приоритета.
Видел случаи когда пилили прототип, а потом заказчик сказал идти в продакшн.
а что заказчику обещали? production-ready систему или прототип на-посмотреть?
возможно ожидания у заказчика были выставлены неудачно
Всегда пишите так, как будто этот код — критически важен для проекта.
мне кажется, такой подход плохо сработает, если вы используете новые для себя технологии (библиотеки, инструменты — всё, что относится к разработке). Как бы не был важен этот функционал, будет трудно принимать решения «как лучше его реализовать», потому что в начале не хватает опыта. ИМХО, новая предметная область тоже может влиять — откуда бы мне, разработчику, знать, что вне РФ нет такой сущности как ИНН, так что я честно делаю ИНН ключом:)
я клоню к тому, что вы много времени потратите с таким подходом.
есть же прототипы, которые делаются только с целью proof-of-concept: разработали, научились, собрали ошибки, в следующем прототипе или в новой системе сделаете правильно в заданном контексте. на самом деле этот подход тоже небыстрый, но более эффективный с точки зрения вашего обучения и с большей обратной связью от пользователей/заказчика.
> Практически во всех канонических учебниках по базам данных описывается, насколько неэффективны искусственные ключи и как прекрасны естественные.
Ровно наоборот, в любом учебнике написано, что эффективны как раз искусственные ключи, а естественные — ужасны.
Я раньше поражался тому, как уродливы изнутри «взлетевшие» проекты. Сейчас я знаю: красивые проекты не взлетают, потому что они не успевают взлететь. Пока инженеры в белых халатах прикручивают красивый двигатель к идеальному крылу, бригада взлохмаченных придурков во главе с безумным авантюристом пролетает над ними на конструкции из микроавтобуса, забора и двух промышленных фенов, навстречу второму туру инвестиций. Авантюрист любезно раздаёт восторженным пассажирам талоны и бумажные пакетики.
С другой стороны в enterprise на мой взгляд уж очень тяжко все и медленно двигается. Народ может обсуждать и переделывать по 5 раз решение, хотя в это время в проде может быть абсолютная лажа, и любой из новых вариантов был бы лучше, но нет, надо же найти лучшее. В результате вместо 2х дней на изменение тратится от 2х до 3х недель. И это я говорю о простом изменении, если что-то помасшабнее, то вообще все грустно.
В общем во всем нужна мера.
Практически во всех канонических учебниках по базам данных описывается, насколько неэффективны искусственные ключи и как прекрасны естественные. Но мир, обычно, еще не дошел до такого уровня глобализации, чтобы всем можно было бы использовать естественный ключ
У меня есть мысль, что естественных ключей в полном смысле слова не бывает. Бывают некомпьютерные искусственные ключи. Номер паспорта. Это же число, инкрементный идентификатор. И подходит он только для учета самих паспортов. ИНН. Это тоже придуманное число из базы данных налогоплательщиков. Принцип учета не меняется от того, в компьютере у нас база или на бумаге.
Можно использовать один ключ в нескольких базах данных, но от этого он не станет менее искусственным. Это всё потому что у объекта-сущности может измениться любое свойство, но мы все равно будем считать его тем же объектом.
Добавлю свои пять копеек для стартапов:
- автоматизированный деплоймент и автоматизированный откат деплоймента. Экономит просто гигантское количество времени и нервов, особенно если приложениие нужно обновлять каждый день или оно не обновлялось несколько месяцев. Относится как к деплойменту приложения, так и к базам данных
- логгирование, алертинг и аналитика. Нужно думать сразу, какая информация нужна для аналитики, какие ошибки требуют немедленной реакции админа, а какие нужно регулярно просмотривать в поисках багов или проблем с приложением.
- прототипы являются очень полезным инструментом при соблюдении простых правил:
— прототип должен содержать ровно столько функционала, чтобы впечатлить инвесторов или оценить спрос на идею. Идеальный прототип — лендинг с формой сбора email-ов.
— прототип не расширяется и не переписывается — он выкидывается. Поэтому его желательно делать с использованием средств быстрой разработки (CMS, фреймворки...)
важно хранить логи действий пользователя в течение 1-2х недель на случай, если он обратится в техническую поддержку. Затем эту информацию можно удалить.
Очень зависит от специфики системы. Действительно, важно понимать ЧТО вы логгируете, не стремясь просто набить терабайт побольше и потом хвалиться ими. Но вот у нас бывают случаи разбора проблем и 3х месячной давности, и тогда только детальные логи помогают понять в чем дело. Иные процессы требуют вообще журналирования более чем на год, пусть и довольно поверхностного.
В начале идет большое количество изменений (новый функционал, исправленный старый, эксперименты). Если вместо этого пилить ненужный функционал (закладываться на будущее), то не только стоимость ненужного сейчас функционала и задержка нужного из-за занятости программистов тянут проект к банкротству, но и увеличение стоимости любого функционала из-за ненужного.
Например, локализация, когда достаточно одного языка. Или обрезание логов для двух недель, а потребовалось проанализировать поведение пользователей за больший промежуток времени.
Конечно, именно сделать то, что сейчас актуально наиболее важно для проекта. А то так если пилить задачи на будущее, можно прошляпить настоящее.
Дополню про локализацию — нет сразу поддержку всех языков вводить не нужно, это излишний очень большой кусок работы. А вот тип строк юникод — можно выбрать, это объем работы на начальном этапе никак не изменит. Да, это увеличит объем на диске, но в начале данные не занимают много места. Если точно известно что это не стратап или потенциально (пусть и в самых смелых фантазиях) международное приложение, а например, приложение для госсектора — тут можно и юникод не использовать, так как язык ну уже совсем точно будет один.
Про логи — не надо сразу ставить 2 недели, но какой-то срок поставить надо. А главное настроить процедуру их удаления. Ок, если вы не знаете сколько они могут понадобится — поставьте удалять через 3 месяца, через 1 год, через 3. И настройте сразу процедуру. В процессе работы вы поймете как часто и за какой период эта информация нужна. Если не чистить мусор сразу, то через 3 года об удалении обычно никто не помнит, а через 5 лет у вас будет помойка, которую будет тяжело и долго разгребать. В плохом варианте — помоек будет много.
Но для хранение юникод данных используется в 2 раза больше места, чем для хранение в локальной кодировке. Я не делала проекты, которые бы могли быть только локальными — мне кажется это может быть госсектор или что то еще только локальное, может быть областное, и оно не предполагает хранения отображаемых данных. Например. названия улиц — потому что могут решить их продублировать на китайском — и будет проблема.
В общем это я к чему, вроде и 2017й год и дисковое пространство дешевле. Но
Например у нас 100 полей со строковыми данными, для простоты размером до 200 символов каждое. Для MS SQL берем Varchar (1 байт) и Nvarchar (2 байта на символ)
Varchar 2000 байт на строку
NVarchar 4000 байт на строку
Вроде мало — какая разница-то?
А теперь представим что у нас добавляется этих строк много.
То есть когда у вас 4 Тб данных или 8 Тб это все таки имеет значение. Опять же тут надо все таки очень сильно думать — будет у вас больше одного языка и латиницы или нет.
И да в 99% надо использовать юникод.
Например, MS SQL:
All non-East Asian languages and the Thai language store non-Unicode characters in single bytes.
Очень скептически отношусь к идее удаления логов и прочей истории. Другое дело, что нужно регулярно перемещать старые записи из оперативных баз (или таблиц) в архивы.
По поводу времени в UTC — если уж приняли такое решение "на будущее", то всегда понимайте где у вас по бизнес-логике дата, а где датавремя и никогда не надейтесь на автоматическое приведение даты и даты+времени при сравнении, вычислении длительности и т. п. Требуйте от бизнеса явных правил приведения дат ко времени и назад с учетом часового пояса пользователя и офиса, его обслуживающего, если начинаете работать в нескольких часовых поясах, чтобы не получалось что человек оплатил подписку только что, а станет она ему доступна только с полночи в Гринвиче. Или наоборот, оплатил за 30 дней, а получит, например, 29 дней и 20 часов.
Что нужно учесть при проектировании системы, чтобы не было мучительно больно?