我有一张表,其中存储了相对较大的字符串(10000 个字符)。
我会有很多行(数百万行?),但其中 99% 的行将具有相同的大字符串值。
有谁知道 postgres 是否有机制可以很好地处理这种情况?(即不要使用千兆的存储空间)
我有一张表,其中存储了相对较大的字符串(10000 个字符)。
我会有很多行(数百万行?),但其中 99% 的行将具有相同的大字符串值。
有谁知道 postgres 是否有机制可以很好地处理这种情况?(即不要使用千兆的存储空间)
PostgreSQL 在内部压缩大值。但它不会检测到多行中的值是相同的。如果你想要这样的检测,你必须自己做。例如使用如下模式:
CREATE TABLE big_texts (
id SERIAL PRIMARY KEY,
big_text TEXT NOT NULL DEFAULT ''
);
CREATE TABLE base_table (
id SERIAL PRIMARY KEY,
big_text_id INT4 NOT NULL REFERENCES big_texts (id),
other TEXT,
columns INT8,
);
我会有很多行(数百万行?),但其中 99% 的行将具有相同的大字符串值。
在这种情况下,我会将唯一的“大字符串”存储在另一个表中,并只保留对另一个表中正确行的引用。
实际上,您可能需要考虑使用 MD5 作为 ID。Postgres 支持 MD5。
因此,您可以使用 @depesz 修改后的模式插入:
CREATE TABLE big_text (
id VARCHAR(32) NOT NULL,
big_text TEXT NOT NULL,
CONSTRAINT big_text_pkey PRIMARY KEY (id)
);
您可以使用宿主语言以编程方式创建 ID,也可以使用 Postgres 为您创建 ID: http ://www.postgresql.org/docs/9.1/static/functions-string.html
然后您可以执行以下操作:
INSERT INTO big_text (id, big_text) VALUES (md5(big_text), big_text);
如果插入失败,您已经在数据库中有文本。显然,您可以通过首先选择 md5 值来以更好的方式执行此操作。
10000
字符不是那么大,但如果你真的想扩大规模,你还可以研究布隆过滤器之类的东西。
您可能想为 postgres 使用 citus 数据扩展。2021 年 3 月,他们为表甚至表分区添加了列存储选项。这完全符合其他答案的建议,但在幕后。 https://www.citusdata.com/blog/2021/03/06/citus-10-columnar-compression-for-postgres/