我被要求使用postgreSQL数据库,它将取代我目前使用的berkeleyDB。虽然;我意识到这不是一个理想的情况,它是我无法控制的。
所以问题是......如果你被要求将postgreSQL变成一个关键值存储库,你会如何做到这一点,同时尽可能提高效率?
我的值是字节数组,而我的键是字符串,我可以对这些字符串的长度施加一些限制。
我认为我应该使用blob作为我的价值和持有密钥的主键列,但是当我冒险进入这个旅程时,我很好奇堆栈溢出社区中是否有人这样做,或者是否有任何特定的'陷阱'我应该留意。
答案 0 :(得分:21)
Postgresql中正确执行此操作的扩展称为hstore。它的工作方式与您期望的其他键值存储系统类似。只需加载扩展程序。语法是唯一的,但是如果你曾经使用过redis或mongo,你会很快得到它。不要让它变得更难。我明白,我们经常不会选择我们的工具而必须去做 这是文档页面:
答案 1 :(得分:2)
如果您被迫使用关系数据库,我建议您尝试在数据中查找结构以利用这一事实,因为您放弃了非结构化数据和键值存储所带来的速度优势。您找到的结构越多,您摆脱困境的好处就越大。即使您只在键中找到结构。
还要考虑您是否只需要按顺序或随机访问您的数据,以及按此要求比例和结构数据库。您是否会按类型对您的值进行查询?这些问题中的每一个都可能对您构建数据库的方式产生影响。
关于postgresql中blob的一个具体考虑,它们在内部表示为pg_largetable(loid:oid,pageno:int4,data:bytea)。块的大小由LOBBLKSIZE定义,但通常为2k。因此,如果您可以在表中使用字节数组而不是blob并限制blocksize下的值/键对的大小,则可以通过第二个表避免此间接。如果您有权访问数据库的配置,也可以增加块大小。
我建议在数据访问中寻找数据和模式的结构,然后再详细询问您的问题。
答案 2 :(得分:1)
另一种选择是将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树那样运行有效的范围查询,但是它应该具有更好的读/写性能。索引应该小60%。
答案 3 :(得分:0)
您需要存储什么作为价值?字符串? Ints?对象(例如,序列化的Java对象)。一个简单的实现可以使用3列表,如下所示:
NAME(VARCHAR) TYPE(VARCHAR) VALUE(VARCHAR)
(也许TYPE是一些枚举)。上面的内容不适用于像序列化对象这样的二进制数据,但也许你需要一个BLOB。
或者(可能是很多更好的主意),你见过Apache Commons Configuration吗?您可以使用数据库(通过JDBC)对其进行备份,并且可以存储属性,以便检索它们:
// get a property called 'number'
Double double = config.getDouble("number");
Integer integer = config.getInteger("number");
这可能会在实施方面为您节省很多麻烦。您可能在保存二进制数据时遇到问题,因为您必须在插入和检索之前对其进行序列化。但是我过去曾经使用它来通过XStream存储整数,双精度和序列化的Java对象,所以我可以确认它运行良好。
答案 4 :(得分:0)
它确实应该取决于密钥的内容。如果它总是一个低于255个字符的字符串,那么使用Varchar作为yoru PK,然后使用blob(假设值很大)作为值。如果它总是一个数字,请使用int等。
换句话说,需要更多信息来真正给你一个好的答案:)