DROP CONSTRAINT 後主鍵的索引會發生什麼變化?
我正在執行 PostgreSQL 9.1.4。
我有一個包含許多現有行的表,以及一堆帶有指向它的外鍵的其他表,我正在嘗試:
1 - 移除目前主鍵的 pkey 約束,因為它目前不是串列類型。
2 - 添加一個序列類型列並將該新列作為主鍵。
3 - 將步驟 #1 的舊列設置為 UNIQUE 並為所有具有指向我的表的外鍵的表重新創建外鍵。事實上,這些表都有兩個指向我的表的外鍵:一個指向目前是主鍵的舊列,另一個指向新的序列類型列
我已經成功創建了一個執行此操作的腳本,但我想知道:
a) 在上面的步驟 #1 中刪除 pkey 約束是否也會刪除與該主鍵關聯的索引?
b)如果沒有,有沒有辦法重用該索引?在第 3 步添加回 UNIQUE 約束後,是否會創建一個新索引,還是會使用之前存在的索引?除了創建的新列(序列主鍵)之外,表中沒有任何內容被更改。
編輯(一些澄清):
- 我們將舊的 pk 列稱為 OLD_PK,將要由我的腳本創建的新 pk 列稱為 NEW_PK
- OLD_PK 列的類型是 INT
- OLD_PK 列不會也不能被刪除(它的資訊仍然有價值)因此它也不能將自己轉換為串列類型,現有數據必須保留。
- 我知道串列是一條捷徑。就像我說的那樣,我想出了一個工作腳本,我不確定的部分是索引以及從那個角度來看它是如何工作的。
- 以前有一個外鍵指向 OLD_PK 的所有表,在執行腳本後,將有一個外鍵指向 OLD_PK(比如“fkey_old_pk”)和另一個指向 NEW_PK 的外鍵(比如“fkey_new_pk”)
免責聲明
這是實驗性的,僅進行了初步測試。繼續需要您自擔風險。我自己不會使用它,只是使用標準 DDL 命令刪除/重新創建約束。如果您破壞了目錄表中的條目,您很容易弄亂您的數據庫。
PRIMARY KEY
據我所知,目錄表中的 a和約束之間只有兩個區別UNIQUE
(索引本身是相同的):
PRIMARY KEY
約束…true
UNIQUE
約束…false
PRIMARY KEY
約束…'p'
UNIQUE
約束…'u'
您可以將約束和索引從
PRIMARY KEY
約束轉換為UNIQUE
約束,my_idx
作為(可選的模式限定)索引名稱:UPDATE pg_index SET indisprimary = false WHERE indexrelid = 'my_idx'::regclass; UPDATE pg_constraint SET contype = 'u' WHERE conindid = 'my_idx'::regclass;
或從升級
UNIQUE
到PRIMARY KEY
:UPDATE pg_index SET indisprimary = true WHERE indexrelid = 'my_idx'::regclass; UPDATE pg_constraint SET contype = 'p' WHERE conindid = 'my_idx'::regclass;
當然,每張桌子只能有一個PK。
是的,刪除主鍵約束將刪除索引。
但需要注意的是,serial不是真正的類型,它是 的快捷方式
INT default nextval('some_sequence')
,其中some_sequence
是自動生成的。您沒有說目前列類型是什麼,但由於您希望能夠重用串列列的索引,因此假設它是 INT。
如果您打算最終刪除舊列,則問題並不明顯,但如果您只想將其轉換為串列列,則不需要刪除和重新創建相關的約束。只需創建一個序列,將其初始化為主鍵的下一個值,並將其下一個值設為該列的預設值,如下所示:
CREATE SEQUENCE myseq START WITH 12345;
其中 12345 被目前替換
max(pk)
然後:
ALTER TABLE tablename ALTER COLUMN pk_col SET DEFAULT nextval('myseq');