2008-09-15 5 views
7

태스크 : 다른 RDBMS에 적합한 데이터베이스 레코드의 페이징을 구현하십시오. 메서드는 주류 엔진 - MSSQL2000 +, Oracle, MySql 등에서 작동해야합니다.데이터베이스 엔진 독립적 페이징을 구현하는 방법은 무엇입니까?

RDBMS 특정 솔루션을 게시하지 마십시오. 대부분의 최신 데이터베이스 엔진에서이를 구현하는 방법을 알고 있습니다. 나는 보편적 인 해결책을 찾고있다. 임시 테이블 기반 솔루션 만이 지금 내 마음에 온다.

편집 :
내가 SQL 솔루션을 찾고 있어요없는 제 3 자 라이브러리입니다.

답변

5

SQL 사양에 페이징을 표준으로 포함시킨 경우 보편적 인 솔루션이있었습니다. 모든 RDBMS 언어에 대해 RDBMS 언어라고하는 요구 사항에는 페이징 지원도 포함되지 않습니다.

많은 데이터베이스 제품은 표준 언어에 대한 독점적 인 확장을 통해 SQL을 지원합니다. 그들 중 일부는 한계 조항과 함께 MySQL과 같은 페이징을 지원합니다. 각각 다르게 처리됩니다. 다른 DBMS에서는 rowid라는 필드를 추가해야합니다.

데이터베이스 시스템 자체에 내장되어 있지 않거나 오라클, MySQL 및 기타 다른 언어를 사용하는 ABC가 없다면 누구나 자유롭게 문제를 풀 수 있습니다. SQL Server를 사용하고 있으며 다양한 데이터베이스 시스템이 데이터베이스 개발자가 자체 페이징 구현을 제공하여이를 사용하는 코드에 범용 인터페이스를 제공하기로 결정했습니다.

+0

그래, 다른 해결책을 시도했지만 더 많거나 적은 휴대용 버전을 만드는 것은 불가능한 것 같습니다. – aku

0

JPA는 쿼리 클래스와 함께 할 수 있습니다 알고 :

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

결과 세트의 처음 10 개 결과를 제공합니다.

DBMS 독립 원시 SQL 솔루션을 원한다면 운이 나쁘다고 생각합니다. 모든 공급 업체가 다르게합니다.

3

페이징을 수행하는 가장 자연스럽고 효율적인 방법은 LIMIT/OFFSET (Sybase의 TOP에서) 구조를 사용하는 것입니다. DB 독립적 인 방법은 실행중인 엔진을 알고 적절한 SQL 구문을 적용해야합니다.

적어도 이것이 DB 독립적 라이브러리의 코드에서 수행 된 방식입니다. 특정 쿼리를 사용하여 엔진에서 데이터를 가져 오면 페이징 로직을 추상화 할 수 있습니다.

하나의 SQL 문장 솔루션을 정말로 찾고 있다면 마음에 가지고있는 것을 보여줄 수 있습니까? temp 테이블 솔루션 용 SQL과 같습니다. 아마도 더 관련성 높은 제안을 얻을 수 있습니다.

편집 :

은 내가 임시 테이블 함께 할 수있는 방법을 볼 수 없습니다와 엔진 특정 구문을 사용할 수 있기 때문에 당신이 생각하고 있었는지 알고 싶었다. 이 예제에서 특정 구문을 사용했습니다. 필자는 여전히 (구현 된) 표준 SQL로 데이터베이스에서 페이징을 구현하는 방법을 보지 못합니다. 전체 테이블을 표준 SQL 및 응용 프로그램의 페이지로 가져올 수는 있지만 분명히 바보입니다.

이제 "LIMIT/OFFSET 또는 동급을 사용하지 않고 페이징을 구현하는 방법이 있습니까?" 나는 그 대답이 "Sanely, no"라고 생각한다. 당신은 커서를 사용하여 시도 할 수 있지만 당신은 데이터베이스 특정 문장/행동뿐만 아니라 먹이에 빠지게됩니다.

방금 ​​나에게 발생한 wacko (바보 읽기) 아이디어는 create table test (ID int, name varchar, phone varchar, page int)와 같은 페이지 열을 추가 한 다음 페이지를 가져 오는 것입니다. 1 select * with page from page = 1 그러나 이는 해당 열을 유지 관리하는 코드를 추가해야한다는 것을 의미합니다. 다시 전체 데이터베이스를 가져 오거나 데이터베이스 특정 구문을 사용하여 수행 할 수 있습니다. 그것은 가능한 각각의 주문과 다른 많은 결점마다 다른 칼럼을 추가해야하는 것 외에도.

나는 증거를 제공 할 수는 없지만, 나는 정말로 당신이 단지 그것을 위생적으로 할 수 없다고 생각한다.

1

계속 진행 :
표준에 따라 구현하여 시작하십시오. 그런 다음 표준을 구현하지 않는 DBMSes 인 경우를 처리합니다. 코너 케이스를 처리하는 방법은 개발 환경에 따라 다릅니다.

"보편적 인"접근 방식을 찾고 있습니다. 페이지를 매기는 가장 보편적 인 방법은 커서를 사용하는 것입니다. 그러나 커서 기반 페이지 매김은 웹 애플리케이션과 같은 비 상태 유지 환경에 적합하지 않습니다. 여기

나는 표준 (커서 포함) 구현에 대해 서면으로 작성했습니다 : 나는 질문에 쓴 http://troels.arvin.dk/db/rdbms/#select-limit-offset

+0

Troels Arvin, 매우 유용한 페이지입니다. 감사합니다. – aku

0

@Vinko Vrsalovic,

내가 가장 데시벨에서 작업을 수행하는 방법을 알고있다. 나는 보편적 인 해결책을 찾거나 그것이 존재하지 않는다는 증거를 얻으 려합니다.

여기 임시 테이블을 기반으로 한 바보 같은 해결책이 있습니다. 그것은 명백하게 나쁘다. 그래서 그것에 대해 말할 필요가 없다.

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이 아니며 널리 구현되지도 않습니다. 그 외에도 임시 테이블을 사용하지 않는 방법과 비교하여 데이터 복사가 훨씬 느린 작업 일 수 있습니다. –

+0

아마도 임시 테이블을 만드는 대신보기가 적용될 수 있습니까? 열 중 하나가 ID 열인보기를 만들 수 있습니까? –

+0

@ 1800 INFORMATION, 예제를 보여줄 수 있습니까 – aku

관련 문제