#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.