Не всё должно быть таблицей

Сначала запросы, потом хранилище

28 мин
Чему научишься
  • описывать задачу хранилища вопросами: что ищут, как часто и насколько свежим должен быть ответ;
  • отличать поиск по точному ключу от поиска по условию;
  • не выбирать хранилище по тому, в каком виде пришли данные.

Комендант смотрит на погасшие архивы. «Пять хранилищ. Кто решал, что в какое класть?»

КВЕРИ первым находит зацепку — журнал, который программы «Котомаркета» вели о своих обращениях к данным. За последнюю минуту перед 18:00 в нём записано, о чём они спрашивали и сколько раз. Рядом инженеры магазина приписали, насколько свежим должен быть каждый ответ.

КВЕРИ: Похоже, выбор начинался не с названия технологии. Сначала здесь считали вопросы.

Курсант со спины у голографического журнала; в воздухе плывут строки-вопросы разной яркости, робот-кот сидит на краю пульта
Последняя минута магазина: о чём программы спрашивали свои данные.

Вопросы раньше хранилища

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

Поэтому инженер начинает с работы программы. Что она будет спрашивать у данных? Что будет менять? Какие ответы нужны постоянно, а какие редко? Только после этого имеет смысл выбирать хранилище.

Например, для корзины покупателя 17 программа уже знает точное имя нужной записи — ключ cart:17. Ей не нужно просматривать все корзины и проверять каждую. Это поиск по точному ключу.

С выручкой иначе. Вопрос «все заказы за вчера дороже тысячи рублей» не содержит заранее известного номера нужной записи. Программе сначала нужно найти записи, которые подходят под признаки. Это поиск по условию.

Частота тоже меняет требования. Одни данные программа может спрашивать раз в день, другие — тысячи раз в минуту. При этом отдельно смотрят на чтение и запись: получить уже сохранённое значение и изменить данные — разная работа для хранилища. Если почти каждое обращение только читает карточку товара, нагрузка одна. Если обращения постоянно увеличивают счётчик просмотров, хранилищу приходится снова и снова принимать изменения.

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

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

Получается четыре вопроса.

  1. По чему ищут. По точному ключу — когда программа знает имя нужной записи или собирает его из номера. Или по условию, когда подходящие записи ещё нужно найти.
  2. Как часто. Раз в день или тысячи раз в минуту — и сколько из этого чтение, а сколько запись.
  3. Насколько свежим должен быть ответ. Можно ли показать то, что было минуту назад, или нужно ровно то, что есть сейчас.
  4. Сколько данных и какой они формы. Десять строк или миллиард, ровные записи или все разные.

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

Журнал из архива напечатает ячейка ниже. show_questions() — учебная функция курса: она просто выводит журнал таблицей. В настоящей работе такую сводку собирают по журналам серверов и графикам нагрузки.

Что значит «свежий ответ»

Допустим, содержимое корзины уже изменилось. Если программа сразу показывает новое содержимое, ответ свежий. Если некоторое время продолжает показывать предыдущее состояние, ответ отстаёт от последнего изменения.

Само отставание не всегда ошибка. В журнале просмотрам товара разрешено отстать на минуту, а карточке товара — на минуты. Для корзины и положения посылки требования строже: там ответ нужен за секунды.

Это похоже на табло с расписанием. Если информация обновляется чуть позже события, табло некоторое время показывает прежнее состояние. Вопрос для инженера звучит практично: сколько такого отставания ещё можно терпеть в конкретной задаче?

Сначала описывают обращения программы к данным, потом выбирают хранилище.
Ячейка вызывает подготовленную для урока функцию, которая печатает журнал обращений за последнюю минуту перед 18:00.
python

Читаем журнал

Буква N в журнале заменяет конкретный номер — покупателя, товара или посылки. Столбец «свежесть ответа» говорит, насколько ответ может отставать от последних изменений. «Нельзя потерять» — требование уже не к свежести, а к сохранности.

Начнём с корзины. Вопрос «что в корзине у покупателя N» звучит 1 200 раз в минуту. Номер покупателя уже известен, значит программа может сразу обратиться по точному ключу. Ответ нужен за секунды: если товар уже добавили или убрали, старое состояние быстро станет заметно.

С просмотрами работа другая. Вопрос «+1 к просмотрам товара N» звучит 4 800 раз в минуту. Здесь программа тоже знает номер товара заранее, но обращение меняет данные: счётчик нужно увеличить. При этом отображаемое число может отстать на минуту.

Карточку товара N читают 3 000 раз в минуту. И здесь номер товара известен заранее. Требование к свежести мягче: ответ может отстать на минуты.

Положение посылки спрашивают 900 раз в минуту. Номер посылки известен, поэтому снова подходит поиск по точному ключу. Но старое положение быстро вводит в заблуждение, поэтому ответ нужен за секунды.

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

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

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

Заказ оформляют 60 раз в минуту. По сравнению с тысячами чтений это редко, но здесь другое требование: запись нельзя потерять. Поэтому заказы живут в основной базе.

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

КВЕРИ: Форма данных тоже важна, но одной её мало. Сначала выясни, как программа будет эти данные читать и менять.

Ещё немного Python: словарь

Словарь хранит пары «вопрос → ответ» в фигурных скобках: слева от двоеточия вопрос, справа ответ, между парами — запятые. Строка вида answers = {…} даёт словарю имя — по нему проверка найдёт твои ответы.

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

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

Проверь себя
Программа получает данные о товарах в формате JSON — это текст с фигурными скобками, похожий на словарь Python. Как выбрать для них хранилище?
Практика: напиши код
Разметь пять вопросов магазина. Для каждого определи, ищет программа по точному ключу, когда номер известен заранее, или по условию, когда подходящие записи ещё нужно найти. Замени каждое None на слово «ключ» или «условие» — в кавычках, как в примере словаря выше.
python

ТерминыЧто значат новые слова

словообычными словами
шаблон доступакак программа обращается к данным: что ищет, как часто, насколько свежий ответ нужен
поиск по ключуточное имя нужной записи известно заранее — например, корзина покупателя 17
поиск по условиюизвестны только признаки — город, сумма; подходящие записи ещё надо найти
Главное из урока
  • Перед выбором хранилища выписывают вопросы к данным: по чему ищут, как часто, насколько свежим должен быть ответ, сколько данных и какой они формы.
  • В журнале магазина частые вопросы по точному ключу подошли хранилищу «ключ → значение», а подсчёт выручки — таблицам и SQL. Это примеры выбора, а не закон: SQL справляется и с частыми запросами. Заказы, которые нельзя потерять, держат там, где их сохранность лучше всего защищена, — в основной базе.
  • Сам формат ничего не решает: может спокойно лежать и в основной базе.

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

В журнале был столбец «свежесть ответа». Откуда вообще берётся несвежий ответ, если данные уже лежат в хранилище? Рядом с кэшем «Котомаркета» стоит его двойник. На нём и посмотрим.