Я должен составить 2 таблицы:
Журнал (10 миллионов строк с этими столбцами: идентификатор, заголовок, жанры, печать, цена)
Автор (180 миллионов строк с этими столбцами: идентификатор, имя, magazine_id)
. Каждый автор может записать на журнале ONLY ONE, и каждый журнал имеет больше авторов.
Таким образом, если я хочу знать всех авторов Моторного Журнала, я должен использовать этот запрос:
SELECT * FROM Author, Magazine WHERE ( Author.magazine_id = Magazine.id ) AND ( genres = 'Motors' )
То же относится к столбцу Printing и Price.
Для предотвращения этих соединений с таблицами миллионов строк я думавший использовать это представляю в виде таблицы:
Журнал (10 миллионов строк с этим столбцом: идентификатор, заголовок, жанры, печать, цена)
Автор (180 миллионов строк с этим столбцом: идентификатор, имя, magazine_id, жанры, печать, цена)
. и этот запрос:
SELECT * FROM Author WHERE genres = 'Motors'
Действительно ли это - хороший подход?
Я хочу заставить его работать быстрее
Я могу использовать Postgresql или Mysql.
Нет, я не думаю, что дублирование информации, как вы описываете, является хорошим дизайном для реляционной базы данных.
Если вы измените жанр или цену данного журнала, вам придется не забыть изменить это во всех авторских строках, где информация дублируется. А если вы иногда забываете, то в итоге получаете аномалии в данных. Откуда вы можете знать, какой из них правильный?
Это одно из преимуществ нормализации реляционных баз данных - представлять информацию с минимальной избыточностью, чтобы не возникало аномалий.
Чтобы сделать работу быстрее, а именно это, я думаю, вы и пытаетесь сделать, вам следует научиться использовать индексы, особенно охватывающие индексы.
Это хороший подход?
SELECT * FROM Author, Magazine WHERE Author.magazine_id = Magazine.id AND genres = 'Motors' {{1 }}
Вы должны сделать это:
SELECT * FROM Author
JOIN Magazine ON Author.id = Magazine.id
WHERE genres = 'Motors'
Это должно быть быстро. Если он слишком медленный, убедитесь, что у вас есть все соответствующие индексы, включая индексы первичного ключа в полях id для всех таблиц и индекс для жанров
.
Вам также следует перечислить нужные столбцы, а не возвращать их все. Обратите внимание, что этот запрос потенциально может вернуть миллионы строк. Вы уверены, что хотите получить их все? Я бы рассмотрел решение, использующее разбиение на страницы и выборку только первых 50, пока пользователь не запросит следующую страницу.
Если вам нужно получить только авторов журнала (а не информацию о журнале), вы можете использовать EXISTS. Некоторые говорят, что EXISTS быстрее, чем JOIN, потому что EXISTS останавливает поиск после первого попадания. Затем вы должны использовать:
SELECT *
FROM Author
WHERE EXISTS (SELECT 1 FROM Magazine WHERE genres = 'Motor' AND Author.id = Magazine.id)
Кроме того, как упоминалось ранее, указание столбцов ускорит процесс.
Вам не нужно выполнять JOIN, и даже тогда ваш основной запрос неверен. Вы хотели сказать:
SELECT name FROM author
WHERE magazine_id in
(SELECT id FROM magazine WHERE genres = 'motors')
Есть много разных способов управлять такими огромными хранилищами данных. Если вы приведете пример того, что вы хотите получить из этих данных, люди могут предложить эффективные способы сделать это.