推荐 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 设计的性能和寿命...
- 如果我从不使用它,是否有必要拥有 [Id] 列(我担心最终身份中的数字也会 运行 )?
- 我应该向 [Id] 列添加 PRIMARY KEY 约束吗?
- [FileName] 列应该有 CLUSTERED 索引还是 NONCLUSTERED 索引?
- 每当我查询这个 table(它经常更新)时,我是否应该使用 NOLOCK?
- 这个table不断的增删数据to/from会不会有碎片的顾虑?如果是这样,我该如何处理?
如有任何建议或想法,我们将不胜感激。欢迎有主见的设计 ;-)
更新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(或其他)
我有一个场景,文件将上传到数据库 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 设计的性能和寿命...
- 如果我从不使用它,是否有必要拥有 [Id] 列(我担心最终身份中的数字也会 运行 )?
- 我应该向 [Id] 列添加 PRIMARY KEY 约束吗?
- [FileName] 列应该有 CLUSTERED 索引还是 NONCLUSTERED 索引?
- 每当我查询这个 table(它经常更新)时,我是否应该使用 NOLOCK?
- 这个table不断的增删数据to/from会不会有碎片的顾虑?如果是这样,我该如何处理?
如有任何建议或想法,我们将不胜感激。欢迎有主见的设计 ;-)
更新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(或其他)