В статье описаны проблемы при проектировании баз данных и немного всего приложения, которые потом с ростом проекта все сложнее и сложнее решить. Моменты, которые важно учесть на этапе дизайна, и не задумываться о них в последствии. Ну или задумываться за чашкой чая и фразой «А помнишь, как мы решили это сделать сразу? Сколько времени мы этим себе сэкономили!», а не с ощущением зубной боли и болезненном вздрагивании при каждом воспоминании. По мере роста системы и числа пользователей, дизайн базы все сложнее и сложнее изменить, и масштаб изменений становится все более глобальным и трудоемким.

Сейчас многие успешные проекты выросли из небольших стартапов, которые потом получили коммерческий успех и стали большими международными компаниями. Такая возможность роста появилась в последние 20 лет, в основном благодаря интернету и эффекту «стирания границ». Появились глобальные интернет-приложения и мобильные приложения, которые могут быть использованы в любой стране. Ранее, чаще всего, если приложение должно было быть международным проектом, оно и проектировалось уже сразу с учетом такого требования. Конечно, можно воспользоваться эволюционным подходом, и по мере роста проекта добавлять в него необходимые функции и масшатибирование. Но для облегчения внедрения дальнейших изменений, необходимо сразу учитывать масштаб некоторых базовых функций, изменить которые в дальнейшем сложно.

Я работала в 2х стартап-проектах, которые выстрелили и выросли в большие компании с миллионами пользователей из маленьких региональных проектов, и сейчас являются высоконагруженными. К моему удивлению я увидела, что есть много общих проблем, хотя приложения писались разными командами и для разных пользователей. Видны общие проблемы в базах данных, которые являются наследием стартапа, такими детскими проблемами роста, которые показывают, что изначально проект был запланирован маленьким.



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

И так, основные ошибки:

  1. Отсутствие возможности локализации.

    Наш мир давно стал глобальным, и для программных приложений уже нет границ. Когда проект становится популярен не только в одной стране, но и по всему миру, возможность локализации очень важна. На этапе разработки и закладывания фундамента локализации важен корректный выбор типов данных для хранения информации, которая будет различаться в зависимости от страны. Если такого фундамента нет, то локализовать приложение, когда оно уже активно используется, будет сложно. Существует 4 основных момента, которые нужно учесть при локализации.

    • Часовые пояса

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

    • Разные языки

      При выборе текстовых полей следует использовать формат Unicode или тип NVarchar, впоследствии это облегчит работу с приложением. Необходимо обратить внимание на правила сортировки и сравнения строк в вашей БД. Убедитесь, что Вы выбрали не сортировку (Collation) по умолчанию, а сортировку, которая будет корректно работать при сравнении диакритических знаков, иероглифов и символов нестандартной ширины, при условии, что конечный пользователь вводит какую-либо информацию. Скажете ваше приложение будет работать только для США или только для Европы? Тогда нужно спросить себя – будут ли там данные, которые может ввести конечный пользователь. Хотя бы что-то строка комментария или какую то информацию для себя? Если такая возможность есть – сделайте хранение строк в Unicode. Мир уже давно перемешался и вы не застрахованы, от того, что человек, пользующийся японским что-то внесет в вашу БД как пользователь. Конечная цель в том, чтобы данные пользователя правильно сохранились и потом корректно выводились.

    • Валюта

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

    • Естественные ключи

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

      Например, в одном из проектов мы думали использовать ИНН в качестве естественного ключа для контрагентов, но отказалась от этой идеи. Не могу описать словами, как мы в последствии радовались этому, так как компания начала развиваться и сотрудничать с юридическими лицами за пределами России.

  2. Типы данных

    Правильный выбор типов данных – залог успешной работы приложения, а, следовательно, здоровья и спокойного сна разработчика. При выборе размерности типа данных необходимо ориентироваться на наибольший возможный вариант из возможно большого количества пользователей и операций.

    Например, при создании таблицы со списком сотрудников только Вашей компании, допустимо использовать первичный ключ типа INT, так как вероятность роста компании до 2млд человек очень мала. Однако, если Вы создаете БД сотрудников компаний Ваших клиентов, необходимо использовать тип данных большей размерности, например, BIGINT, так как есть вероятность, что 500 тыс. сотрудников при условии смены работы четыре раза создадут 2 млн. записей в вашей БД, и таблица для хранения списка сотрудников компаний-клиентов, при наличии большого количества клиентов, вполне может разрастись и превысить 2 млрд. Это же правило действует для таблиц, которые хранят логи пользователей, и другие бизнес операции, которые с ростом приложения могут увеличиться в миллионы раз.

  3. Синхронная реакция на действия пользователя

    При проектировании системы важно продумать, какие из действий пользователей будут касаться изменения или удаления большого количества объектов системы, если система увеличится. Например, если у пользователя 2000 контактов, и он отправляет им приглашение, будет система рассылать данное приглашение немедленно, либо отобразит сообщение пользователю, о том, что его запрос обрабатывается, и затем обновит статус на выполнено, когда действие будет обработано.

    Если обработка будет немедленной, то при росте системы в дальнейшем возможны проблемы с производительностью сервера. Также, рабочая нагрузка системы при обработке всех запросов синхронно будет напрямую зависеть от действий пользователей. Например, при стандартной загрузке, системе хватает 10% ресурсов для обработки всех запросов в штатном режиме. При появлении пользовательского супер-запроса, такого как приглашение 500 тысячам пользователей одновременно, загрузка системы может возрасти до 100%. Пример несколько синтетический, но, думаю, суть понятна. При этом система перестанет штатно обрабатывать запросы остальных отдельных пользователей, пока не завершит обработку данного огромного запроса.

    Подумайте, какие действия пользователей могут быть масштабными, и сделайте их асинхронными. В примере с приглашениями система не начинает отправку немедленно, а создает новое задание «отправка приглашений пользователям». Когда задача создана, система в фоновом режиме осуществляет отправку приглашений и сообщает пользователю о выполнении задачи по ее завершению. Для удобства пользователя также немало важным является его уведомление о действиях системы, которая работает в асинхронном режиме.

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

  4. Накопление ненужных данных

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

    Например, важно хранить логи действий пользователя в течение 1-2х недель на случай, если он обратится в техническую поддержку. Затем эту информацию можно удалить. Поэтому важно продумать и сразу ввести процесс удаления старых данных до того как таких данных накопится слишком много. Если сразу не прописать данный процесс, то есть большая вероятность столкнуться с проблемой, когда в БД добавляется огромный поток новых данных, и система не справляется с удалением ненужных данных. Необходимо продумать эффективную систему удаления старых данных, такую, чтобы она не только превосходила по скорости новый поток данных, но и смогла в обозримые сроки удалить огромный массив информации за прошлые годы работы.

    Правило удаления старых ненужных данных должно касаться и всех новых функций.

  5. Отсутствие тестов и документации

    Обычно стратап-проекты спешат запуститься побыстрее. Также обычно стратапы реализует сравнительно небольшая команда разработчиков, которая знает наизусть всю бизнес логику приложения и не понимает, зачем терять время на написание документации, а иногда и тестов. Работа идет по принципу «сейчас запустимся, а потом напишем». Однако, как только система запускается, появляется огромное количество новых задач, и времени на написание документации не остается.

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

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

  6. Масштабирование

    При возрастании нагрузки на систему, возникает необходимость ее масштабирования. Следовательно, во время проектирования системы необходимо продумать возможности масштабирования системы при увеличении нагрузки, например, в 10 раз. Продуманный под возможность масштабирования дизайн облегчит последующие изменения под новые реалии растущей системы.

    Было бы хорошо задать себе и разработчикам следующие вопросы:

    • Как увеличится производительность системы, если нарастить мощность оборудования?

    • Можно ли создать копию системы на другом сервере и включить его в работу? Если нет, что нужно изменить в дизайне, чтобы это стало возможным?

    • Насколько большой масштаб изменений нужен для разбиения системы на несколько частей и перестройки архитектуры с использованием принципов SOA или микросервисов?

    Это не значит, что систему необходимо проектировать сразу крупномасштабной, но важно заложить фундамент дальнейшего масштабирования системы. Соломку стелите тонким слоем, не надо сразу везде снопы складывать.

Итак, на начальных стадиях проектирования системы важно соблюдать баланс между работой на будущее и работой на настоящее. И настоящее важнее, потому что существуют конкретные требования и задачи, которые необходимо реализовать, обычно в сжатые сроки. Будущее может и не наступить, или предстать совершенно иным, изначально ожидалось. Если у вас попросили сделать городской автобус, совсем не нужно сразу делать возможность преобразования его в космический корабль, ведь этого будущего у городского автобуса может и не случиться. Поэтому идеальным является заложить основу дальнейшего разделения системы, которая впоследствии будет использована для разнесения на сервисы и модули.
Поделиться с друзьями
-->

Комментарии (30)


  1. zenkz
    19.05.2017 19:44
    +2

    Локализация — один из самых болезненных вопросов. Тут важно всё, начиная от региональных настроек сервера и клиентов и заканчивая способами хранения текстовых констант для локализации. Видел несколько проектов, не заложивших это заранее, а потом с большой болью пытавшихся это внедрить.

    Ещё одна беда многих проектов — дублирование кода. Нужно изначально заложить в архитектуру приложения как можно больше защиты против этого.

    Третья беда — отсутствие продуманной процедуры обновления от версии к версии с возможностью отката и отсутствие скриптов для для разворачивания базы данных с нуля.

    Частая ошибка — неправильный выбор типа данных для ключа в базе данных. Из-за чего возникают ошибки когда таблица перерастает определённый размер (к примеру 32000 записей для int), либо возникают проблемы с масштабированием. К этой же проблеме отнесём и автогенерацию первичных ключей, которая опять же либо выглядит как костыль, либо страдает от проблем с масштабированием. Логичным выходом является использование GUID, но он медленный и очень неудобен в отладке и написании SQL запросов для поддержки и анализа проблем.


    1. zenkz
      19.05.2017 21:14
      +2

      Дополню свой комментарий ещё парой мыслей:

      Ошибки выбора типов данных встречаются не только для первичных ключей. Это очень большая проблема для строк (Юникод или однобайтовые строки), для дробных значений (к примеру знаю одну программу для ломбардов, которая считает деньги в float типе, а учитывая то, что проценты считаются по дням и в результате генерируется много записей с небольшими суммами, то ошибка быстро накапливается и приводит к расхождению на несколько рублей в сутки для всего ломбарда). Другая проблема — недостаточная точность. Часто считается, что точности 2 знака после запятой для хранения денег достаточно, но фактически есть операции, где важны значения до 5ого знака. К примеру та же пеня.

      Ещё одна ошибка архитектуры — «сделаем прототип, а потом переделаем». Это не работает. Всегда пишите так, как будто этот код — критически важен для проекта. Видел случаи когда пилили прототип, а потом заказчик сказал идти в продакшн. И его можно понять — перед ним рабочая система, но вы говорите ему, что нужно всё переделать и ещё и заплатить за это…

      Частая проблема, которую можно видеть особенно в старых проектах, это любовь к универсальным решениям. Вплоть до форм, конфигурируемых с помощью xml и генерации SQL запросов на лету. Это работает для простейших задач, но порождает проблемы удобства использования для клиентов, снижает безопасность системы и порождает различные костыли.


      1. KristinaMyLife
        19.05.2017 23:23
        +2

        Ой как раз первое приложение было финансовым, и там использовали тип с фиксированной точностью до 4 знаков, и много не было. Когда прочитала про float для финансовых данных аж все сжалось, это прямо «ужас ужас ужас».

        Согласна про излишнюю универсальность. Тут очень важно уметь правильно остановится. Иногда решение усложняется в разы, потому что пытаются заложить универсальность, под случаи, которые происходят в 0,03% случаев и в итоге вся система работает медленнее и не если бы только медленнее, но и сложнее.


      1. barkalov
        20.05.2017 18:53
        +2

        Всегда пишите так, как будто этот код — критически важен для проекта.
        Казалось бы хороший совет, но он не работает.
        Высокий приоритет везде = отсутствие приоритета.


        1. Odrin
          22.05.2017 10:05

          Приоритет должен влиять на порядок выполнения задач, но не на качество выполнения.


      1. dadwin
        20.05.2017 23:26
        +1

        Видел случаи когда пилили прототип, а потом заказчик сказал идти в продакшн.

        а что заказчику обещали? production-ready систему или прототип на-посмотреть?
        возможно ожидания у заказчика были выставлены неудачно

        Всегда пишите так, как будто этот код — критически важен для проекта.

        мне кажется, такой подход плохо сработает, если вы используете новые для себя технологии (библиотеки, инструменты — всё, что относится к разработке). Как бы не был важен этот функционал, будет трудно принимать решения «как лучше его реализовать», потому что в начале не хватает опыта. ИМХО, новая предметная область тоже может влиять — откуда бы мне, разработчику, знать, что вне РФ нет такой сущности как ИНН, так что я честно делаю ИНН ключом:)
        я клоню к тому, что вы много времени потратите с таким подходом.

        есть же прототипы, которые делаются только с целью proof-of-concept: разработали, научились, собрали ошибки, в следующем прототипе или в новой системе сделаете правильно в заданном контексте. на самом деле этот подход тоже небыстрый, но более эффективный с точки зрения вашего обучения и с большей обратной связью от пользователей/заказчика.


        1. zenkz
          23.05.2017 23:47
          +1

          Про «Всегда пишите так, как будто этот код — критически важен для проекта.» — Тут вопрос в качестве и ответственности за код. Часто на начальных стадиях проекта много кода пишется как Proof-of-Concept, но затем к нему уже не возвращаеются и он идёт в продакшн. Сюда же относится создание технического долга с самого начала проекта, притом часто создаются очень болезненные проблемы вроде «дедлайн поджимает, так что давайте вносить изменения в конфигурации CMS-ки на-живую без документирования и создания скриптов — всё равно же у нас один заказчик и базу данных никогда не прийдётся разворачивать с нуля». Вроде разумное решение, но скольно оно может создать проблем в будущем — страшно представить!


    1. alexsibtone
      20.05.2017 09:52

      smallint (postgres) = -32768..+32768, так что int более 2 млрд строк.


  1. zxweed
    19.05.2017 22:32

    хехе
    > Практически во всех канонических учебниках по базам данных описывается, насколько неэффективны искусственные ключи и как прекрасны естественные.
    Ровно наоборот, в любом учебнике написано, что эффективны как раз искусственные ключи, а естественные — ужасны.


    1. KristinaMyLife
      19.05.2017 23:25

      Это видимо уже писали люди, который достался проект с естественными ключами.


      1. bopoh13
        21.05.2017 23:13

        Вопрос интересный, вот где стандартов не хватает.


        1. barkalov
          22.05.2017 10:16

    1. zenkz
      20.05.2017 00:42

      Всегда стараюсь сделать ключ простым и с использованием простого типа. Даже если есть возможность сделать естественный ключ (простой или составной). Причина очень простая — даже если на текущий момент ключ выглядит уникальным, то в будущем это правило может быть нарушено. Возьмём стандартный пример с людьми: Фамилия, Имя, Отчество опциональны или неуникальны, ИИН и прочие госномера применимы только для конкретных стран и имеют свойство меняться. К примеру через 5 лет примут закон, что в ИИН будет 20 символов длиной и может включать буквы, или вообще их отменят. Что тогда?!


      1. barkalov
        20.05.2017 19:09

        А как насчет UUIDv5 по ИНН + Фамилия + Имя + Отчество + whatever. Каковы минусы такого решения, кроме коллизий?


        1. Nikita_Danilov
          21.05.2017 11:12
          +1

          В MS SQL (да и думаю во всех реляционных БД) индексы по полям простого типа (число, гуид) работают значительно лучше/эффективнее чем по строковым. Значит и джойны по простым полям будут работать лучше.


        1. dmpas
          21.05.2017 15:19

          1. «Фамилия Имя Отчество» могут меняться

          2. https://habrahabr.ru/post/146901/


  1. JediPhilosopher
    20.05.2017 00:58
    +5

    Все это прекрасно, но есть замечательный коммент который хорошо описывает почему так никогда не будет https://habrahabr.ru/post/310310/#comment_9825136

    Я раньше поражался тому, как уродливы изнутри «взлетевшие» проекты. Сейчас я знаю: красивые проекты не взлетают, потому что они не успевают взлететь. Пока инженеры в белых халатах прикручивают красивый двигатель к идеальному крылу, бригада взлохмаченных придурков во главе с безумным авантюристом пролетает над ними на конструкции из микроавтобуса, забора и двух промышленных фенов, навстречу второму туру инвестиций. Авантюрист любезно раздаёт восторженным пассажирам талоны и бумажные пакетики.


    1. KristinaMyLife
      20.05.2017 09:57

      К сожалению это так — победил не тот кто сделал лучший продукт, а тот кто сделал продукт быстрее или\и смог его побыстрее продать большему количеству людей.
      С другой стороны в enterprise на мой взгляд уж очень тяжко все и медленно двигается. Народ может обсуждать и переделывать по 5 раз решение, хотя в это время в проде может быть абсолютная лажа, и любой из новых вариантов был бы лучше, но нет, надо же найти лучшее. В результате вместо 2х дней на изменение тратится от 2х до 3х недель. И это я говорю о простом изменении, если что-то помасшабнее, то вообще все грустно.
      В общем во всем нужна мера.


  1. michael_vostrikov
    20.05.2017 08:57
    +3

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

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


    Можно использовать один ключ в нескольких базах данных, но от этого он не станет менее искусственным. Это всё потому что у объекта-сущности может измениться любое свойство, но мы все равно будем считать его тем же объектом.


    1. KristinaMyLife
      20.05.2017 10:03

      Прямо самая суть! Задача ключа как раз сказать когда мы имеем дело с тем же объектом, а когда это уже другой объект, пусть и с частично совпадающими свойствами. Понятно, что «сферического коня в вакууме» или «идеального ключа» тут не будет, важно выбрать что-то, что будет выполнять задачу идентификации объекта достаточно хорошо, в рамках поставленной задачи. В идеале еще заглянуть в хрустальный шар и посмотреть, как рамки поставленной задачи могут расшириться. Но хрустальные шары иногда мутные, и не всегда видно, как и куда проект пойдет в дальнейшем.


  1. Scf
    20.05.2017 10:11
    +2

    Добавлю свои пять копеек для стартапов:


    • автоматизированный деплоймент и автоматизированный откат деплоймента. Экономит просто гигантское количество времени и нервов, особенно если приложениие нужно обновлять каждый день или оно не обновлялось несколько месяцев. Относится как к деплойменту приложения, так и к базам данных
    • логгирование, алертинг и аналитика. Нужно думать сразу, какая информация нужна для аналитики, какие ошибки требуют немедленной реакции админа, а какие нужно регулярно просмотривать в поисках багов или проблем с приложением.
    • прототипы являются очень полезным инструментом при соблюдении простых правил:
      — прототип должен содержать ровно столько функционала, чтобы впечатлить инвесторов или оценить спрос на идею. Идеальный прототип — лендинг с формой сбора email-ов.
      — прототип не расширяется и не переписывается — он выкидывается. Поэтому его желательно делать с использованием средств быстрой разработки (CMS, фреймворки...)


  1. Nikita_Danilov
    20.05.2017 12:14

    Соглашусь (и обеими руками поддержу) со всем, но по 4му пункту в части логов уточню:

    важно хранить логи действий пользователя в течение 1-2х недель на случай, если он обратится в техническую поддержку. Затем эту информацию можно удалить.

    Очень зависит от специфики системы. Действительно, важно понимать ЧТО вы логгируете, не стремясь просто набить терабайт побольше и потом хвалиться ими. Но вот у нас бывают случаи разбора проблем и 3х месячной давности, и тогда только детальные логи помогают понять в чем дело. Иные процессы требуют вообще журналирования более чем на год, пусть и довольно поверхностного.


    1. KristinaMyLife
      20.05.2017 12:17

      Спасибо за дополнение, да согласна, ключевая идея — определить срок хранения, даже если это 1 год, 3 года или 5. Если сначала определили какой-то большой срок — например 5 лет иногда возможно посмотреть как часто происходит обращение к этим данным, если к данным старше 1 года никто не обращался ни разу — можно выгрузить эти данные вообще куда-нибудь в файл и оставить на каком-нибудь медленном диске, на случай обращения.


  1. hippoage
    21.05.2017 00:18

    Не соглашусь со статьей в целом. Да, интересно почитать какие задачи были в успешных проектах при росте. Но если их решать сразу в начале, то с огромной вероятностью успешного проекта не получится.

    В начале идет большое количество изменений (новый функционал, исправленный старый, эксперименты). Если вместо этого пилить ненужный функционал (закладываться на будущее), то не только стоимость ненужного сейчас функционала и задержка нужного из-за занятости программистов тянут проект к банкротству, но и увеличение стоимости любого функционала из-за ненужного.

    Например, локализация, когда достаточно одного языка. Или обрезание логов для двух недель, а потребовалось проанализировать поведение пользователей за больший промежуток времени.


    1. KristinaMyLife
      21.05.2017 00:42

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


      1. vadim1406
        21.05.2017 19:42

        «тут можно и юникод не использовать» — а сейчас точно 2017 год?! Что значит не использовать юникод? Почему? Как?! Типа место экономим? :) Все соврменные средства программирования заточены под юникод, так почему БД не должна его использовать?


        1. KristinaMyLife
          21.05.2017 23:46

          Так как у нас 2017 год, то БД практически всегда должна использовать юникод.
          Но для хранение юникод данных используется в 2 раза больше места, чем для хранение в локальной кодировке. Я не делала проекты, которые бы могли быть только локальными — мне кажется это может быть госсектор или что то еще только локальное, может быть областное, и оно не предполагает хранения отображаемых данных. Например. названия улиц — потому что могут решить их продублировать на китайском — и будет проблема.
          В общем это я к чему, вроде и 2017й год и дисковое пространство дешевле. Но
          Например у нас 100 полей со строковыми данными, для простоты размером до 200 символов каждое. Для MS SQL берем Varchar (1 байт) и Nvarchar (2 байта на символ)
          Varchar 2000 байт на строку
          NVarchar 4000 байт на строку
          Вроде мало — какая разница-то?
          А теперь представим что у нас добавляется этих строк много.
          То есть когда у вас 4 Тб данных или 8 Тб это все таки имеет значение. Опять же тут надо все таки очень сильно думать — будет у вас больше одного языка и латиницы или нет.
          И да в 99% надо использовать юникод.


  1. vadim1406
    21.05.2017 19:47
    +1

    Про локализацию… Все названия, имена, описания — сразу сохраняем в двух языках — локальный и латинский (два поля в БД: NameLoc, NameLat) по минимуму. По максимуму — словарь с языками, ссылки на этот справочник и прочее. Хотя не могу вспомнить систему, где данные (не UI) больше чем на двух языках.


    1. VolCh
      22.05.2017 11:03

      И пользователей заставлять на латыни писать названия и описания? Тут даже поле key (вторичный ключ, чтобы из приложения было удобнее анализировать) они нормально заполнить на английском не могут, а уж всё...


  1. VolCh
    21.05.2017 20:38
    +1

    Очень скептически отношусь к идее удаления логов и прочей истории. Другое дело, что нужно регулярно перемещать старые записи из оперативных баз (или таблиц) в архивы.


    По поводу времени в UTC — если уж приняли такое решение "на будущее", то всегда понимайте где у вас по бизнес-логике дата, а где датавремя и никогда не надейтесь на автоматическое приведение даты и даты+времени при сравнении, вычислении длительности и т. п. Требуйте от бизнеса явных правил приведения дат ко времени и назад с учетом часового пояса пользователя и офиса, его обслуживающего, если начинаете работать в нескольких часовых поясах, чтобы не получалось что человек оплатил подписку только что, а станет она ему доступна только с полночи в Гринвиче. Или наоборот, оплатил за 30 дней, а получит, например, 29 дней и 20 часов.