推荐 SQL 服务器 table 文件导入和处理设计

Recommended SQL Server table design for file import and processing

我有一个场景,文件将上传到数据库 table (dbo.FileImport),文件的每一行都在一个新行中。每行将包含行数据和它来自的文件的名称。文件名是唯一的,但可能包含几百万行。 table 中可能同时存在多个文件的数据。

处理每个文件并将结果存储在单独的 table 中。处理完与文件相关的数据后,从导入中删除数据 table 以防止 table 无限增长。

table结构如下:

CREATE TABLE [dbo].[FileImport] (
        [Id]             BIGINT         IDENTITY (1, 1) NOT NULL,
        [FileName]       VARCHAR (100)  NOT NULL,
        [LineData]      NVARCHAR (300) NOT NULL
    );

在处理过程中,相关文件的数据通过以下查询加载:

SELECT [LineData] FROM [dbo].[FileImport] WHERE [FileName] = @FileName

然后用下面语句删除:

DELETE FROM [dbo].[FileImport] WHERE [FileName] = @FileName

我的问题是关于 table 设计的性能和寿命...

如有任何建议或想法,我们将不胜感激。欢迎有主见的设计 ;-)


更新2017-12-10 我没有提到文件的行可能不是唯一的。因此,如果这会影响推荐,请考虑这一点。

答案中的示例脚本将是一个额外的好处! ;-)

Is it necessary to have the [Id] column if I never use it (I am concerned about running out of numbers in the Identity eventually too)?

不必有未使用的列。这不是关系 table 并且不会被外键引用,因此可以使参数成为主键是不必要的。

我不会担心 运行宁出 64 位整数值。 bigint 最多可容纳正值 36,028,797,018,963,967。如果每秒加载 10 亿行,运行 需要几个世纪的时间。

Should I add a PRIMARY KEY Constraint to the [Id] column?

我会在 FileName 和 ID 上创建一个复合集群主键。这将提供增量值以方便按插入顺序检索行,并且 FileName 最左边的键列将大大有利于您的查询。

Should I have a CLUSTERED or NONCLUSTERED index for the [FileName] column?

见上文。

Should I be making use of NOLOCK whenever I query this table (it is updated very regularly)?

没有。假设您按 FileName 查询,只有请求的行将与建议的主键接触。

Would there be concern of fragmentation with the continual adding and deleting of data to/from this table? If so, how should I handle this?

增量键避免碎片。

编辑:

这是 table 的建议 DDL:

CREATE TABLE dbo.FileImport (
      FileName VARCHAR (100) NOT NULL
    , RecordNumber BIGINT NOT NULL IDENTITY
    , LineData NVARCHAR (300) NOT NULL
    CONSTRAINT PK_FileImport PRIMARY KEY CLUSTERED(FileName, RecordNumber)
    );

这是我将如何做的粗略草图

CREATE TABLE [FileImport].[FileName] (
        [FileId]             BIGINT         IDENTITY (1, 1) NOT NULL,
        [FileName]       VARCHAR (100)  NOT NULL
    );
go

alter table [FileImport].[FileName]
add constraint pk_FileName primary key nonclustered (FileId)
go

create clustered index  cix_FileName on [FileImport].[FileName]([FileName])
go


CREATE TABLE [FileImport].[LineData] (
        [FileId]       VARCHAR (100)  NOT NULL,
        [LineDataId]             BIGINT         IDENTITY (1, 1) NOT NULL,
        [LineData]      NVARCHAR (300) NOT NULLL.
    constraint fk_LineData_FileName foreign key (FileId) references [FileImport].[FileName](FIleId)
    );

alter table [FileImport].[LineData]
add constraint pk_FileName primary key clustered (FileId, LineDataId)
go

这是一些标准化,因此您不必每次都引用完整的文件名 - 您可能不必这样做(如果您不想这样做,只需将 FileName 移到第二个 table 而不是 FileId 并将索引聚类在 (FileName, LeneDataId)) 上,但由于我们使用的是关系数据库......
不需要任何额外的索引 - table 由正确的键

排序

Should I be making use of NOLOCK whenever I query this table (it is updated very regularly)?

如果您的数据对您有任何意义,请不要使用它。事实上,如果您必须使用它,这很重要 - 您的数据库架构确实存在问题。它的索引方式 SQL 服务器将使用非常快的 Seek 操作。

Would there be concern of fragmentation with the continual adding and deleting of data to/from this table? If so, how should I handle this?

您可以设置一个 maintenance job 来重建您的索引,并且 运行 每晚使用 Agent(或其他)