2008-09-15 3 views
7

Задача: реализовать подкачку записей базы данных, подходящую для разных СУБД. Метод должен работать на основные двигатели - MSSQL2000 +, Oracle, MySql и т. Д.Как реализовать независимый поисковый движок базы данных?

Пожалуйста, не публикуйте конкретные решения для РСУБД, я знаю, как реализовать это для большинства современных двигателей баз данных. Я ищу универсальное решение. В настоящее время мне приходят в голову только временные решения, основанные на таблицах.

EDIT:
Я ищу для решения SQL, а не третья библиотека партии.

ответ

5

Было бы универсальное решение, если бы спецификации SQL включали пейджинг в качестве стандарта. Требование к тому, чтобы язык RDBMS назывался языком РСУБД, не включает поддержку подкачки.

Многие продукты базы данных поддерживают SQL с проприетарными расширениями на стандартный язык. Некоторые из них поддерживают подкачку, такую ​​как MySQL, с предложением limit, Rowid с Oracle; каждый обрабатывается по-разному. Другие СУБД должны будут добавить поле под названием rowid или что-то в этом роде.

Я не думаю, что у вас может быть универсальное решение (любой может доказать, что я здесь не прав, открыта для обсуждения), если он не встроен в систему базы данных, или, если нет компании, говорят, что ABC использует Oracle, MySQL, SQL Server, и они решили, что все различные системы баз данных обеспечивают собственную реализацию пейджинга своими разработчиками баз данных, предоставляя универсальный интерфейс для кода, который его использует.

0

JPA позволяет делать это с классом запросов:

Query q = ...; 
q.setFirstResult (0); 
q.setMaxResults (10); 

дает вам 10 результатов в результирующем наборе.

Если вы хотите независимое сырое SQL-решение СУБД, я боюсь, что вам не повезло. Все производители делают это по-другому.

3

Самый естественный и эффективный способ обработки подкачки - использовать конструкцию LIMIT/OFFSET (TOP in Sybase world). Независимый от DB способ должен был бы знать, на каком движке он работает, и применить правильную конструкцию SQL.

По крайней мере, так я видел это в коде DB независимых библиотек. Вы можете абстрагироваться от логики подкачки, как только вы получите данные из движка с конкретным запросом.

Если вы действительно ищете одно решение для SQL-предложений, не могли бы вы показать, что вы имеете в виду? Как и SQL для решения temp table. Это, вероятно, даст вам более актуальные предложения.

EDIT:

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

Итак, теперь вопрос будет больше похож на «Есть ли способ реализовать подкачку без использования LIMIT/OFFSET или эквивалентного?» и я догадываюсь, что ответ «Санли, нет». Вы можете попробовать использовать курсоры, но вы также будете жертвовать предложениями и характеристиками конкретной базы данных.

Идея wacko (читать глупо), которая только что пришла мне в голову, заключалась бы в том, чтобы добавить столбец страницы в таблицу, например создать табличный тест (id int, имя varchar, телефон varchar, page int), а затем вы можете получить страницу 1 с выбором * из таблицы, где page = 1. Но это означает, что вам нужно добавить код для поддержки этого столбца, что снова может быть сделано только путем приведения всей базы данных или использования конкретных баз данных. Это, кроме того, нужно добавить другой столбец для каждого возможного заказа и многих других недостатков.

Я не могу предоставить доказательства, но я действительно думаю, что вы просто не можете сделать это здорово.

1

Продолжить, как обычно:
Начните с реализации его в соответствии со стандартом. Затем обработайте угловые шкафы, т. Е. СУБД, которые не реализуют стандарт. Как обрабатывать угловые случаи зависит от вашей среды разработки.

Вы ищете универсальный подход. Самый универсальный способ разбиения на страницы - использование курсоров, но разбиение на страницы на основе курсора не очень хорошо сочетается с не-stateful environment, как веб-приложение.

Я написал о стандарте и реализации (в том числе курсоры) здесь: http://troels.arvin.dk/db/rdbms/#select-limit-offset

+0

Troels Arvin, довольно полезная страница, спасибо! – aku 2008-09-15 07:42:46

0

@Vinko Vrsalovic,

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

Вот одно глупое решение, основанное на временной таблице. Это явно плохо, поэтому нет необходимости комментировать его.

N - upper bound 
M - lower bound 

create #temp (Id int identity, originalId int) 

insert into #temp(originalId) 
select top N KeyColumn from MyTable 
where ... 

select MyTable.* from MyTable 
join #temp t on t.originalId = MyTable.KeyColumn 
where Id between M and M 
order by Id asc 

drop #temp 
+0

Проблема с этим подходом заключается в том, что хотя IDENTITY является стандартным SQL, он недоступен во всех базах данных. Кроме того, SELECT TOP не является стандартным SQL и не является широко распространенным. Кроме того, копирование данных может быть намного медленнее по сравнению с методами, которые не используют временную таблицу. – 2008-09-15 08:01:03

+0

Возможно, можно использовать представление вместо создания временной таблицы? Можете ли вы создать представление, в котором один из столбцов является столбцом идентификации? – 2008-09-15 09:00:52

Смежные вопросы