SQL-запросы - попытаться избежать дублирования данных в наборе результатов? - PullRequest
3 голосов
/ 14 января 2012

Это вопрос, который меня интересовал уже довольно давно. Я попытаюсь объяснить с помощью примера, но это общий вопрос.

Скажем, у вас есть две таблицы:

  1. пользователей, которые содержат имя, фамилию, ... пользователя
  2. записей, которые содержат сообщения, написанные пользователем, с такими полями, как заголовок, текст, ...

Теперь предположим, что я хочу отобразить все сообщения, созданные за последние 24 часа. В этой таблице я хочу отобразить имя, фамилию ... пользователя, создавшего этот пост. Запрос, вероятно, будет выглядеть примерно так:

ВЫБРАТЬ ... ИЗ сообщений, пользователей ГДЕ posts.user_id = users.id И [последние 24 часа]

Теперь перейдем к моему вопросу. Поскольку весьма вероятно, что один пользователь создал несколько сообщений за последние 24 часа, мы в основном получаем его / ее имя, фамилию, ... снова и снова. Другими словами, набор результатов запроса выше содержит повторяющиеся данные (но не повторяющиеся строки).

Не лучше ли:

  1. ВЫБРАТЬ ... ИЗ сообщений, ГДЕ [последние 24 часа]
  2. ВЫБРАТЬ ... ОТ пользователей, где ИД ВХОДИТ (ВЫБРАТЬ ОТЛИЧИТЬ user_id ОТ ОТДЕЛОК ГДЕ [последние 24 часа])
  3. сопоставить результат первого запроса с результатом второго запроса на уровне приложения или в процедуре sql, чтобы узнать имя, фамилию, ... сообщения - это легко сделать, если идентификаторы (первичные ключи ) являются индексом / ключом некоторой хэш-карты, массива или аналогичных элементов.

Я понимаю, что это очень общий вопрос, но любые идеи приветствуются. Спасибо!

Ответы [ 3 ]

2 голосов
/ 14 января 2012

Любой метод должен работать, но вы нажмете на важную часть:

Сделайте это на уровне приложения.

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

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

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

Для вашего конкретного примера гораздо лучше сделать все это в одном запросе.

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

0 голосов
/ 14 января 2012

Лучшее решение зависит от количества строк в каждой таблице и количества сообщений на пользователя в день.

Если постов и пользователей относительно мало, то можно выбрать и посты, и пользователей за один раз.

Если существует несколько пользователей и много сообщений на пользователя, лучше использовать второй вариант, выбирая их отдельно. Сначала вы выбираете сообщения за последние 24 часа, а затем выбираете авторов следующим образом:

SELECT users.id, first_name, last_name
FROM users
LEFT JOIN posts ON users.id = user_id
WHERE [posts in the last 24 h]
0 голосов
/ 14 января 2012

Я думаю, что лучшим решением может быть выбор пользователя, который имеет сообщения за последние 24 часа, а затем выбор сообщений по идентификатору пользователя.

1. step:

SELECT DISTINCT id, first_name, last_name
FROM users INNER JOIN
posts ON posts.user_id = users.id
WHERE [last 24 hours]

2. step:

SELECT *
FROM posts
WHERE user_id = @userId AND [last 24 hours]

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...