Table 反规范化

Table denormalization

我必须对现有 table 进行反规范化并保存所有已存在的数据。 以前我的 table 结构是

TABLE A:
[id] INT IDENTITY(1,1)
[name] NVARCHAR(100)
[countryID] INT

TABLE B:
[id] INT IDENTITY(1,1)
[countryName] NVARCHAR(100)

新表A结构:

TABLE A:
[id] INT IDENTITY(1,1)
[name] NVARCHAR(100)
[countryName] NVARCHAR(100)

不知道有没有比这个更优雅的解决方案

--BACKUP TABLE TO VARIABLE
DECLARE @backup TABLE (
            [Id] INT NOT NULL,
            [Name] NVARCHAR (1000) NOT NULL,
            [CountryId] INT NULL,
INSERT INTO @backup SELECT * FROM [dbName].[TableA]

--RECREATE THE TABLE WITH NEW STRUCTURE
DROP TABLE [dbName].[TableA]
CREATE TABLE [dbName].[TableA]
        (
            [Id] INT IDENTITY(1, 1) NOT NULL,
            [Name] NVARCHAR (1000) NOT NULL,
            [CountryId] NVARCHAR (100) NULL,
            CONSTRAINT [PK_TableA] PRIMARY KEY CLUSTERED 
            (
                [Id] ASC
            ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]

SET IDENTITY_INSERT [dbName].[TableA] ON --Required to save original Id's

--INSERT DATA FROM BACKUP TABLE
INSERT INTO [dbName].[TableA]([Id],[Name],[CountryId])
SELECT 
backup.[Id],
backup.[Name],
[dbName].[TableB].[Name],
FROM @backup backup
LEFT JOIN [dbName].[TableB] on backup.[CountyId] = [dbName].[TableB].[Id]

SET IDENTITY_INSERT [dbName].[TableA] ON

不同的人可能会有不同的选择。但对我来说,我会选择这个步骤来做同样的事情-

  1. 备份Table-A
  2. 更改 Table-A 并添加新列 "countryName"
  3. 通过左连接 Table-B
  4. 更新 countryName 列中的数据
  5. 将 Table-A 更改为删除列 "countryID"
  6. 删除 Table-B(根据要求)

注意:我会选择更改 Table-A 选项只是为了避免在数据丢失的情况下恢复 table。

我会对你的解决方案持谨慎态度。它不是 thread-safe(也就是说,如果其他线程正在修改 table,您可能会丢失数据)。如果数据库出现问题,您还 运行 有丢失备份 table 的风险——假设数据库在 drop 之后但在 insert 之前出现故障。

您实际上只是向 TableA 添加了一个新列。那么,你可以直接这样做:

alter tableA add column countryName varchar(100);

update a
    set countryName = b.countryName
    from tableA a join
         tableB b
         on a.CountyId = b.id;

这两个应该是数据库中的"safe"操作。在执行它们之前,我仍然会备份生产数据库。但是,他们应该没问题。

需要注意的是,如果 TableA 真的很大,更改 table 可能需要一些时间。在生产中更改 table 之前,您可能想在 development/staging 盒子上进行测试。