我正在使用 SQL Server 2008,并且我有一个包含大约 50 行的表。
该表包含类型的主要标识列int
。
我想将该列升级为bigint
.
我需要知道如何快速做到这一点,不会使我的数据库服务器不可用,也不会删除或破坏我的任何数据
我应该怎么做最好?这样做的后果是什么?
我正在使用 SQL Server 2008,并且我有一个包含大约 50 行的表。
该表包含类型的主要标识列int
。
我想将该列升级为bigint
.
我需要知道如何快速做到这一点,不会使我的数据库服务器不可用,也不会删除或破坏我的任何数据
我应该怎么做最好?这样做的后果是什么?
好吧,这不是一个快速的方法,真的....
我的方法是这样的:
创建一个具有相同结构的新表 - 除了ID
列是BIGINT IDENTITY
而不是INT IDENTITY
----[在这里将您的服务器设置为独占单用户模式;用户从此时起无法使用您的服务器]----
查找并禁用所有引用您的表的外键约束
转动SET IDENTITY_INSERT (your new table) ON
将旧表中的行插入到新表中
转动SET IDENTITY_INSERT (your new table) OFF
删除你的旧表
将新表重命名为旧表名
更新所有对您的表有 FK 引用的表以使用BIGINT
而不是INT
(这应该可以通过简单的ALTER TABLE ..... ALTER COLUMN FKID BIGINT
)
再次重新创建所有外键关系
现在您可以再次将您的服务器恢复到正常的多用户使用状态
我错过了什么?
为什么你不能这样做:
ALTER TABLE tableName ALTER COLUMN ID bigint
我想先在测试环境中尝试一下,但这总是对我有用
可能最好的方法是使用 BIGINT IDENTITY 列创建一个新表,使用 SET IDENTITY_INSERT ON 移动现有数据;然后重命名表。您将需要在维护窗口期间执行此操作,就像您在 Management Studio 中更改数据类型一样(这同样会创建一个新表、移动数据并阻止流程中的每个人)。
正如@MobileMon 所说,您可以为您的列使用 Alter 脚本,但在删除约束之前无法执行此操作。除了 FK 约束之外,您还必须在更改列类型之前删除 PK 约束!
如果 ID 数据不重要(无 FK 等),还有另一种创造性的方式:
& 如果 ID 数据很重要:
重要说明: 1. 如果旧的列 ID 值不重要并且您的值之间存在很大差距(除了插入之外还有删除),则不需要 BigInt。只需将新的 ID 列再次设为 Int 即可。2. 当表增长并达到溢出值(20 亿)时,您可以查看属性中的实际行数,即表的存储。也许您的到达溢出,但您的行号远少于此。
为什么有人要使用 BigInt 而不是 Int 作为 IDENTITY?
考虑这种情况:您的数据库存在于多个环境中,包括实时生产环境中的 1 个实例和(TestA、B、C 等)、(QA A、B、C 等)、(Demo A、 B、C 等)、(UAT A、B、C 等)、(培训 A、B、C 等)不断......你甚至不想知道......
此数据库 IDENTITY 字段用于将唯一编号传递给第三方提供商,该第三方提供商是非生产环境中的共享环境。供应商收取费用以设置多个环境,因此公司有一个用于生产数据库,一个用于所有其他环境。
所以......当在非生产环境中进行测试时,这些数字永远不会与您碰巧在其中进行测试的任何非生产环境相互交叉。并且测试包括压力测试......一次发送100个数千行。
最重要的是...所有这些环境都在生产环境中刷新,因此身份字段会随着生产环境中的任何内容而重置。因此,必须跟踪每个环境中使用的传播,然后将 IDENTITY 重置为以前从未使用过的新传播。如果在这些环境中再次发送已发送的号码,第 3 方供应商将呕吐。供应商不愿意或无法刷新或重置这些数字。
这是一个现实世界的问题,当前字段在所有环境中仍然是一个整数,并且跟踪这些价差的管理每季度或每当有人对数千笔交易进行大规模压力测试时都会更新。
因此,在大约 10 年内,该 IDENTITY 必须更新为 BIGINT,否则必须有人说服第 3 方供应商对其进行更新。
哦,是的,管理层可能会对此大发雷霆,直到一切都突然崩溃。
然后 HACK "ALTER TABLE tableName ALTER COLUMN ID bigint" 就可以了。空间和索引处理很便宜!