Выборка из множественных SQL таблиц одинаковой структуры для одной сущности

Начну несколько издалека. Предположим, у нас есть таблица (допустим mySQL) следующего вида:

CREATE TABLE `table` (
`id` int(11) unsigned NOT NULL,
`lang` tinyint(3) unsigned NOT NULL,
`data` text NOT NULL,
PRIMARY KEY (`id`,`lang`)
) ENGINE=InnoDB


В таблице хранятся данных для объекта с ID = `id` на нескольких языках, поэтому PRIMARY KEY = (id, lang). Типичный use case для этой таблицы: необходимо получить данные data для объекта с id = 1 желательно на языке 1, если его нет — на языке 2, иначе пофигу на каком, лишь бы был.

Такая задача решается достаточно просто:

SELECT * FROM `table` WHERE `id` = 1
ORDER BY
CASE WHEN `lang` = 1 THEN 1
WHEN `lang` = 2 THEN 2
ELSE 3
END ASC
LIMIT 1


Выборка получается достаточно быстрая и используя только PRIMARY ключ и сортировку.

Вопрос №1: как сделать такую выборку не для одного, а для N объектов сразу, не прибегая к subquery:

SELECT (подзапрос для одного объекта) FROM (запрос, выбирающий ID объектов)

Теперь представим ситуацию, что объектов этих — 1 000 000, плюс языков к каждой из них — ещё по 20. Берем и разбиваем одну таблицу на несколько с точно такими же структурами. Объекты распределятся по таблицам с помощью примитивной хэш-функции вида (id % N == 0).

Вопрос №2: Задача всё та же. Как теперь получить такую выборку? Думаю, что ответ на этот вопрос будет прямо вытекать из вопроса №1 :)

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

Что-то мне подсказывает, что должны быть более элегантные способы решения такой задачи :/

Заранее всем спасибо за предложенные варианты и обсуждения! ;)
  • Вопрос задан
  • 4793 просмотра
Пригласить эксперта
Ответы на вопрос 1
Colwin
@Colwin
Ведущий Java-разработчик
Необходимо понять, каким образом задаются эти самые N объектов.
Если о характере выборки ID для этих объектов ничего нельзя сказать, то на вопрос 1 кроме предложенного варианта с подзапросом вряд ли что-то можно придумать.

Если я правильно понимаю задачу, результат первого вопроса будет выглядеть примерно так:

select *
from `table`
where id in (
    <подзапрос или список для выбора id>
)
order by
    case when lang = 1 then 1
        when lang = 2 then 2
        else 3
    end asc


А вот по поводу второго… Если есть подобного рода запросы, может быть, оптимальнее разбивать не по id, а по языкам?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы