如何删除未使用的序列?

时间:2011-11-25 06:36:45

标签: postgresql ddl sequences

我们正在使用PostgreSQL。我的要求是从我的数据库中删除未使用的序列。 例如,如果我通过我的应用程序创建任何表,将创建一个序列,但是为了删除表,我们也不会删除序列。如果想要创建相同的表,则会创建另一个序列。

示例:table:file;自动创建id coumn的序列:file_id_seq

当我删除表file并再次使用相同名称创建表时,正在创建一个新序列(即file_id_seq1)。我通过这种方式在应用程序数据库中积累了大量未使用的序列。

如何删除这些未使用的序列?

4 个答案:

答案 0 :(得分:13)

首先,当删除列(或表中的列)时,为串行列自动创建的序列会自动删除。您描述的问题不应该存在。只有非常旧版本的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;

根据当前regclassc.oid::regclasssearch_path的强制转换会自动根据需要对模式名称进行限定。参见:

结果:

DROP SEQUENCE foo_id_seq;
DROP SEQUENCE bar_id_seq;
...

执行结果以删除未绑定到串行列(或任何其他列)的所有序列。研究meaning of columns and tables here

小心虽然! 意味着那些序列不在使用中。有许多用例将序列创建为独立对象。例如,如果您希望多列共享一个序列。你应该确切地知道你在做什么。

但是,无法以这种方式删除绑定到serial列的序列。因此,这个方面的操作是安全的。

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.

答案 1 :(得分:0)

如果您使用的是pgAdmin,则可以选择序列并选中“依赖”选项卡。它将列出任何依赖于序列的对象。

另一种方法是TRY删除序列。如果表引用它,pgAdmin将抛出一个错误,指出某些内容取决于此序列。如果您能够删除没有任何错误的序列,则没有依赖性。

请务必在某处测试。

答案 2 :(得分:0)

我做的是先获取所有序列,然后将这些结果保存到文件中,然后在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

答案 3 :(得分:0)

小心谨慎,“drop sequence sequence_name_here”将成功删除序列,即使它作为表列的默认nextval()值附加。这里似乎有一些脱节,特别是如果序列是单独创建的。我也在寻找完美的一个衬垫来清理100%未使用的序列。