【问题标题】:How to delete unused sequences?如何删除未使用的序列?
【发布时间】:2011-11-25 06:36:45
【问题描述】:

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

示例:表:file;为id 自动创建序列:file_id_seq

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

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

【问题讨论】:

    标签: postgresql ddl sequences


    【解决方案1】:

    首先,当该列(或它所在的表)被删除时,为连续列自动创建的序列自动删除。你描述的问题一开始就不应该存在。只有 非常 个旧版本的 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;
    ...
    

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

    小心!它确实 not 意味着这些序列没有在其他情况下使用。有许多用例将序列创建为独立对象。例如,如果您希望多列共享一个序列。你应该清楚自己在做什么。

    但是,您不能以这种方式删除绑定到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.
    

    【讨论】:

    • 我所做的和你的解决方案一样。这是正确的方式与否我不知道。我得到了所有的序列。然后保存在 file.sql 然后我运行该文件。代码是:
    • \o d:/test1.sql SELECT 'drop sequence ' || c.relname || ';' FROM pg_class c WHERE (c.relkind = 'S'); \o \i d:/test1.sql
    • @user1023877:它试图删除所有序列。如果存在任何“绑定”序列,则应该失败。
    • 所以这不是正确的解决方案,所以我将继续使用另一个解决方案。谢谢。
    • 是的,我将继续使用另一种解决方案,这仅意味着您的解决方案。谢谢。
    【解决方案2】:

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

    另一种方法是尝试删除序列。如果一个表引用它,pgAdmin 将抛出一个错误,指出某些东西取决于这个序列。如果您能够删除序列而没有任何错误,则没有依赖关系。

    一定要在某个地方进行测试。

    【讨论】:

    • 但是手动把所有序列一个一个丢掉太难了
    • @user1023877 您应该编写一个执行类似操作的脚本。您可以阅读 syscatalog 来查看依赖关系,但编写这样的内容也可能很乏味。简而言之:我认为这样的任务没有简单的方法。
    • 好的,谢谢。您能否参考任何链接,这些链接将提供有关如何编写脚本的信息?
    • 试试官方docssystem catalog的信息
    • 谢谢。我会通过它。
    【解决方案3】:

    我首先得到所有序列,然后将这些结果保存到一个文件中,然后我在 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
    

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多