NoSQL и Антивакцинаторство

b91c11cb28586abdfccf7336cb03e5d7.png

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

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

С середины прошлого века мы работаем над реляционными базами данных. И они прекрасны. Но сейчас все чаще любят использовать NoSQL всех видов и мастей. И они иногда неплохо ложатся и затыкают собой какое-то мелкое место в проекте. Если я ценю свои данные и мне нужна какая-то надежность, то мне нужны ACID гарантии. Если это всего лишь кеш, данные из которого нужны чтобы ускорить приложение то я с радостью возьму Redis или аналоги. Ведь если он упадет или данные рассогласуются я смогу их восстановить из нормальной базы.

Справедливости ради часть ACID гарантий завезли уже и в некоторые нереляционки, где-то их даже включили по умолчанию.

Несколько раз мне приходилось расследовать инциденты связанные с битыми данными в NoSQL базах или даже просто в самописных хранилищах поверх файловой системы. Это был ад. Тот ад, который я больше никогда не хочу видеть на этой Земле. А эти инциденты повторялись. Работая с реляционными базами каждый такой инцидент повторялся лишь единожды, причиной его становился забытый constraint или внешний ключ или пачка операций не была завернута в транзакцию. В любом случае проблема решалась одним из инструментов и больше не воспроизводилась.

Скорее всего есть те, кто не собирал по столу вытекшие глаза после расследования инцидента связанного с битыми данными. Они скажут, что ACID гарантии избыточны. Так эти гарантии стали жертвами собственной эффективности. Но, кстати, даже тут современным СУБД есть что ответить: да из коробки они заточены на поддержание данных в максимальной консистентности, но если вам это не нужно, то у вас есть широкий набор инструментов, чтобы эти гарантии ослабить в одном конкретном узком месте, оставляя их в другом.

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

Только вот код бизнес логики будет меняться еще десятки раз, да и собрать его по десятку сервисов, каждый из которых аж до тошноты соответствует букве S из SOLID будет непросто. А этот constraint занимает всего пару строк великолепного SQL. Который кое-как читается даже людьми с ним сильно не знакомыми. Хотя так ли их много в сообществе разработчиков? Все таки, как не крути NoSQL-мыслевирус еще не засел так глубоко и большинство все-таки на каком-то уровне SQL выживают.

А ведь SQL потрясающий язык, может у меня идет сумасшедшая профдеформация, но я иногда думаю, что мир был бы лучше, если бы SQL учили все. Когда смотрю какой-то закрученный детектив где ФБР не может найти серийного убийцу действующего в тех-то штатах в такие-то годы я понимаю, что по факту имей мир SQL интерфейс, то это был бы всего лишь один простой SQL запрос с несколькими INTERSECT операторами.

А вот еще… Необходимость описывать схему и структурировать данные.

Тут есть два варианта: если вы пишете на строго типизированном языке, то вряд ли ваши данные, которые вы хотите складывать в свою базу такая уж свалка. Потому что если там прямо совсем треш, то как вы его получили? Ну ладно, даже если вы его как-то получили, то что вы с этими данными потом собираетесь делать? Как вы будете обрабатывать совсем уж не структурированный поток данных. Скорее всего какая-то структура данных у вас таки есть. Если же вы пишете на языке без строгой системы типов, то после того как я понимающе и соболезнуя похлопаю вас по плечу, я все равно спрошу у вас: А как вы собираетесь эти данные обрабатывать?! Ну то есть типов может и нет у вас в языке, но они есть в компьютере под капотом как не крути и очень сложно писать код, который работает совсем уж с не определенными типами.

И я действительно готов поверить, да что там готов, у меня у самого в одном из пет-проектов есть необходимость хранить свалку HTML. Возможно здесь бы и легла лучше какая-то NoSQL база, но у меня уже в проекте была реляционка. И знаете что? Она вполне себе справилась с этой задачей, даже не особо чихнув или подавившись.

Я знаю, что все основные СУБД уже поддерживают JSON как один из основных типов. То есть, если где-то в проекте вам таки нужно устроить свалку из черт знает чего, то почти каждая современная база даст это сделать. Более того, по черт знает чему можно построить даже индекс или заставить валидировать при вставки на соответствии схеме.

А еще тулинг. С инструментами для баз данных часто все хуже чем с инструментами для .net, java, python etc, но насколько же они несравнимо лучше чем та дрянь, что существует для нереляционок. А еще не для всех нереляционок вообще есть что-то внятное, что позволит нормально посмотреть на свои данные. Более того, за почти 70 лет, что активно развиваются реляционные базы инструменты успели не только появится, их успели отладить, на StackOverflow успели задать вопросы и получить ответы. Разрабатывая проект с реляционной базой под капотом вообще не получится себя почувствовать первопроходцем, ведь первая же ссылка в гугле будет отвечать на ваш вопрос. Даже если это не сама база, а что-то вокруг нее: инструменты для репликации, бекапов, мониторинга или еще черт знает чего. Да даже ORM последнее время стали совсем не дурны.

По SQL даже книжки есть хорошие, причем их даже много. Многие из них издаются уже с десяток лет и там исправлены основные неточности. Вряд ли вчера появившаяся нереляционка обещающая, непонятно как измеренный потрясающий performance, сможет таким похвастаться еще лет 20. А протянет ли она 20 лет?

При приеме на работу сложно требовать знания конкретной нереляционки. Их многовато стало последнее время. С другой стороны все SQL базы похожи между собой сильнее чем нереляционки между собой. И это значит, что вам будет легче нанимать людей с их знанием. Более того общаться в команде будет легче. И выше будет вероятность, что кто-то из команды уже решал эту задачу ранее и получил какой-то практический опыт. Возможно даже негативный. Любят как-то недооценивать этот момент. Но при работе с NoSQL, может это только у меня так было, сравнительно глубоко знал особенности этих баз и был вынужден постоянно объяснять термины, нюансы и edge-кейсы остальным.

Выводы

Я иногда использую NoSQL базы. Но делаю это в крайнем случае.

Сначала я раскладываю все в реляционку. Это решение по умолчанию. Если что-то где-то оказывается неудобно или тормозит, я могу ослабить гарантии или денормализовать данные. Обычно этого хватает. Когда этого не хватает для этого конкретного случая отлично подходят нереляционки. Но не стоит переводить на них весь проект.

Инструменты для NoSQL оставляют желать лучшего, а для некоторых задач отсутствуют.

Про SQL-базы проще разговаривать в команде, проще нанимать людей, проще искать ответы.

Дисклеймер: Статья имеет легкий правокационно юмористический налет.

И да. Дисклеймеры обычно пишут в начале.

© Habrahabr.ru