Вопрос о соединениях и таблице с миллионами строк

Я должен составить 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.

6
задан xRobot 1 May 2010 в 20:57
поделиться

5 ответов

Нет, я не думаю, что дублирование информации, как вы описываете, является хорошим дизайном для реляционной базы данных.

Если вы измените жанр или цену данного журнала, вам придется не забыть изменить это во всех авторских строках, где информация дублируется. А если вы иногда забываете, то в итоге получаете аномалии в данных. Откуда вы можете знать, какой из них правильный?

Это одно из преимуществ нормализации реляционных баз данных - представлять информацию с минимальной избыточностью, чтобы не возникало аномалий.

Чтобы сделать работу быстрее, а именно это, я думаю, вы и пытаетесь сделать, вам следует научиться использовать индексы, особенно охватывающие индексы.

6
ответ дан 8 December 2019 в 17:19
поделиться

Это хороший подход?

  1. Плюсы этого подхода перевешивают минусы. Минусы денормализации (это то, что вы предлагаете) включают:
    • Вам необходимо поддерживать правильные данные о жанре, печати и ценах для каждого журнала в таблице авторов каждый раз, когда они меняются на журнал_id. Это дорого.
    • Очевидно, вы тратите НАМНОГО больше места для хранения, повторяя данные каждого журнала в среднем 18 раз (это правильное предположение?). {{1 }}
    • Любой другой выбор / обслуживание таблицы авторов становится медленнее / дороже.
  2. Ваш запрос не работает. Вместо этого он должен быть
     
    SELECT * FROM Author, Magazine 
    WHERE Author.magazine_id = Magazine.id AND genres = 'Motors' {{1 }} 
  3. Чтобы решить вашу проблему, убедитесь, что у вас есть указатель по журнальной таблице по жанрам и указатель по magazine_id в таблице авторов
2
ответ дан 8 December 2019 в 17:19
поделиться

Вы должны сделать это:

SELECT * FROM Author
JOIN Magazine ON Author.id = Magazine.id
WHERE genres = 'Motors'

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

Вам также следует перечислить нужные столбцы, а не возвращать их все. Обратите внимание, что этот запрос потенциально может вернуть миллионы строк. Вы уверены, что хотите получить их все? Я бы рассмотрел решение, использующее разбиение на страницы и выборку только первых 50, пока пользователь не запросит следующую страницу.

1
ответ дан 8 December 2019 в 17:19
поделиться

Если вам нужно получить только авторов журнала (а не информацию о журнале), вы можете использовать EXISTS. Некоторые говорят, что EXISTS быстрее, чем JOIN, потому что EXISTS останавливает поиск после первого попадания. Затем вы должны использовать:

SELECT *
FROM Author
WHERE EXISTS (SELECT 1 FROM Magazine WHERE genres = 'Motor' AND Author.id = Magazine.id)

Кроме того, как упоминалось ранее, указание столбцов ускорит процесс.

4
ответ дан 8 December 2019 в 17:19
поделиться

Вам не нужно выполнять JOIN, и даже тогда ваш основной запрос неверен. Вы хотели сказать:

SELECT name FROM author
WHERE magazine_id in 
    (SELECT id FROM magazine WHERE genres = 'motors')

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

1
ответ дан 8 December 2019 в 17:19
поделиться
Другие вопросы по тегам:

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