Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将PostgreSQL数据库用作简单键值存储的最佳方法_Java_Postgresql_Jdbc_Berkeley Db_Key Value - Fatal编程技术网

Java 将PostgreSQL数据库用作简单键值存储的最佳方法

Java 将PostgreSQL数据库用作简单键值存储的最佳方法,java,postgresql,jdbc,berkeley-db,key-value,Java,Postgresql,Jdbc,Berkeley Db,Key Value,我被要求使用postgreSQL数据库,它将取代我目前使用的berkeleyDB。虽然;我意识到这不是一个理想的情况,这是我无法控制的 所以问题是。。。如果您被要求将postgreSQL转换为键值存储,您将如何在尽可能提高效率的同时做到这一点 我的值是字节数组,键是字符串,我可以对这些字符串的长度施加一些限制 我假设我应该使用一个blob作为我的值和主键列来保存该键,但由于我只是冒险进入这一旅程,我很好奇stack overflow社区中是否有人这样做过,或者是否有任何我应该注意的特定“gotc

我被要求使用postgreSQL数据库,它将取代我目前使用的berkeleyDB。虽然;我意识到这不是一个理想的情况,这是我无法控制的

所以问题是。。。如果您被要求将postgreSQL转换为键值存储,您将如何在尽可能提高效率的同时做到这一点

我的值是字节数组,键是字符串,我可以对这些字符串的长度施加一些限制


我假设我应该使用一个blob作为我的值和主键列来保存该键,但由于我只是冒险进入这一旅程,我很好奇stack overflow社区中是否有人这样做过,或者是否有任何我应该注意的特定“gotchas”

您需要存储什么作为值?串?Ints?对象(例如序列化的Java对象)。一个简单的实现可以处理3列表,如下所示:

NAME(VARCHAR)   TYPE(VARCHAR)   VALUE(VARCHAR)
(可能是某种枚举类型)。不过,上述方法不适用于序列化对象之类的二进制数据,而且可能需要一个BLOB

或者(也许是更好的主意),你看到了吗?您可以使用数据库(通过JDBC)来支持这一点,并且可以存储属性以便检索它们:

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

这可能会在执行方面为您省去很多痛苦。您可能在保存二进制数据时遇到问题,因为您必须在插入和检索之前对其进行序列化。但我过去曾使用它通过XStream存储int、double和序列化Java对象,因此我可以确认它工作得很好。

它确实应该取决于密钥是什么。如果总是255个字符以下的字符串,则使用Varchar作为yoru PK,然后使用blob(假设值较大)作为值。如果它总是一个数字,请使用int等


换句话说,需要更多的信息才能给你一个好的答案:)

如果你被迫使用关系数据库,我建议你尝试在数据中找到结构来利用这个事实,因为你放弃了非结构化数据和键值存储的速度优势。你发现的结构越多,你从困境中获得的优势就越大。即使你只在键中找到结构

也考虑如果你只需要顺序或随机访问你的数据,在这个比率和结构根据这个要求你的数据库。例如,您是否打算按类型查询您的值?这些问题中的每一个都会对数据库的结构产生影响

关于postgresql中blob的一个特殊考虑是,它们在内部表示为pg_largetable(loid:oid,pageno:int4,data:bytea)。块的大小由LOBBLKSIZE定义,但通常为2k。所以,若您可以在表中使用字节数组而不是BLOB,并将值/密钥对的大小限制在blocksize下,那个么您可以通过第二个表避免这种间接寻址。如果可以访问数据库的配置,还可以增加块大小


我建议您在数据访问中查找数据结构和模式,然后再详细询问您的问题。

Postgresql中正确执行此操作的扩展名为hstore。它的工作方式与您期望的其他键值存储系统类似。只需加载扩展。语法是独特的,但如果你曾经使用过redis或mongo,你会很快得到它。不要让事情变得更难。我明白,我们通常不需要挑选工具,只能勉强度日。
以下是文档页面:


另一种选择是使用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%左右。

这些字节数组实际上代表什么?文件内容?序列化对象?其他?它们实际上是发送到服务器的序列化actionscript对象。。。但服务器代码不知道或不关心其中包含的内容。是的,我同意使用关系数据库作为键值存储有点荒谬。但使用数据库的一些优点仍然保持不变,例如高效的文件io、加密、用户访问限制等。。。真的那么疯狂吗?是的。谢谢你的链接。。。如果可能的话,我当然希望使用真正的键值存储。我不确定这些技术是否被批准用于国防部的某个项目,试图获得批准是一个令人担忧的问题,因为这不是一项及时的任务。我将进行更多的搜索。下面是如何加载扩展。您需要成为DBA或超级用户。创建扩展存储;