2016-08-24 86 views
0

我有created(timestamptz)屬性表。現在,我需要根據時間戳創建分頁,因爲當用戶正在觀看第一頁時,可以將新項目提交到此表中,這會使數據不一致,以防將分頁使用OFFSETPostgres:使用時間戳分頁

所以,問題是:我應該保留created類型爲timestamptz或者最好將其轉換爲整數(unix,例如1472031802812)。如果是這樣,是否有缺點?另外,atm我有now()作爲created的默認值 - 是否有替代函數來創建unix時間戳?

+1

將datetime保留爲整數時間戳沒有任何優勢。其實這隻會讓事情變得複雜。例如想象一個查詢「從月初開始給我所有的東西」。不要。 'timestamp'正是你需要的,使用它。 – freakish

+0

@freakish,謝謝!如果我有整數,我只會說'SELECT * FROM table_name WHERE created stkvtflw

+0

我不確定我的理解。 'timestampz'不支持'<'運算符。你爲什麼要轉換任何東西?我沒有看到這一點。 – freakish

回答

1

讓我改寫評論的東西到我的答案。您只想使用timestamp類型而不是integer,因爲這正是它的設計目的。在時間戳整數和timestamp對象之間進行手動轉換隻是一個痛苦,你什麼也得不到。最終你會需要它來處理更復雜的基於日期時間的查詢。

回答關於分頁的問題。你只需做一個查詢

SELECT * 
FROM table_name 
WHERE created < lastTimestamp 
ORDER BY created DESC 
LIMIT 30 

如果是第一次查詢然後設置說lastTimestamp = '3000-01-01'。否則,你設置lastTimestamp = last_query.last_row.created


優化

注意,如果該表是先大後ORDER BY created DESC可能不是有效的(特別是如果有不同的範圍稱爲平行)。在這種情況下,你可以使用移動的「時間窗口」,例如:

SELECT * 
FROM table_name 
WHERE 
    created < lastTimestamp 
    AND created >= lastTimestamp - interval '1 day' 

1 day間隔arbitrarly採摘(調整它以您的需求)。您也可以在應用程序中排序結果。

如果結果不爲空,則進行更新(在您的應用程序)

lastTimestamp = last_query.last_row.created 

(假設你已經做了排序,否則你拿min(last_query.row.created)

如果結果是空的,那麼你重複查詢與lastTimestamp = lastTimestamp - interval '1 day'直到你拿東西。如果lastTimestamp變爲低電平,即當它低於表中的任何其他時間戳(必須預取)時,您也必須停止。

所有這一切是在某種假設爲插入物:

  1. new_row.created >= any_row.created
  2. new_row.created ~ current_time
  3. new_row.created分佈是或多或少均勻

假設1確保了分頁結果在一致的數據中,假設2僅僅用於默認日期3000-01-01。假設3是要確保當你不得不發出很多空查詢時,你沒有很大的空白。

+0

謝謝!一個問題:如果我將創建基於'created'的索引,'DESC'仍然不會有效嗎? – stkvtflw

+0

@stkvtflw如果我們談論數億行,那麼是的。但在你選擇任何戰略基準之前。 – freakish

+0

對不起,再次打擾你,但我還有一個非常最後一個問題)如何將unix時間戳與MILLISECONDS轉換爲postgres-acceptable-timestamptz? – stkvtflw

0

你的意思是這樣的嗎?

select extract(epoch from now())::integer as unix_time 
+0

看起來很複雜)我的意思是,如果我有整數,我只會說'SELECT * FROM table_name WHERE created stkvtflw