用数据表中的 ID 替换名称的快速方法?

Fast Way to Replace Names with Ids in Datatable?

我有一个非常大的 CSV 文件,我必须定期加载它,其中包含时间序列数据。 headers 的示例如下:

| SiteName | Company | Date | ResponseTime | Clicks |

此数据来自上传者外部的服务。 SiteNameCompany 都是字符串字段。在数据库中,这些是标准化的。有一个Sitetable和一个Companytable:

CREATE TABLE [dbo].[Site] (
    [Id] INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
    [Name] NVARCHAR(MAX) NOT NULL
)

CREATE TABLE [dbo].[Company] (
    [Id] INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
    [Name] NVARCHAR(MAX) NOT NULL
)

还有数据table。

CREATE TABLE [dbo].[SiteStatistics] (
    [Id] INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
    [CompanyId] INT NOT NULL,
    [SiteId] INT NOT NULL,
    [DataTime] DATETIME NOT NULL,
    CONSTRAINT [SiteStatisticsToSite_FK] FOREIGN KEY ([SiteId]) REFERENCES [Site]([Id]),
    CONSTRAINT [SiteStatisticsToCompany_FK] FOREIGN KEY ([CompanyId]) REFERENCES [Company]([Id])
)

CSV 文件中大约有 200 万行,任何类型的 IO-bound 迭代都不起作用。我需要在几分钟内完成,而不是几天。

我最初的想法是我可以 pre-load SiteCompany 到数据表中。我已经将 CSV 以与 CSV 列匹配的格式加载到数据 table 中。我现在需要用 Site 的 Id 字段替换每个 SiteName,用 Company 的 Id 字段替换每个 Company。处理此问题最快、最有效的方法是什么?

如果您使用预加载网站和公司,您可以使用代码获得不同的值:

DataView view = new DataView(table);
DataTable distinctCompanyValues = view.ToTable(true, "Company")

DataView view = new DataView(table);
DataTable distinctSiteValues = view.ToTable(true, "Site")

然后使用 Sql-Bulk-Copy 将这两个数据表加载到它们的 SQL 表中。


接下来将所有数据转储到:

CREATE TABLE [dbo].[SiteStatistics] (
    [Id] INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
    [CompanyId] INT DEFAULT  0,
    [SiteId] INT DEFAULT 0,
    [Company] NVARCHAR(MAX) NOT NULL,
    [Site] NVARCHAR(MAX) NOT NULL,
    [DataTime] DATETIME NOT NULL
)

然后执行更新以设置参照完整性字段:

UPDATE [SiteStatistics] ss SET
[CompanyId] = (SELECT Id FROM [Company] c Where ss.[Company] = c.Name),
[SiteId] = (SELECT Id FROM [Site] s Where ss.[Site] = s.Name)

添加外键约束:

ALTER TABLE [SiteStatistics] ADD CONSTRAINT [SiteStatisticsToSite_FK] FOREIGN KEY ([SiteId]) REFERENCES [Site]([Id])
ALTER TABLE [SiteStatistics] ADD CONSTRAINT [SiteStatisticsToCompany_FK] FOREIGN KEY ([CompanyId]) REFERENCES [Company]([Id])


最后从 SiteStatistics 中删除站点和公司名称字段:

ALTER TABLE [SiteStatistics] DROP COLUMN [Company];
ALTER TABLE [SiteStatistics] DROP COLUMN [Site];