1

几个月前,我接管了一个应用程序,该应用程序使用Guids作为主表上的主键。最近我们一直在讨论一些与索引有关的数据库问题,并且我刚刚读到了使用Guids作为主键,并且我已经知道他们可能有多少坏主意,而且我认为它可能会付出代价在数据库变得太大之前改变它们。将GUID主键更改为整数主键

我想知道是否有简单的方法将它们更改为Ints?有一些惊人的软件会为我做这个吗?还是完全取决于我?

我在考虑只添加一个额外的Int列以及所有适当的表,写一些代码来根据CreationDate列用1-n填充此列,编写一些更多代码来填充所有相关表中的列,然后切换与新的int列的关系。听起来太困难了......这是做这件事的最好方法吗?

+1

为什么你不能只是做一些基于http://stackoverflow.com/questions/3698793/how-to-add-a-new-identity-column-to-a-table-in-sql-server –

+2

检查http://stackoverflow.com/questions/6084572/how-to-set-auto-increment-after-creating-a-table-without-any-data-loss/6086661#6086661和http:// stackoverflow。 com/questions/17040124/add-an-identity-column-to-existing-table-as-the-primary-key-and-change-order –

+1

我所做的是一个多步骤的过程:(1)找到所有外来的(2)删除所有外键约束,(3)将所有主键放在受影响的表上,(4)在这些表上创建新的“ID INT”列,使它们成为该表上的群集主键,以及(5)恢复外键约束。这可以很容易地脚本 –

回答

0

将所有上述链接的部分组合在一起后,我想出了这个脚本,为了答案而简化了。

表变化

JOB 
Id Guid PK 
Name nvarchar 
CreationDate datetime 

REPORT 
Id Guid PK 
JobId int 
Name nvarchar 
CreationDate datetime 

SCRIPT

-- Create new Job table with new Id column 
select JobId = IDENTITY(INT, 1, 1), Job.* 
into Job2 
from Job 
order by CreationDate 


-- Add new JobId column to Report 
alter table Report add JobId2 int 

-- Populate new JobId column 
update Report 
set Report.JobId2 = Job2.JobId 
from Job2 
where Report.JobId = Job2.Id 

-- Delete Old Id 
ALTER TABLE Job2 DROP COLUMN Id 

-- Delete Relationships 
ALTER TABLE Report DROP CONSTRAINT [FK_Report_Job] 
ALTER TABLE Job DROP CONSTRAINT PK_Job 

-- Create Relationships 
ALTER TABLE [dbo].[Job2] ADD CONSTRAINT [PK_Job] PRIMARY KEY CLUSTERED 
([JobId] ASC) 
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY] 

ALTER TABLE [dbo].[Report] WITH CHECK ADD CONSTRAINT [FK_Report_Job] FOREIGN KEY([JobId2]) 
REFERENCES [dbo].[Job2] ([JobId]) 
ON DELETE CASCADE 
ALTER TABLE [dbo].[Report] CHECK CONSTRAINT [FK_Report_Job] 


-- Rename Columns 
sp_RENAME 'Report.JobId', 'OldJobId' , 'COLUMN' 
sp_RENAME 'Report.JobId2', 'JobId' , 'COLUMN' 

-- Rename Tables 
sp_rename Job, Job_Old 
sp_rename Job2, Job 

之前,我创建的作业2台,因为这意味着我没有(从删除关系分开)接触到原件工作表,所以如果出现问题,一切都可以很容易地恢复到原来的状态。