Уроки моих ошибок: начните с MySQL

Если вы собираетесь начать писать свой первый проект, у вас может возникнуть соблазн начать с базы данных NoSQL. Это реальные проблемы, с которыми я столкнулся, сделав именно это.

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

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

1Во-первых, в NoSQL нет визуального редактора баз данных, такого как MySQL Workbench. В нем вы можете протестировать каждый запрос, прежде чем писать его в свой код, чтобы увидеть, возвращает ли он, изменяет или удаляет то, что вы хотите.

Именно так будет выглядеть ваша строка кода, когда вам нужно будет сделать реальный запрос в вашем коде. Как только вы введете его в редактор и нажмете «Выполнить», он отправит результаты.

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

С другой стороны, NoSQL требует, чтобы вы тестировали запросы в среде, за настройку которой вы отвечаете с нуля. Вы едете.

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

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

2Предположим, что у вас более 1000 элементов в таблице базы данных. Если вы не знаете точно, какой элемент вам нужен, выполнение операции, которая просматривает всю вашу таблицу NoSQL, чтобы найти его, будет дорого с точки зрения памяти и времени.

Этот тип операции называется сканированием. Если вы читаете это и думаете, что вам придется много этим заниматься, NoSQL причинит вам боль. То же самое происходит, если вам нужно получить более 1000 элементов за раз.

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

Find all restaurants whose type = sushi or pizza

Это прекрасный запрос для запуска в MySQL. Не так много на NoSQL. Это можно сделать до определенного момента, но это не то, для чего это нужно.

Вместо этого NoSQL создан для ситуаций, когда вы точно знаете, какой элемент вам нужен.

Get restaurant 004488

Возьмем, к примеру, приложение для обмена сообщениями. Приложение для обмена сообщениями — хорошее применение для базы данных NoSQL. Однако, если вы строите его впервые, вы можете столкнуться с некоторыми неожиданными проблемами.

В приложении для обмена сообщениями вы всегда будете знать идентификаторы участников (sarah101, jill102) и ветку сообщений (229900). Таким образом, вы всегда можете запросить определенные элементы по их идентификатору.

Вы можете получить точную ветку для jill102 и sarah101:

Get thread 229900

Или, если мы не знаем, какая ветка для разговора jill102 и sarah101, вы можете получить элементы для jill102и sarah101, а затем сравните потоки, частью которых они являются:

Get user jill102
returns... {user: jill102, displayName: JillPickle, email: [email protected] threads: [229900, 112284, 030399]}
Get user sarah101
returns... {user: sarah101, displayName: SarahBear, email: [email protected] threads: [229900, 887765, 2004123]}
Get thread 229900

Но в базе данных NoSQL вы не должны получать все потоки, из которых состоят jill102 и sarah101, путем сканирования всей таблицы потоков следующим образом:

Find all threads whose users are jill102 and sarah101

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

Если Джилл хочет найти сообщение от Сары о скалолазании пару месяцев назад, вам придется просмотреть все сообщения в цепочке 002299:

Find all messages in thread 002299 that contain "rock climbing"

Этот запрос просматривает каждое одно из тысяч сообщений в их потоке.

Если это предиктивный поиск, все становится еще хуже, поскольку вы будете запускать этот запрос с каждым нажатием клавиши:

Find all messages that contain "r"
Find all messages that contain "ro"
Find all messages that contain "roc"
Find all messages that contain "rock"
Find all messages that contain "rocki"
etc.

Либо запрос вернет плохие результаты. Или ваша база данных израсходует достаточно ресурсов, чтобы вызвать проблемы у всех пользователей².

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

Интерфейс Workbench³ невозможно переоценить с точки зрения ценности. Это сэкономит ваше время и поможет лучше понять, что происходит в вашей базе данных. Добавьте к этому гибкость MySQL, и вы сможете сосредоточиться на важных аспектах вашего проекта, а не на головной боли, связанной с тем, как обойти ограничения вашей базы данных.

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

²Возможности в этом сценарии включают, но не ограничиваются:

  1. Несохраненные/неотправленные/неполученные сообщения
  2. Бесконечный спиннер

Есть и другие. «Sequel Pro — популярный выбор.

Ресурсы MySQL

Amazon Web Services RDS (Relational Database System)
Using MySQL with Node.js

Ресурсы NoSQL

Amazon Web Services DynamoDB
DynamoDB Basics
You can find a good starter assortment of DynamoDB handling functions I've put up on github.

Блог Фила и Дрюса

Первоначально опубликовано на philandrews.io.