Есть ли способ найти все различные значения для нескольких столбцов в одном запросе?

#sql #oracle #oracle9i

#sql #Oracle #oracle9i

Вопрос:

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

Справочная информация:

Версия базы данных: Oracle 9i

Версия Java: 1.4.2

Проблема

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

Например.:

 CREATE TABLE mytable
(
document_id integer,
filename varchar(255),
added_date date,
created_by varchar(32),
....
)
  

Из-за проблем с сетью / задержкой между веб-сервером и сервером базы данных я хотел бы свести к минимуму количество запросов, выполняемых к базе данных.

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

Для облегчения навигации на веб-странице мы предоставляем фильтры для выбора только документов, соответствующих определенному значению — например, созданных пользователем ‘joe bloggs’ или созданных ’01-01-2011′. Кроме того, предусмотрена подкачка, вызывающая вызов db для получения следующих 50 документов или чего-то еще.

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

Это занимает довольно много времени из-за задержки в сети и того факта, что это означает 5 дополнительных запросов.

Мой вопрос

Я хотел бы знать, есть ли способ получить эту же информацию всего за один запрос?

Например, есть ли способ получить различные результаты из этой таблицы в форме:

 DistinctValue    Type
01-01-2011       added_date
01-02-2011       added_date
01-03-2011       added_date
Joe Bloggs       created_by
AN Other         created_by
....             ...
  

Я предполагаю, что одна из проблем с вышесказанным заключается в том, что типы данных различаются по столбцам, поэтому dates и varchars не могут быть возвращены в столбце «DistinctValue».

Есть ли лучший / стандартный подход к этой проблеме?

Заранее большое спасибо.

Джей

Редактировать

Как я упоминал в комментарии ниже, я подумал о возможно более эффективном подходе к памяти / загрузке, который устраняет первоначальное требование объединения запросов —

Я полагаю, что другой способ, которым это могло бы сработать, — это вместо первоначального заполнения выпадающих списков заставить их реагировать на ввод текста пользователем, а затем отобразить раскрывающийся список в стиле «suggester» только с теми различными значениями, которые соответствуют введенному тексту. Я думаю, это означало бы а) сохранение отдельных запросов для разных значений, но б) выполнение запросов только по отдельности по мере необходимости и в) сокращение результирующего набора путем фильтрации уникальных значений в тексте пользователя.

Комментарии:

1. являются ли данные статическими или постоянно изменяющимися для этих документов? Изменяют ли конечные пользователи эти документы (или добавляют к ним)? или больше доступа только для чтения?

2. После того, как ваша система некоторое время будет работать, у вас будут сотни дат, я не знаю, сколько пользователей и загрузок документов. (предположительно, зависит от вашего приложения.) Таким образом, это станет очень длинным набором результатов. Рассматривали ли вы вместо этого какую-либо форму кэширования?

3. @tbone — данные, хранящиеся в документе, почти всегда будут статическими, но пользователи могут добавлять и удалять документы, когда захотят (и часто делают).

4. @APC — Я не рассматривал кэширование известных различных значений — доступная память ограничена, но мы планируем внедрить memcached в дальнейшем для многих наших запросов.

Ответ №1:

Этот запрос вернет результат, как вы описали выше:

 SELECT DocumentID As DocumentID, 'FileName' As AttributeType, FileName As DistinctValue
 FROM TableName
UNION
SELECT DocumentID, 'Added Date', Added_date FROM TableName
UNION
SELECT DocumentID, 'Created By', created_by FROM TableName
UNION
....
  

Если у вас есть привилегия, вы могли бы создать представление, используя этот SQL, и вы могли бы использовать его для своих запросов.

Комментарии:

1. Вы не можете смешивать типы данных в одних и тех же столбцах в ОБЪЕДИНЕНИИ, по крайней мере, не в Oracle. Во втором столбце тип DATE смешивается с типом VARCHAR2. Это привело бы к ошибке ORA-01790. Вы могли бы выполнить TO_CHAR в столбце date, чтобы обойти это.

2. @DCookie — Мы могли бы ожидать, что документы будут иметь временные метки. Таким образом, дополнительным преимуществом приведения к varchar является то, что мы теряем элемент time, тем самым уменьшая количество возвращаемых различных значений.

3. @DCookie, @APC — некоторые столбцы являются временными метками, где элемент time определенно необходим. Однако в настоящее время мы в любом случае форматируем эти даты / временные метки для отображения во внешнем интерфейсе, поэтому потенциально можем использовать строку формата с вызовом TO_CHAR .

4. @Leslie — спасибо за ваш ответ, я поиграю с этим и функцией TO_CHAR, упомянутой @DCookie, и посмотрю, смогу ли я чего-нибудь добиться. В противном случае я представляю другой способ, которым это могло бы сработать, — вместо первоначального заполнения выпадающих списков заставить их реагировать на ввод текста пользователем, а затем отобразить раскрывающийся список в стиле «suggester» только с теми различными значениями, которые соответствуют введенному тексту. Я думаю, это означало бы а) сохранение отдельных запросов для разных значений, но б) выполнение запросов только по отдельности по мере необходимости и в) сокращение результирующего набора путем фильтрации уникальных значений в тексте пользователя.

5. @DCookie — Я недостаточно внимательно изучил спецификации таблицы, спасибо за исправление

Ответ №2:

Из-за проблем с сетью / задержкой между веб-сервером и сервером базы данных я хотел бы свести к минимуму количество запросов, выполняемых к базе данных.

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

Возможно, вы захотите заглянуть в Lucene. Всякий раз, когда я вижу «минимизировать запросы к БД» в сочетании с «поиском документов», это то, о чем я думаю. Я использовал это с большим успехом, и его можно использовать в средах только для чтения или обновления. Ответ Oracle — Oracle Text, но (во всяком случае, для меня) его немного сложно настроить и использовать. Зависит от технических ресурсов и сильных сторон вашей компании.

В любом случае, это намного превосходит множество запросов к БД для каждого соединения.

Комментарии:

1. Вопрос OP заключается не в поиске самих документов, а в запросе таблицы, которая содержит метаданные о документах. Как бы Lucene — или любой другой индексатор текста — помог здесь?

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

3. @APC: Согласно вопросу: «хотел бы знать, есть ли способ получить эту же информацию всего в одном запросе?»… «есть ли лучший / стандартный подход к этой проблеме?». Мой ответ — да, лучший подход — использовать индексы lucene и запрашивать lucene.