我们正在使用PostgreSQL。我的要求是从我的数据库中删除未使用的序列。 例如,如果我通过我的应用程序创建任何表,将创建一个序列,但是为了删除表,我们也不会删除序列。如果想要创建相同的表,则会创建另一个序列。
示例:table:file
;自动创建id
coumn的序列:file_id_seq
当我删除表file
并再次使用相同名称创建表时,正在创建一个新序列(即file_id_seq1
)。我通过这种方式在应用程序数据库中积累了大量未使用的序列。
如何删除这些未使用的序列?
答案 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;
根据当前regclass
,c.oid::regclass
中search_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%未使用的序列。