未使用の配列を削除するには?

私たちはPostgreSQLを使用しています。私の要件は、データベースから未使用の配列を削除することです。 たとえば、アプリケーションからテーブルを作成すると、シーケンスが1つ作成されますが、シーケンスを削除していないテーブルも削除されます。同じテーブルを作成したい場合、別のシーケンスが作成されています。

Example: table: file; automatically created sequence for id coumn: file_id_seq

テーブル file を削除して再度同じ名前で作成すると、新しいシーケンスが作成されます( file_id_seq1 )。私はこの方法でアプリケーションデータベースに膨大な数の未使用のシーケンスを蓄積しています。

これらの未使用の配列を削除するには?

2

4 答え

最初に、シリアル列に対して自動的に作成されるシーケンスは、列(またはそのテーブルがある)が削除されると自動的に削除されます。あなたが記述する問題は、まずは存在してはいけません。 非常に古いバージョンのPostgreSQLはそれをしませんでした。 7.4歳以上?

問題の解決策:

このクエリは、実行されるデータベース内のすべての「バインドされていない」シーケンスを削除する DDLコマンドを生成します。

SELECT string_agg('DROP SEQUENCE ' || c.oid::regclass, '; ') || ';' AS ddl
FROM   pg_class       c
LEFT   JOIN pg_depend d ON d.refobjid = c.oid
                       AND d.deptype <> 'i'
WHERE  c.relkind = 'S'
AND    d.refobjid IS NULL;

c.oid :: regclass regclass へのキャストは、現在の search_path に従って必要に応じてシーケンス名を自動的に修飾します。見る:

結果:

DROP SEQUENCE foo_id_seq;
DROP SEQUENCE bar_id_seq;
...

結果を実行して、シリアル列(または他の列)にバインドされていないすべてのシーケンスを削除します。 コラムとテーブルの意味についてはこちらをご覧ください。

Careful though! It does not mean those sequences aren't in use otherwise. There are a number of use cases where sequences are created as standalone objects. For instance if you want multiple columns to share one sequence. You should know exactly what you are doing.

しかし、このように serial カラムにバインドされたシーケンスは削除できません。したがって、操作は this の点で安全です。

DROP SEQUENCE test_id_seq

結果:

ERROR:  cannot drop sequence test_id_seq because other objects depend on it
DETAIL:  default for table test column id depends on sequence test_id_seq
HINT:  Use DROP ... CASCADE to drop the dependent objects too.
10
追加された
Postgres 9.3.4を実行していて、テーブルが削除されたときにテーブルのシーケンスは削除されません。私はまだ手動でシーケンスを削除する必要があります。
追加された 著者 Amalgovinus,
あなたが正しいです、私の問題は、シーケンスフィールドにPKがないことでした。
追加された 著者 Amalgovinus,
@ user1023877:これは、すべてのシーケンスを削除しようとします。 「束縛された」配列が存在する場合には失敗するはずです。
追加された 著者 Erwin Brandstetter,
@Amalgovinus: serial 疑似型で作成された場合と同様に、シーケンスはPK列によって所有されません。参照: stackoverflow.com/a/24659884/939860 またはstackoverflow.com/a/10002134/939860
追加された 著者 Erwin Brandstetter,
@Amalgovinus:私は正しいと確信していますが、PKには何もありません。 :) 所有権はここで重要な部分です。
追加された 著者 Erwin Brandstetter,
@SteveGlick:あなたの編集をありがとう。あなたはスキーマを追加することにしました。私はちょうどよりエレガントなコードに置き換えました。
追加された 著者 Erwin Brandstetter,
私のしていることはあなたの解決策と同じです。それは正しい方法か私は知らない。私はすべてのシーケンスを取得します。 file.sqlに保存してからファイルを実行します。コードは次のとおりです。
追加された 著者 user1023877,
\ o d:/test1.sql SELECT 'ドロップシーケンス' || c.relname || ';' FROM pg_class c WHERE(c.relkind = 'S'); \ o \ i d:/test1.sql
追加された 著者 user1023877,
これは適切な解決策ではありませんので、別の解決策に移行します。ありがとうございます。
追加された 著者 user1023877,
はい、私はあなたの解決策を意味する別のソリューションに移動します。ありがとうございました。
追加された 著者 user1023877,
この問題がPostgres 8.4で起こるかもしれないと報告していますが、毎回私のために起こったことではありません。たぶんバグかもしれない、誰かが私のデータベースで何かを混乱させた、私は知らない。
追加された 著者 Felipe Andrade,

pgAdminを使用している場合は、シーケンスを選択して「依存する」タブをチェックすることができます。シーケンスに依存するオブジェクトがリストされます。

別の方法は、シーケンスを削除するためにTRYを行うことです。テーブルがそれを参照すると、pgAdminは何かがこのシーケンスに依存しているというエラーを投げます。エラーなしでシーケンスを削除できる場合は、依存関係はありません。

これをどこかでテストしてください。

0
追加された
@ user1023877あなたはこれに似た何かをするスクリプトを書かなければなりません。依存関係を見るためにsyscatalogを読むことができますが、このようなことを書いても面倒です。それを短くする:私はそのような仕事のための簡単な方法はないと思います。
追加された 著者 DrColossos,
追加された 著者 DrColossos,
しかし、すべてのシーケンスを手動で1つずつ削除することは難しい
追加された 著者 user1023877,
大丈夫ありがとう。スクリプトを書く方法に関する情報を提供するリンクを参照できますか?
追加された 著者 user1023877,
ありがとうございました。私はそれを通過します。
追加された 著者 user1023877,

私はまずすべてのシーケンスを取得し、これらの結果をファイルに保存してから、psqlでファイルを実行します:コンテンツは del_seq_all.sql というファイル名で保存され、 > test1.sql ]をクリックします。私はこれが正しい解決策であるかどうかわかりません。しかし結果は期待どおりになる。

\o d:/test1.sql
SELECT 'drop sequence ' || c.relname || ';' FROM pg_class c WHERE
(c.relkind = 'S');
\o

\i d:/test1.sql
0
追加された

慎重に進んで、 "drop sequence sequence_name_here"は、テーブル列のデフォルトのnextval()値としてアタッチされていても、シーケンスを正常に削除します。特にシーケンスが別々に作成されている場合は、ここでいくつかの接続が切断されているようです。私は100%未使用の配列をきれいにするための完全なライナーも探しています。

0
追加された