【问题标题】:Change huge table PK column data type更改巨表PK列数据类型
【发布时间】:2009-09-14 07:43:46
【问题描述】:

现在我们已经用完了 PK 列上的 int 容量(这是一个 IDENTITY)我想对 bigint 执行此操作,但简单的 ALTER TABLE 似乎无法处理这么大的桌子。所以我的问题是:如何在保持实际值不变的情况下更改 PK 列的类型,是否还需要更改引用表?

【问题讨论】:

    标签: sql-server alter-table


    【解决方案1】:

    除了 KLE 的建议之外,以下查询可能会有所帮助:

    要禁用引用 oldTable 的表的所有约束,请尝试执行以下查询的输出:

    SELECT 'ALTER TABLE ' + OBJECT_NAME(fk.parent_object_id) + ' NOCHECK CONSTRAINT ' + fk.name
    FROM sys.foreign_keys fk
    INNER JOIN sys.foreign_key_columns AS fkc ON fk.OBJECT_ID = fkc.constraint_object_id
    WHERE OBJECT_NAME (fk.referenced_object_id) = 'oldTable'
    

    要将所有数据移动到新表中,并更改字段,请尝试以下操作:

    INSERT INTO newTable
    SELECT CONVERT(BIGINT, ID) AS ID, COL1, COL2, ..., COLN
    FROM oldTable
    

    删除旧表:

    DROP TABLE oldTable
    

    要将新表重命名为旧名称:

    sp_rename newTable, oldTable
    

    要重新启用引用 oldTable 的表的所有约束,请尝试执行以下查询的输出:

    SELECT 'ALTER TABLE ' + OBJECT_NAME(fk.parent_object_id) + ' CHECK CONSTRAINT ' + fk.name
    FROM sys.foreign_keys fk
    INNER JOIN sys.foreign_key_columns AS fkc ON fk.OBJECT_ID = fkc.constraint_object_id
    WHERE OBJECT_NAME (fk.referenced_object_id) = 'oldTable'
    

    希望对你有帮助...

    【讨论】:

    • 如果使用这种方法,不要忘记重新创建表上的索引
    • 我认为最好禁用受影响表上的所有触发器
    【解决方案2】:

    我们要做的是:

    保存您的表格

    1. 创建一个结构正确的新表

    2. 禁用这些表以及引用它们的所有约束

    3. 将所有数据移动到新表中,并更改字段;可以分批完成

    4. 空表删除旧表

    5. 将新表重命名为旧名称

    6. 在所有表上启用所有约束(一些 FK 列和约束可能也需要修复......但它们不是 PK,因此它们是可修改的)

      6 编辑(感谢 Alexey)

    这很干净,可以批量操作,很好理解。

    【讨论】:

    • 某些数据类型不兼容。一般来说,您应该将所有引用的表更改为。如果您有许多引用表 - 这可能会成为“依赖地狱”
    【解决方案3】:

    您还需要更改子表。毕竟,您现在也将尝试在其中插入一个大整数。我会先改变子表

    这不是一个简单或短暂的过程。我建议您在设定的日期告诉您的用户数据库将因维护而停机(您可以衡量开发需要多长时间),并在您制作时将数据库重置为单用户模式这些变化。您不希望在切换到另一个表时丢失用户添加(或更改)到另一个表的数据。如果由于某种原因你不能有一个维护窗口(为了数据完整性,我强烈建议你这样做),那么你必须首先更改子表以避免插入错误,如果你真的接近限制并且将是几乎可以立即看到大量数字。

    确保为整个数据库结构编写脚本,包括默认值、触发器、检查常量索引等,因为您需要重新创建所有内容。

    确保通过 dev 上的脚本完成所有这些操作。一旦你测试了这个过程,这将使做一个产品变得更容易。

    【讨论】:

      【解决方案4】:

      我认为您只能创建一个更改了 PK 数据类型的新数据库,然后导出/导入数据,或者批量插入新数据库,然后重命名新数据库。当然,如果您有许多引用的表并且您的新 PK 数据类型与以前的不兼容,那么这是实际的。

      【讨论】:

        猜你喜欢
        • 2013-09-12
        • 2014-03-05
        • 2010-11-01
        • 2014-01-20
        • 1970-01-01
        • 2019-11-08
        • 1970-01-01
        • 2020-03-20
        • 1970-01-01
        相关资源
        最近更新 更多