Отчасти это действенный совет, отчасти — вопрос к читателям.
Совет: при создании нового приложения, требующего постоянного хранения данных, как это и бывает в случае большинства веб-приложений, по умолчанию следует выбирать Postgres
.
Почему не sqlite?
sqlite
— достаточно неплохая база данных, но данные хранятся в одном файле.
Из этого следует, что, каким бы ни было ваше приложение, оно работает на одной и только на одной машине. Или, по крайней мере, в одной общей файловой системе.
Если вы создаёте десктопное или мобильное приложение, то это идеальное решение. Если вы делаете веб-сайт, то это не всегда так.
Существует множество историй успеха о применении sqlite
для веб-сайта, но в основном их рассказывают люди, создававшие собственные серверы и инфраструктуру. Platforms as a service наподобие Heroku, Railway, Render и так далее в общем случае ожидают, что вы будете использовать базу данных, доступ к которой выполняется через границу сети. Нет ничего плохого в том, чтобы отказаться от части преимуществ таких платформ, но подумайте, стоят ли преимущества sqlite
отказа от предоставляемых платформой автоматических бэкапов баз данных и возможности работы с несколькими серверами приложений.
В официальной документации есть хорошее руководство с более подробным описанием.
Почему не DynamoDB, Cassandra или MongoDB?
Где бы ни был сейчас Рик Хулихэн, надеюсь, у него всё хорошо.
Я смотрю много докладов с конференций, но, вероятно, чаще всего смотрю его доклад DynamoDB Deep Dive 2018 года. Знаю, что немногие из вас готовы смотреть часовой доклад, но оно того стоит. Доклад очень хорош.
В целом смысл этого доклада заключается в том, что базы данных в том же стиле, что и DynamoDB
(в том числе и Cassandra
с MongoDB
), замечательные, если... и это «если» очень важно:
Вы точно заранее знаете, что должно делать ваше приложение.
Вы точно заранее знаете, какими будут паттерны доступа.
Вам точно известно, что придётся масштабироваться до очень больших объёмов данных.
Вы готовы отказаться от определённого уровня consistency.
Всё это связано с тем, что подобные базы данных, по сути, представляют собой огромную распределённую хэш-таблицу. Единственные операции, работающие без необходимости сканирования всей базы данных — это поиск по секционному ключу и сканы, при которых используется ключ сортировки.
Какие бы запросы вам ни нужно было выполнять, перед хранением данных придётся закодировать это знание в один из таких индексов. Хотите хранить пользователей и искать их или по имени, или по фамилии? Тогда вам лучше создать ключ сортировки вида <FIRST NAME>$<LAST NAME>
. Паттерны доступа должны быть неразрывно связаны с тем, как вы храните данные. Если паттерны доступа существенно изменятся, то может потребоваться полная повторная обработка всех данных.
И это раздражает, особенно в случае MongoDB
, ведь разработчиков убеждают, что эта база данных более «гибкая». Да, вам не придётся создавать её схему. Да, можно просто сохранять нетипизированый JSON в коллекции. Нет, это не гибкий тип базы данных, а эффективный.
При работе с реляционной базой данных можно перейти от получения всех домашних питомцев человека к получению всех владельцев домашнего питомца, добавив в таблицы один-два индекса. Но при работе с такой разновидностью NoSQL это может быть сложной задачей.
К тому же она не так удобна, если вам нужно выполнять аналитические запросы. На произвольные вопросы наподобие «сколько пользователей выполняло вход в прошлом месяце?» можно элементарно ответить, написав SQL-запрос; может быть, на реплике для чтения, если вы опасаетесь выполнять затратный запрос на той же машине, что работает с трафиком пользователей. Это просто невозможно для подобного типа баз данных. Для обработки данных вам потребуется вывести их с помощью ETL.
Если вы видите, что студент или выпускник использует MongoDB
, то остановите его. Ему нужна помощь. Его ввели в заблуждение.
Почему не Valkey?
Ставшая потомком Redis
, эта база данных больше всего известна тем, что работает эффективным кэшем вне процесса. Вы вычисляете что-то затратное один раз и засовываете это в Valkey
, чтобы пяти вашим HTTP-серверам не приходилось вычислять это заново.
Однако её можно использовать в качестве основной базы данных. Она хранит все свои данные в ОЗУ, поэтому довольно быстра.
Очевидные проблемы:
Размер ОЗУ ограничен. Да, можно установить гораздо больше памяти, чем вы могли бы представить, но она всё равно достаточно ограничена по сравнению с жёсткими дисками.
Аналогично с
DynamoDB
и подобными ей базами данных, вам нужно будет заранее продумывать модель данных.
Почему не Datomic?
Если вы о ней уже знали, то заслуживаете уважения.
Datomic
— это база данных NoSQL
, но реляционная. У неё нет проблем, связанных с необходимостью проектировать всё заранее, к тому же она обладает некоторыми приятными свойствами.
Данные хранятся не в таблицах, а в парах «сущность-атрибут-значение-время» (entity-attribute-value-time, EAVT). Вместо строки person с id
, name
и age
мы храним 1 :person/name "Beth"
и 1 :person/age 30
. Благодаря этому запросы работают на основе «универсальных» индексов.
Вам не нужно координироваться с writer при отправке запросов. Запросы к базе данных выполняются по состоянию на заданное время. Новые данные, даже операции удаления (или, как их называют, retraction), на самом деле не удаляют старые данные.
Но существуют и серьёзные проблемы:
Она работает только с JVM-языками.
Вне
Clojure
(достаточно нишевого языка) её API ужасен.Если плохо структурировать запрос, то сообщения об ошибках будут ужасными.
Вся вселенная разработанных для SQL инструментов здесь просто недоступна.
Почему не XTDB?
Любители Clojure
создают множество баз данных.
По духу XTDB
похожа на Datomic
, но:
У неё есть HTTP API, то есть вы не привязаны к JVM.
Существует две оси времени, относительно которых можно выполнять запросы. System Time, когда записи были вставлены, и Valid Time.
Она имеет SQL API.
Самые важные аргументы против:
Она новая. Её SQL API появилась только в прошлом году. Недавно у неё поменялась вся модель хранения. Выживет ли разрабатывающая её компания ещё десять лет? Кто знает!
Ладно, признаю, это только один аргумент. Уверен, что можно придумать и другие, но считайте, что он актуален для всех новых баз данных. Лучший показатель того, что нечто будет существовать в будущем — это его возраст. COBOL существует уже десятки лет и будет жить ещё несколько десятков.
Если у вас есть постоянное хранилище, то вы хотите, чтобы срок его поддержки был максимально долгим. Разумеется, можно выбрать для своего приложения новую или экспериментальную базу данных, но вне зависимости от её технических свойств это рискованный выбор. Он не должен рассматриваться как вариант по умолчанию.
Почему не Kafka?
Kafka
— это журнал, в который можно только добавлять информацию. Он может справляться с терабайтами данных. Это очень хороший журнал только для записи. Он превосходно работает, если вам нужно выполнять что-то наподобие event sourcing с данными, поступающими из множества сервисов, поддерживаемых различными командами.
Но:
До определённого масштаба таблица в Postgres идеально работает в качестве журнала только для записи.
Вероятно, над вашим продуктом не будут работать сотни людей и в него не будут поступать терабайты событий.
При создании Kafka consumer можно совершить больше ошибок, чем вы ожидаете, ведь вам нужно отслеживать своё место в журнале.
Даже если она имеет поддержку поставщика облачных услуг (а хорошие управляемые сервисы
Kafka
существуют), это ещё одна часть инфраструктуры, которую нужно мониторить.
Почему не ElasticSearch?
Будет ли поиск по данным основной функцией вашего продукта?
Если да, то ElasticSearch
даст вам серьёзные преимущества. Вам придётся подавать данные в неё через ETL и управлять всем процессом, но ElasticSearch
изначально предназначена для поиска. И она хорошо с ним справляется.
Если же нет, то вполне подойдёт Postgres
. Для большинства приложений более чем достаточно будет добавить немного ilike
и встроенного полнотекстового поиска. При необходимости вы в дальнейшем всегда сможете добавить отдельную функцию поиска.
Почему не MSSQL или Oracle DB?
Вы должны задать себе откровенный вопрос: стоят ли они своей цены?
Я имею в виду не только саму стоимость лицензии, но и затраты на привязку к поставщику. Как только ваши данные попадут в Oracle DB
, вы будете платить Oracle вечно. Вам вечно придётся обучать своих кодеров её особенностям. И вечно выбирать между enterprise-фичами и своим кошельком.
Я знаю, очень маловероятно, что вы выпустите патч для Postgres
, так что не буду притворяться, что возникнет какое-то волшебство «мощи open source», но считаю, что для выбора проприетарной базы данных у вас должны быть очень конкретные потребности. Если вам не нужна какая-то совершенно уникальная фича MSSQL
, без которой вы просто не можете жить, то не используйте её.
Почему не MySQL?
По этому пункту мне нужна помощь читателей.
MySQL
владеет Oracle. У неё есть фичи, доступные только в enterprise-версиях. То есть в определённой степени у вас возникнут те же проблемы привязки к поставщику, как и в случае с другими базами данных.
Однако бесплатная версия MySQL
уже применяется в чрезвычайно широком спектре областей. Она существует очень давно. Есть люди, знающие, как с ней работать.
Моя проблема заключается в том, что за свою карьеру я работал с ней всего около полугода. Я просто не знаю её так хорошо, чтобы обоснованно сравнивать с Postgres
.
Я уверен, что у неё нет каких-то невероятных скрытых преимуществ и я никого не сбиваю с толку, предлагая пользоваться Postgres
. К тому же я читал о том, что у Postgres
в общем случае лучше реализована поддержка обеспечения соблюдения инвариантов внутри самой базы данных, но не буду против, если кто-нибудь расскажет мне что-то новое по этому вопросу.
Почему не какие-нибудь векторные базы данных ИИ?
Большинство из них новые. Помните о рисках использования нового.
ИИ — это пузырь. Да, это пузырь, пусть и выполняющий свои задачи, но всё-таки пузырь. Не стройте на нём систему, если этого можно избежать.
Даже если ваш бизнес — это ещё одно ИИ-жульничество, вам, вероятно, всё равно достаточно просто сделать
import openai
.
Почему не Google Sheets?
Вы правы. Здесь никаких минусов я найти не могу. Остановитесь на них.