2017-08-09 116 views
1

我試圖創建一個表,其中,第二列是有序的下降複合主鍵:使用ASC或DESC命令的主鍵?

CREATE TABLE AccountHistory (                                           
    AccountNumber BIGINT NOT NULL,                                           
    Ts TIMESTAMP NOT NULL,                                             
    Memo TEXT,                                                
    ChangeAmount BIGINT NOT NULL,                                           
    PRIMARY KEY (AccountNumber, ts DESC)                                        
); 

不過,PostgreSQL是說有在DESC子句的語法錯誤。

  • PostgreSQL真的不允許這樣嗎?
  • 有沒有這樣的DESC鍵有意義?
  • 我唯一的選擇是用我想要的語義創建一個額外的索引嗎?
+2

這根本沒有意義。您在選擇時指定您的訂單,而不是在索引時指定。另外,爲了使用索引,您需要先通過'AccountNumber'命令,然後按'ts'命令,否則排序效率不高。爲了克服這個問題,只在'ts'上指定一個單獨的索引。但是,您不能在索引上指定排序順序,僅限於選擇。 – Psi

+0

@Psi你當然可以告訴postgresql索引列的順序,這在很多情況下非常有意義,例如'create index myindex(AccountNumber,ts DESC)'在postgresql中有效,但我不確定是否它可以在主鍵上完成。 – nos

+0

@nos你可以自己指定索引列的順序(例如'col B',然後'col A'),但是對於我來說這完全沒有意義,爲什麼你可以顛倒特定列的索引順序。另外我不明白你爲什麼要這樣做,因爲你想要選擇而不是定義索引。您只能按升序或降序進行排序,這只是從開始或結束(然後向後)讀取索引,因此不需要指定任何順序來存儲索引。 – Psi

回答

1

https://dba.stackexchange.com/questions/90722/is-unique-index-better-than-unique-constraint-when-an-index-with-an-operator-cla

您可以創建一個像

CREATE UNIQUE INDEX accounthistory_pk_2 on AccountHistory(AccountNumber, ts DESC); 

索引但不能是表的主鍵,但對於像

select DISTINCT on (accountnumber) * from AccountHistory 
order by accountnumber,ts desc; 

測試查詢是非常重要的:

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)" 
1

我認爲這樣做是合理的,因爲語義上按升序或降序排列的索引是相同的,但PostgreSQL不支持它。沒有辦法控制自動創建的索引的索引順序來備份主鍵。

PostgreSQL將不會讓你通過手動創建索引作爲UNIQUE指數與DESC排列順序,然後創建一個聲明PRIMARY KEY約束它使用ALTER TABLE ... ADD CONSTRAINT ... PRIMARY KEY USING INDEX ...創建一個。它將失敗:

ERROR: index "foopk" does not have default sorting behavior 

我不知道爲什麼Pg需要這個。搜索源代碼中的上述錯誤可能會找到合適的評論。

僅通過單獨創建唯一索引就可以獲得沒有約束元數據的類似PRIMARY KEY的行爲。這可能對你很好。