array
列有上限吗?
插入数组字段时出现此错误 -
PG::Error: ERROR: index row size 3480 exceeds maximum 2712 for index "ix_data"
Run Code Online (Sandbox Code Playgroud)
这是我的表定义 -
create table test_array(id varchar(50), data text[]);
ALTER TABLE test_array ADD PRIMARY KEY (id);
CREATE INDEX ix_data ON test_array USING GIN (data);
Run Code Online (Sandbox Code Playgroud)
我需要数组字段的索引,因为我正在对它进行一些查找。
我有这个UNIQUE
限制:
ALTER TABLE table ADD CONSTRAINT "abc123" UNIQUE
("col1", "col2", "col3", "col4", "col5", "col6", "col7", "col8");
Run Code Online (Sandbox Code Playgroud)
然后我这样做:
INSERT INTO table ("col1", "col2", "col3", "col4", "col5", "col6", "col7", "col8")
VALUES ('a', 'b', 'c', 'd', 'e', 'f', null, true);
INSERT INTO table ("col1", "col2", "col3", "col4", "col5", "col6", "col7", "col8")
VALUES ('a', 'b', 'c', 'd', 'e', 'f', null, true);
Run Code Online (Sandbox Code Playgroud)
两者都有效。两行已添加到表中。从逻辑上讲,第二个应该失败。但事实并非如此。
我究竟做错了什么?这让我发疯。
注意:如果这是我自己的数据,我将拥有一个真正独特的列,而不是这个“疯狂”的UNIQUE
约束。问题是这个表保存了我的银行帐户的记录,而且他们愚蠢地在 CSV 转储中没有真正的“唯一”列,我可以用它来实际确保不插入重复的行,所以我有提出一个组合整个表中所有列以确定唯一性的方法。
我们一再看到尝试索引值超过最大大小的列失败。Postgres 10 有这样的错误信息:
Run Code Online (Sandbox Code Playgroud)ERROR: index row size xxxx exceeds maximum 2712 for index "foo_idx" HINT: Values larger than 1/3 of a buffer page cannot be indexed. Consider a function index of an MD5 hash of the value, or use full text indexing.
例子:
等等。
现在,a_horse_with_no_name 演示了一个具有更大text
值(10000 个字符)的案例,它似乎仍然适用UNIQUE
于 Postgres 9.6 中的索引。引用他的测试用例:
create table tbl (col text);
create unique index on tbl (col);
insert into tbl
values (rpad(md5(random()::text), 10000, md5(random()::text)));
select length(val) …
Run Code Online (Sandbox Code Playgroud) 我有两张这样的表:
CREATE TABLE cmap5 (
name varchar(2000),
lexemes tsquery
);
Run Code Online (Sandbox Code Playgroud)
和
CREATE TABLE IF NOT EXISTS synonyms_all_gin_tsvcolumn (
cid int NOT NULL, -- REFERENCES pubchem_compounds_index(cid)
name varchar(2000) NOT NULL,
synonym varchar(2000) NOT NULL,
tsv_syns tsvector,
PRIMARY KEY (cid, name, synonym)
);
Run Code Online (Sandbox Code Playgroud)
我目前的查询是:
SELECT s.cid, s.synonym, c.name, ts_rank(s.tsv_syns,c.lexemes,16)
FROM synonyms_all_gin_tsvcolumn s, cmap5 c
WHERE c.lexemes @@ s.tsv_syns
Run Code Online (Sandbox Code Playgroud)
输出是:
cid | synonym | name (query) | rank
5474706 | 10-Methoxyharmalan | 10-methoxyharmalan | 0.0901673
1416 | (+/-)12,13-EODE | 12,13-EODE | 0.211562
5356421 …
Run Code Online (Sandbox Code Playgroud) postgresql aggregate full-text-search group-by greatest-n-per-group
幸运的是,当我尝试在大长度文本列上创建唯一索引时,Erwin Brandstetter救了我。
插入率的上限是每年数百亿行。
对于我的实现,散列永远不需要离开数据库,但散列数据必须经常与外部数据进行比较才能存在。
根据我针对这些目的进行优化的有限经验,我假设散列的最佳数据类型是bytea
. 替代方案当然是更长的十六进制字符串。
bytea
这些哈希的最佳数据类型是否正确?
如果bytea
不是最优的,什么是最优的?
我的意图应该如何实现?
澄清
我根据 Erwin Brandstetter 的建议使用文本的哈希值,以确保大文本是唯一的。我有限的理解是,原始二进制数据总是性能最好的,尤其是与字符串相比时。
只需比较哈希是否存在即可抢占唯一性违规,因此哈希很高兴永远不需要离开数据库。由于 libpqxx 令人难以置信的设计,看起来好像数据可以简单地通过准备好的语句输入并使用(decode(md5($1::text), 'hex'))
. 当我更熟悉bytea
通过 libpqxx 3.1 插入时,我会将其移至 C++。
对于此实现,冲突是可以接受的,因为可以在不破坏系统的情况下重建数据以符合要求。
如果愉快地达到最大吞吐量,那么应该预期经济资源将可用于容纳它;因此,主要关注点始终是性能,所以如果我对 Postgres 的功能及其分区表处理这些行数的能力的理解是准确的,那么它有望在很长一段时间内成为该工作的正确工具。幸运的是,超过几秒钟的数据永远不会改变,我的理解是 Postgres 分区表可以将这些数据制成碎肉。如果没有,这将是那些好问题之一。
postgresql ×5
index ×3
aggregate ×1
bytea ×1
group-by ×1
limits ×1
null ×1
optimization ×1
performance ×1
size ×1