我正在使用SQL Server 2008,我有一个包含大约50个行的表。
该表包含int
类型的主要标识列。
我想将该列升级为bigint
。
我需要知道如何以快速的方式做到这一点,这不会使我的数据库服务器不可用, 并且不会删除或破坏我的任何数据
我该怎么做才能做到最好?这样做的后果是什么?
答案 0 :(得分:26)
嗯,这不会是一种快速的方式,真的......
我的方法是:
创建一个结构相同的新表格 - 除了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
)
再次重新创建所有外键关系
现在您可以将服务器恢复为正常的多用户使用状态
答案 1 :(得分:15)
我错过了什么?
为什么你不能这样做:
ALTER TABLE tableName ALTER COLUMN ID bigint
我想首先在测试环境中尝试一下,但这总是对我有用
答案 2 :(得分:8)
可能最好的方法是创建一个带有BIGINT IDENTITY列的新表,使用SET IDENTITY_INSERT ON移动现有数据;然后重命名表。您需要在维护窗口期间执行此操作,就像在Management Studio中更改数据类型一样(类似地创建新表,移动数据并阻止流程中的每个人)。
答案 3 :(得分:0)
您可以像@MobileMon所说的那样对列使用Alter脚本,但是在删除约束之前不能这样做。除了FK约束,还必须在更改列类型之前删除PK约束!
如果ID数据不重要(没有FK等),还有另一种创造性的方法:
&如果ID数据很重要:
重要说明:1.如果旧的列ID值不重要并且您的值之间有很大的差距(除了插入项,您还有删除项),则不需要BigInt。只需将新的ID列再次设为Int。 2.当表增长并达到溢出值(20亿)时,您可以查看属性,表存储中的实际行号。也许您已达到溢出范围,但您的行号要少得多。
答案 4 :(得分:-4)
为什么有人想使用BigInt而不是Int作为IDENTITY?
考虑这种情况: 您的数据库存在于多个环境中,包括实时生产环境中的1个实例和(TestA,B,C等)中的其他几个实例(QA A,B,C等),(演示A,B,C,等等,(UAT A,B,C等),(训练A,B,C等)......等等......你甚至不想知道......
此数据库IDENTITY字段用于将唯一编号传递给第三方提供商,该第三方提供商是非生产环境中的共享环境。供应商为了设置多个环境而收取一条腿和一条腿,因此公司有一个用于生产数据库,一个用于所有其他环境。
所以......当在非生产环境中进行测试时,这些数字永远不会从您正在测试的任何非生产环境中相互交叉。并且测试包括压力测试......在数千行中发送数百行一时间
最重要的是......所有这些环境都会使用Production进行刷新,因此Identity字段会被生产中的任何内容重置。因此,必须跟踪每个环境中使用的扩散,然后将IDENTITY重置为之前从未使用过的新扩展。如果在这些环境中再次发送已经编号的数字,第三方供应商将会呕吐。并且供应商不愿意或无法刷新或重置这些数字。
这是一个现实世界的问题,目前的领域仍然是所有环境中的一个整体,跟踪这些差价的管理每季度更新一次,或者每当有人对数以千计的交易进行大规模压力测试时都会更新。
所以在大约10年内,这个IDENTITY必须更新为BIGINT,或者有人必须说服第三方供应商在他们的最后刷新。
噢,是的,管理层可以给老鼠一个屁股,直到一切都突然崩溃。然后HACK“ALTER TABLE tableName ALTER COLUMN ID bigint”就可以了。 空间和索引处理很快!