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

时间:2018-11-20 00:27:15

标签: c# sql sql-server sqlbulkcopy import-csv

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

| SiteName | Company | Date | ResponseTime | Clicks |

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

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
)

以及数据表。

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绑定迭代都将无法进行。我需要几分钟而不是几天。

我最初的想法是我可以将SiteCompany预加载到DataTables中。我已经以与CSV列匹配的格式将CSV加载到数据表中。我现在需要用SiteName的ID字段替换每个Site,并用Company的ID字段替换每个Company。最快,最有效的方法是什么?

1 个答案:

答案 0 :(得分:1)

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

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];