Как реализовать независимую от ядра базы данных подкачку?

StackOverflow https://stackoverflow.com/questions/61750

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

Редактировать:
Я ищу SQL-решение, а не стороннюю библиотеку.

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

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

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

Дурацкая (читай глупая) идея, которая только что пришла мне в голову, заключалась бы в добавлении столбца страницы в таблицу, скажем, create table test (id int, name varchar, phone varchar, page int), а затем вы можете получить страницу 1 с помощью select * from таблица, где страница = 1.Но это означает необходимость добавления кода для поддержки этого столбца, что, опять же, может быть сделано только путем либо привлечения всей базы данных, либо использования специфичных для базы данных конструкций.Это помимо необходимости добавлять разные столбцы для каждого возможного порядка и многих других недостатков.

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

Действуйте как обычно:
Начните с внедрения его в соответствии со стандартом.А затем обработайте угловые случаи, т.е.СУБД, которые не реализуют стандарт.То, как обрабатывать угловые случаи, зависит от вашей среды разработки.

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

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

SubSonic может сделать это за вас, если вы терпимо относитесь к открытому исходному коду...http://subsonicproject.com/querying/webcast-using-paging/

Кроме этого, я знаю, что NHib делает то же самое

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

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

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

Если вам нужно независимое от СУБД решение raw SQL, боюсь, вам не повезло.Все поставщики делают это по-разному.

@Винко Врсалович,

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

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

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top