2009-04-22 85 views
4

我想在瀏覽器/多個頁面上顯示100000條記錄,而對內存影響最小。即每頁100個記錄。 我想來回移動頁面。我的疑惑是
1.我可以保留內存中的所有記錄嗎?這是一個好主意嗎?在瀏覽器/多個頁面上顯示100000條記錄

2)我可以做永久頁面的數據庫連接/查詢嗎?如果是的話如何寫一個查詢?

任何人都可以請幫我..

回答

8

它一般不會在內存中保留如此多的記錄是個好主意。如果應用程序被多個用戶同時訪問,則內存影響將非常大。

我不知道是什麼DBMS你使用的,但在MySQL和其他幾個人,你可以依靠DB用於分頁與查詢,如:

SELECT * FROM MyTable 
LIMIT 0, 100 

限制後的第一個號碼是偏移量(它將跳過多少記錄),第二個是它將獲取的記錄數。

請記住,這是SQL在每個數據庫上都沒有相同的語法(有些甚至不支持它)。

0

在許多SQL語言中,您有LIMIT(mysql,...)或OFFSET(mssql)的概念。 您可以使用這種東西來限制每頁行數

1

這不是一個好主意,因爲您正在使瀏覽器可執行文件保留所有這些。

當我有這樣的事情來使用JavaScript來渲染頁面,並只是做了一個Ajax調用來獲取下一頁。顯示下一張表格時略有延遲,因爲您抓取它,但用戶習慣於此。

如果您顯示100條記錄/頁面,請使用json從服務器傳遞數據,因爲javascript可以快速解析數據,然後使用innerHTML來放置html,因爲DOM在渲染表格時速度較慢。

+0

U爲每個頁面顯示都建立了一個數據庫連接? – Tony 2009-04-22 12:26:33

3

我不會在內存中保存數據(無論是在瀏覽器中還是在服務應用程序中)。相反,我會使用SQL翻閱結果。

如何做到這一點可以是數據庫特定的。有關MySql中的一個示例,請參閱here。其他數據庫將存在機制。

0

取決於數據。如果你緩存的話,100k int可能不會太糟糕。

T-SQL SET @@ ROWCOUNT = 100來限制返回的記錄數量。

但要做到這一點,並返回總頁數,您需要更高級的分頁SPROC。

這是一個非常熱門的話題,有很多方法可以做到這一點。

這裏是一個老的存儲過程的樣本,我寫

CREATE PROCEDURE Objects_GetPaged 
(
    @sort VARCHAR(255), 
    @Page INT, 
    @RecsPerPage INT, 
    @Total INT OUTPUT 
) 
AS 
SET NOCOUNT ON 

--Create a temporary table 
CREATE TABLE #TempItems 
(
    id INT IDENTITY, 
    memberid int 
) 

INSERT INTO #TempItems (memberid) 
SELECT Objects.id 
FROM Objects 
ORDER BY CASE @sort WHEN 'Alphabetical' THEN Objects.UserName ELSE NULL END ASC, 
     CASE @sort WHEN 'Created'  THEN Objects.Created ELSE NULL END DESC, 
     CASE @sort WHEN 'LastLogin' THEN Objects.LastLogin ELSE NULL END DESC 


SELECT @Total=COUNT(*) FROM #TempItems 

-- Find out the first and last record we want 
DECLARE @FirstRec int, @LastRec int 
SELECT @FirstRec = (@Page - 1) * @RecsPerPage 
SELECT @LastRec = (@Page * @RecsPerPage + 1) 


SELECT * 
FROM #TempItems 
INNER JOIN Objects ON(Objects.id = #TempItems.id) 
WHERE #TempItems.ID > @FirstRec AND #TempItems.ID < @LastRec 
ORDER BY #TempItems.Id 
2

1)不,在內存中的所有記錄那種違背了數據庫的點。看看有一個可滾動的結果集,這樣你就可以獲得你想要的功能,而無需使用SQL。您還可以調整一次提取多少個記錄,以便不會加載比您需要的記錄更多的記錄。

2)DB連接創建和銷燬,但任何嚴重的系統池連接,從而對性能的影響將不會很明顯昂貴。

如果你想獲得更多的花哨,你可以用網頁乾脆做掉,只是加載更多的記錄通過列表中的用戶滾動。

1

正如其他人在此提到的,將大量結果存儲在內存中並不是一個好主意。查詢每個頁面的結果肯定是更好的方法。要做到這一點,你有兩個選擇。一種方法是使用DBMS提供的數據庫特定功能來針對查詢結果的特定子部分。另一種方法是使用JDBC提供的通用方法來實現相同的效果。這樣可以使你的代碼從被捆綁到一個特定的數據庫:

// get a ResultSet from some query 
ResultSet results = ... 
if (count > 0) { 
    results.setFetchSize(count + 1); 
    results.setFetchDirection(ResultSet.FETCH_FORWARD); 
    results.absolute(count * beginIndex); 
} 
for (int rowNumber = 0; results.next(); ++rowNumber) { 
    if (count > 0 && rowNumber > count) { 
     break; 
    } 
// process the ResultSet below 
... 
} 

使用像Spring JDBC或Hibernate的庫可以更輕鬆地進行。

0

我會建議您選擇使用CachedRowSet。

CachedRowSet對象是用於在存儲器緩存其行數據,這使得它可以不總是被連接到它的數據源進行操作的行的容器。

CachedRowSet對象是一個斷開連接的行集,這意味着它利用到其數據源只簡單的連接。它在讀取數據時連接到其數據源,以便使用行填充自己,並在將更改傳播回其基礎數據源時再次進行填充。

因爲在存儲器CachedRowSet對象存儲數據時,數據的,它可以包含在任一週時間量是由可用的內存量來確定。爲了解決這個限制,一個CachedRowSet對象可以從一個稱爲頁面的數據塊中的ResultSet對象中檢索數據。爲了利用這種機制,應用程序使用setPageSize方法設置要包含在頁面中的行數。換句話說,如果頁面大小設置爲5,則一次將從數據源中獲取五行數據塊。應用程序還可以選擇設置一次可以獲取的最大行數。如果最大行數設置爲零,或者沒有設置最大行數,則可以一次獲取的行數沒有限制。

屬性已被設置後,CachedRowSet對象必須使用任一方法populate或方法執行數據填充。以下幾行代碼演示瞭如何使用方法填充。請注意,此版本的方法接受兩個參數,即ResultSet句柄和ResultSet對象中用於開始檢索行的行。

CachedRowSet crs = new CachedRowSetImpl(); 
crs.setMaxRows(20); 
crs.setPageSize(4); 
crs.populate(rsHandle, 10); 

當此代碼運行時,crs將從第十行開始填充rsHandle中的四行。

在類似的路徑上,您可以構建策略以在JSP上分頁數據等等。

相關問題