簡體   English   中英

使用 PostgreSQL 數據庫作為簡單鍵值存儲的最佳方式

[英]Best way to use a PostgreSQL database as a simple key value store

我被要求使用 postgreSQL 數據庫,它將取代我目前使用的 berkeleyDB。 雖然; 我意識到這不是一個理想的情況,它超出了我的控制范圍。

所以問題是......如果你被要求將 postgreSQL 變成一個鍵值存儲,你將如何做到這一點,同時使其盡可能高效?

我的值是字節數組,我的鍵是字符串,我可以對這些字符串的長度施加一些限制。

我假設我應該使用 blob 作為我的值和主鍵列保存鍵,但是當我剛剛踏入這個旅程時,我很好奇堆棧溢出社區中是否有人這樣做過,或者是否有任何特定的“陷阱”我應該注意一下。

Postgresql 中正確執行此操作的擴展名為 hstore。 它的工作方式與您期望的其他鍵值存儲系統類似。 只需加載擴展程序。 語法是獨一無二的,但如果您曾經使用過 redis 或 mongo,您將很快掌握它。 不要讓它變得比現在更難。 我明白,我們經常無法選擇我們的工具而不得不湊合。
這是文檔頁面:

http://www.postgresql.org/docs/9.1/static/hstore.html

如果您被迫使用關系數據庫,我建議您嘗試在數據中找到結構以利用這一事實,因為您放棄了使用非結構化數據和鍵值存儲獲得的速度優勢。 你找到的結構越多,你就越能擺脫困境。 即使您只在鍵中找到結構。

還要考慮您是否只需要順序或隨機訪問您的數據,以及根據此要求以何種比例和結構構建您的數據庫。 例如,您是否要按類型對您的值進行查詢? 這些問題中的每一個都可能影響您構建數據庫的方式。

關於 postgresql 中 blob 的一項具體考慮,它們在內部表示為 pg_largetable (loid:oid,pageno:int4,data:bytea)。 塊的大小由 LOBBLKSIZE 定義,但通常為 2k。 因此,如果您可以在表中使用字節數組而不是 blob 並在塊大小下限制值/鍵對的大小,則可以通過第二個表避免這種間接性。 如果您有權訪問數據庫的配置,您還可以增加塊大小。

我建議在數據訪問中尋找數據結構和模式,然后更詳細地再次詢問您的問題。

另一種選擇是使用 JSON 或 JSONB,並在鍵上具有唯一的哈希索引。

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

CREATE TABLE key_values (
    key uuid DEFAULT uuid_generate_v4(),
    value jsonb
);

CREATE INDEX idx_key_values ON key_values USING hash (key);

一些查詢

SELECT * FROM key_values WHERE key = '1cfc4dbf-a1b9-46b3-8c15-a03f51dde891';
Time: 0.514 ms
postgres=# SELECT * FROM key_values WHERE key = '1cfc4dbf-a1b9-46b3-8c15-a03f51dde890';
Time: 1.747 ms

postgres=# do $$
begin
for r in 1..1000 loop
INSERT INTO key_values (value)
VALUES ('{"somelarge_json": "bla"}');
end loop;
end;
$$;
DO
Time: 58.327 ms

你不能像 B-tree 那樣運行高效的范圍查詢,但它應該有更好的讀/寫性能。 指數應該小 60% 左右。

您需要將什么存儲為值? 字符串? 整數 ? 對象(例如序列化的 Java 對象)。 一個簡單的實現可以使用 3 列表,如下所示:

NAME(VARCHAR)   TYPE(VARCHAR)   VALUE(VARCHAR)

(也許 TYPE 是一些枚舉)。 上面的方法不適用於像序列化對象這樣的二進制數據,但也許你需要一個 BLOB。

或者(和可能是一個更好的主意),你看到Apache的百科全書配置 您可以使用數據庫(通過 JDBC)支持它,並且您可以存儲屬性以便您檢索它們:

// get a property called 'number'
Double double = config.getDouble("number");
Integer integer = config.getInteger("number");

這可能會在實施方面為您省去很多麻煩。 可能在保存二進制數據時遇到問題,因為您必須在插入和檢索后對其進行序列化。 但我過去曾使用它通過 XStream 存儲整數、雙精度數和序列化的 Java 對象,因此我可以確認它運行良好。

這真的應該取決於關鍵是什么。 如果它始終是 255 個字符以下的字符串,則使用 Varchar 作為 yoru PK,然后使用 blob(假設一個大值)作為該值。 如果它總是一個數字,請使用 int 等。

換句話說,需要更多信息才能真正給你一個好的答案:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM