我正在尝试创建一个带有复合主键的表,其中第二列按降序排列:
CREATE TABLE AccountHistory (
AccountNumber BIGINT NOT NULL,
Ts TIMESTAMP NOT NULL,
Memo TEXT,
ChangeAmount BIGINT NOT NULL,
PRIMARY KEY (AccountNumber, ts DESC)
);
Run Code Online (Sandbox Code Playgroud)
但是,PostgreSQL 表示该DESC子句存在语法错误。
我认为这样做是合理的,因为从语义上讲,升序或降序索引是相同的,但 PostgreSQL 不支持它。无法控制自动创建以支持主键的索引的索引顺序。
PostgreSQL 不会让您通过手动创建索引作为UNIQUE具有DESC排序顺序的索引然后PRIMARY KEY使用它创建声明的约束来创建一个ALTER TABLE ... ADD CONSTRAINT ... PRIMARY KEY USING INDEX ...。它将失败:
ERROR: index "foopk" does not have default sorting behavior
Run Code Online (Sandbox Code Playgroud)
我不知道为什么 Pg 需要这个。搜索上述错误的源代码可能会为您找到合适的注释。
PRIMARY KEY只需单独创建唯一索引,您就可以在没有约束元数据的情况下获得类似行为。这对你来说可能没问题。
您可以创建一个索引,例如
CREATE UNIQUE INDEX accounthistory_pk_2 on AccountHistory(AccountNumber, ts DESC);
Run Code Online (Sandbox Code Playgroud)
但这不能是表上的主键,尽管对于像这样的查询很重要
select DISTINCT on (accountnumber) * from AccountHistory
order by accountnumber,ts desc;
Run Code Online (Sandbox Code Playgroud)
测试:
CREATE TABLE AccountHistory (
AccountNumber BIGINT NOT NULL,
Ts TIMESTAMP NOT NULL,
Memo TEXT,
ChangeAmount BIGINT NOT NULL
);
EXPLAIN select DISTINCT on (accountnumber) * from AccountHistory
order by accountnumber,ts desc;
"Unique (cost=65.82..70.52 rows=200 width=56)"
" -> Sort (cost=65.82..68.17 rows=940 width=56)"
" Sort Key: accountnumber, ts"
" -> Seq Scan on accounthistory (cost=0.00..19.40 rows=940 width=56)"
set enable_seqscan=false;
"Unique (cost=10000000065.82..10000000070.52 rows=200 width=56)"
" -> Sort (cost=10000000065.82..10000000068.17 rows=940 width=56)"
" Sort Key: accountnumber, ts"
" -> Seq Scan on accounthistory (cost=10000000000.00..10000000019.40 rows=940 width=56)"
CREATE UNIQUE INDEX accounthistory_pk_1 on AccountHistory(AccountNumber, ts);
"Unique (cost=10000000065.82..10000000070.52 rows=200 width=56)"
" -> Sort (cost=10000000065.82..10000000068.17 rows=940 width=56)"
" Sort Key: accountnumber, ts"
" -> Seq Scan on accounthistory (cost=10000000000.00..10000000019.40 rows=940 width=56)"
CREATE UNIQUE INDEX accounthistory_pk_2 on AccountHistory(AccountNumber, ts DESC);
"Unique (cost=0.15..60.60 rows=200 width=56)"
" -> Index Scan using accounthistory_pk_2 on accounthistory (cost=0.15..58.25 rows=940 width=56)"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8353 次 |
| 最近记录: |