创建结构良好的大型SQL数据库

时间:2017-08-18 14:05:57

标签: sql database normalization

我有一个包含所有服务器的Windows事件日志的表(从日志服务器中提取)。

起初这没关系,因为我把更多的数据放进去,它变得越慢......现在已经有数百万行了。

所以我认为将每个服务器分解为自己的表会更好,这样可以更快地进行特定的查询。

问题是,如果我想在所有服务器上搜索事件怎么办?

所以我来这里就如何正确设置表格提出一些建议。

下面是CREATE TO ..复制和粘贴每个表的结构,用实际名称替换'server1'。

        USE [Events_Data]
    GO

    /****** Object:  Table [dbo].[servername1]    Script Date: 8/18/2017 8:48:59 AM ******/
    SET ANSI_NULLS ON
    GO

    SET QUOTED_IDENTIFIER ON
    GO

    CREATE TABLE [dbo].[servername1](
        [Message] [nvarchar](max) NULL,
        [Id] [nvarchar](max) NULL,
        [Version] [nvarchar](max) NULL,
        [Qualifiers] [nvarchar](max) NULL,
        [Level] [nvarchar](max) NULL,
        [Task] [nvarchar](max) NULL,
        [Opcode] [nvarchar](max) NULL,
        [Keywords] [nvarchar](max) NULL,
        [RecordId] [nvarchar](max) NULL,
        [ProviderName] [nvarchar](max) NULL,
        [ProviderId] [nvarchar](max) NULL,
        [LogName] [nvarchar](max) NULL,
        [ProcessId] [nvarchar](max) NULL,
        [ThreadID] [nvarchar](max) NULL,
        [MachineName] [nvarchar](max) NULL,
        [UserID] [nvarchar](max) NULL,
        [TimeCreated] [datetime] NULL,
        [ActivityId] [nvarchar](max) NULL,
        [RelatedActivityID] [nvarchar](max) NULL,
        [ContainerLog] [nvarchar](max) NULL,
        [MatchedQueryIDs] [nvarchar](max) NULL,
        [Bookmark] [nvarchar](max) NULL,
        [LevelDisplayName] [nvarchar](max) NULL,
        [OpcodeDisplayName] [nvarchar](max) NULL,
        [TaskDisplayName] [nvarchar](max) NULL,
        [KeywordsDisplayNames] [nvarchar](max) NULL,
        [Properties] [nvarchar](max) NULL
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

    GO

我从服务器附加了一行数据......除了'machinename'列特定于表保存事件的服务器之外,每个表都非常相似。

Message,Id,Version,Qualifiers,Level,Task,Opcode,Keywords,RecordId,ProviderName,ProviderId,LogName,ProcessId,ThreadID,MachineName,UserID,TimeCreated,ActivityId,RelatedActivityID,ContainerLog,MatchedQueryIDs,Bookmark,LevelDisplayName,OpcodeDisplayName,TaskDisplayName,KeywordsDisplayNames,Properties
Error message whatever,1000,,0,2,100,,3.60288E+16,302366,Application Error,,Application,,,servernameapp1.domain.com,,00:03.0,,,\\servernamelogs\d$\windows-logs\archive-forwardedevents-2017-04-01-05-03-29-167.evtx,,System.Diagnostics.Eventing.Reader.EventBookmark,Error,Info,Application Crashing Events,Classic,System.Diagnostics.Eventing.Reader.EventProperty System.Diagnostics.Eventing.Reader.EventProperty System.Diagnostics.Eventing.Reader.EventProperty System.Diagnostics.Eventing.Reader.EventProperty System.Diagnostics.Eventing.Reader.EventProperty System.Diagnostics.Eventing.Reader.EventProperty System.Diagnostics.Eventing.Reader.EventProperty System.Diagnostics.Eventing.Reader.EventProperty System.Diagnostics.Eventing.Reader.EventProperty System.Diagnostics.Eventing.Reader.EventProperty System.Diagnostics.Eventing.Reader.EventProperty System.Diagnostics.Eventing.Reader.EventProperty System.Diagnostics.Eventing.Reader.EventProperty

有关创建结构良好的数据库的任何帮助,我都可以查询所有表格,非常感谢!

1 个答案:

答案 0 :(得分:1)

WOW。这有很多不妥之处,但作为一个开始:

  1. 在最常用的Key列或人工键上创建主键和聚簇索引(在这种情况下看起来像id?)
  2. 更改您的数据类型... Varchar(MAX)是一个无限长度的字符串...可能您的Id列应该是Ints和事件字符串列限制为其合理的最大长度。
  3. 将所需列设为不可为空的
  4. 在任何连接/排序/列
  5. 上创建非聚集索引

    为每个服务器创建一个表。只需在ServerId列上创建一个索引......

    P.S。你确定你需要所有这些专栏吗?你是如何插入它们的?一些看起来他们只是输入对象的类型,例如。最后一列中的System.Diagnostics.Eventing.Reader.EventProperty。您可能需要.ToString()或其他东西来获取实际值。但我会质疑你是否真的需要所有这些专栏。