Выборки из одной базы данных без учета распределения - это данные из индексной базы;
Выборки из одной базы данных c учетом распределения - это данные из распределенной базы, но в её пределах, например, список альбомов пользователя;
Выборки из нескольких баз данных - это данные которые аггрегируются из нескольких хранилищ, например список фото для определенного тега;
Определим, какие данные будет выбирать наше приложение.
Независимые списки:
Список ТОПовых фото, с возможностью постраничного вывода (limit, offset);
Список последних фото, с возможностью постраничного вывода (limit, offset);
Зависимые списки:
Для пользователя:
Список альбомов пользователя, с возможностью сортировки и постраничного вывода (user_id, user_hash, order, limit, offset);
Список тегов пользователя (user_id, user_hash);
Список последних фото пользователя, с возможностью постраничного вывода (user_id, user_hash, limit, offset);
Для альбома:
Список фото альбома, с возможностью сортировки и постраничного вывода (album_id, user_hash, order, limit, offset);
Список тегов альбома (album_id, user_hash);
Для фото:
Список тегов фото (foto_id, user_hash);
Для тегов:
Список фото для тега, с возможностью постраничного вывода (tag_id, tag_hash, limit, offset);
Строковые данные:
Пользователь, (user_id + user_hash или login +? pass);
Альбом (album_id, user_hash);
Фото (foto_id, user_hash);
Фото + Альбом + Пользователь (foto_id, user_hash);
Тег - у нас уже есть процедура получения по контенту;
Независимые списки
У нас есть 2 таблицы: топовые и последние фото в индексной базе данных, из них выбираем только с учетом постраницного вывода.
Итак, для топовых фото:
При штатной работе серверов баз данных, у нас все бедет хорошо, но в случае если одно из хранилищ остановлено, то мы получим ошибку. В принципе, это нормально для данных, относящихся только к этому хранилищу, но в случае с выборками данных с нескольких серверов, мы все таки можем выбрать список пусть не полный. Это позволит нам не останавливать проект, а включить режим частичной работы. Хранимую процедуру для выборки последних фото так и сделаем:
В итоге, му можем получить не полный список последних фото, но мы его получим все равно. Можно, конечно, добирать список если не достает строк, но при этом у нас сильно пострадает постраничное разделение.
Зависимые списки
Данные по пользователям, альбомам и фото выбираются в пределах одного хранилища (ктоме выборки тегов, тогда еще используется индексная база), поэтому выборки относительно простые, можно даже не заострять на них внимание:
Отдельно рассмотрим выборки тегов для сущностей (пользователь, альбом, фото). В разделе структура распределенной DB, мы ввели несколько денормализованных связей (таблиц), теперь рассмотрим для чего они нам потребовались. Итак, у нас есть таблица fotos_tags в которой добавлены избыточные поля - album_id и user_id, по сути, для выборки тегов альбома или пользователя, этой таблицы будет достаточно, но, для этого нам потребуется применять DISTINCT, что бы получить уникальные теги в пределах условия, или GROUP BY, что бы получить уникальные теги в пределах условия и посчитать частоту их использования. Ясно, что применение этих директив уменьшит производительность, хотя и позволит нам избежать дополнительных денормализаций, но тут стоит посмотреть на приоритет и частоту использования задач этих данных, а приоритет таков - нужно быстро отдать данные, а изменения не так часты.
Решений несколько, рассмотрим два из них:
Отдельная таблица связей, с количественными показателями (для альбомов) - позволит нам двумя запросами получить нужные теги и частоту их использования. Такой связью просто управлять и обновлять, но в нашем случае, это запросы к двум базам: хранилищу, для получени списка tag_id и к индексной базе для получения тегов;
Отдельная поле у сущности, с количественными показателями (для пользователей) - позволит нам одним запросом получить нужные теги и частоту их использования. Такой связью управлять сложнее, как было видно из триггеров, так как мы работаем не со строками, а с массивом в поле, Но зато, список tag_id у нас есть у сущности;
В принципе, можно вообще уйти от запросов, как таковых, и хранить в отдельном поле сущности все данные от тегах, но в распределенном хранилище, у нас используется только tag_id и tag_hash, а контент тега не никогда передается, поэтому усложнять логику мне кажется не совсем целесообразно.
Итого получаем три вида хранимых процедур для выборки тегов, какой способ выбирать - оставляю на совести разработчика.
Выборка же фото по тегу - практически такая же, как выборки топовых и последних фото, за тем лишь исключением, что первоначальную выборку мы производим не из индексной базы, а из одной из баз хранилища.
Можно, конечно, сделать еще процедуру, в которую будем передавать контент тега, а не id и hash, но я не думаю, что для приложения это будет актуально.
Строковые данные
Строковые данные выбираются довольно просто, мы определяем хранилище, выбираем из него и отдаем приложению.
Единственно, что может понадобится не "чистая" строка из таблицы, а результат JOIN таблиц. Так, например, нам нужно взять строку фото, с данными о альбоме и пользователе. Сложности возникают только могут возникнуть только при выдаче результатов, так как нам прийдется проименовать каждое возвращаемое поле. Составной индекс для этого я бы не рекомендовал использовать так как его потом невозможно будет изменить без удаления зависимостей - хранимых процедур. Лучше создать пустую таблицу, её можно относительно спокойно менять, относительно - значит что при изменении запроса к хранилищу её потребуется изменить и наоборот.