Я искал по сети, и я понятия не имею.
- Предположим, вам нужно создать панель управления в области администрирования вашего приложения Rails, и вы хотите иметь количество подписчиков в день.
- Предположим, что вы используете SQLite3 для разработки, MySQL для производства (довольно стандартная настройка)
В принципе, существует два варианта:
1) Извлеките все строки из базы данных с помощью Subscriber.all
и суммируйте по дням в приложении Rails с помощью Enumerable.group_by
:
@subscribers = Subscriber.all
@subscriptions_per_day = @subscribers.group_by { |s| s.created_at.beginning_of_day }
Я думаю, что это действительно плохая идея. Получение всех строк из базы данных может быть приемлемым для небольшого приложения, но оно вообще не будет масштабироваться. Агрегирование базы данных и функции даты на помощь!
2) Запустить SQL-запрос в базе данных с помощью функций агрегации и даты:
Subscriber.select('STRFTIME("%Y-%m-%d", created_at) AS day, COUNT(*) AS subscriptions').group('day')
который будет запущен в этом SQL-запросе:
SELECT STRFTIME("%Y-%m-%d", created_at) AS day, COUNT(*) AS subscriptions
FROM subscribers
GROUP BY day
Гораздо лучше. Теперь агрегаты выполняются в базе данных, которая оптимизирована для такого рода задач, и только одна строка в день возвращается из базы данных в приложение Rails.
... но подождите... теперь приложение должно появиться в моей программе env, которая использует MySQL!
Замените STRFTIME()
на DATE_FORMAT()
.
Что, если завтра я перейду на PostgreSQL?
Замените DATE_FORMAT()
на DATE_TRUNC()
.
Мне нравится разрабатывать SQLite. Простой и легкий. Мне также нравится идея, что Rails является агностиком базы данных. Но почему Rails не предоставляет способ переводить SQL-функции, которые делают то же самое, но имеют разные синтаксисы в каждой RDBMS (эта разница действительно глупа, но эй, слишком поздно, чтобы жаловаться это)?
Я не могу поверить, что я нашел так мало ответов в Интернете для такой базовой функции приложения Rails: подсчитайте подписку в день, месяц или год.
Скажи мне, что я чего-то не хватает:)
ИЗМЕНИТЬ
Прошло несколько лет с тех пор, как я опубликовал этот вопрос. Опыт показал, что я должен использовать ту же БД для dev и prod. Поэтому теперь я считаю, что агностическое требование базы данных не имеет значения.
Dev/prod четность FTW.