Postgresql

在 Postgres 中生成數百萬個序列(使用 Redis)

  • April 15, 2020

我正在創建一個聊天應用程序,我會將所有對話和使用者的聊天消息保存在一個分區(在 convo ids 上)的 BRIN 索引表中。當我的伺服器想要儲存新消息時,它必須知道每個對話的最後一條消息的序列號。可能會有很多對話,那麼為數據庫中的每個對話動態生成一個序列(CREATE SEQUENCE 序列)可以嗎?

我將使用帶有 Nodejs 網路伺服器集群和 REDIS 實例的數據庫。從語義上講,redis 位於 nodejs 和 Postgres db 之間。我的第二個想法是代替序列,我將創建一個表來保存每個 convo(兩列)的計數器,將計數器載入到 redis 中,並在聊天時鎖定行,在那裡遞增並定期寫回。

哪個更好,這些都好嗎?謝謝!

編輯

消息表是基於 convo id 和消息號索引的多列 BRIN。並且兩列沒有pk,也沒有唯一約束。可能存在差距,甚至可能存在重複(由於 redis INCR 的原子性,這不太可能,因為它將是唯一的實例)(另一個重要點)

我必須詳細說明。我收到兩個回复,告訴我只需為數據庫中的每條消息製作一個序列。問題在於布林指數的長期有效性。這就是我在問題中寫它的原因,因為它很重要。如果你不知道 brin 指數是如何工作的,請查一下。本質上它是一個範圍索引。現在,如果您對所有消息進行一個序列,您會看到會發生什麼。對於 brin,消息編號/id 不會添加任何資訊,因為隨著時間的推移,所有對話的所有消息 id 將介於一個相對較小的數字和最後一個序列值之間。我認為那會大大降低選擇速度。這是聊天應用程序。我將不得不在登錄時查詢未發送的消息。並且不要告訴我使用 btree 甚至不要回答謝謝:D

我曾考慮過 UUID,但出於與上述相同的原因,這不會有幫助。

編輯 2

我現在明白生成序列是一個壞主意。所以剩下的是第二個選項,或者可能是一個序列建議,以防您爭論它對查詢性能的影響。

TL; 博士

您應該只對所有對話使用一個序列。– a_horse_with_no_name

每次對話的順序

眾所周知,DDL 語句很昂貴。此外,它通常需要對數據字典進行序列化。您不能同時創建多個序列。

這種方法是一個“壞主意”。

表中的值

為防止重複 ID,您需要對該表進行鎖定。這是一個已知的序列化點。(我已經在這裡寫過一些關於這個方法的東西

這種方法也是一個“壞主意”。

單序列

序列旨在以高消耗率有效地產生唯一的 ID 值。可以跨多個會話並行獲取這些值。

其他方法需要序列化。序列化對數據庫不利。

反而:

您應該只對所有對話使用一個序列。– a_horse_with_no_name

引用自:https://dba.stackexchange.com/questions/265104