2017-08-18 1 views
-1

Je disposais d'une seule table contenant tous les journaux d'événements Windows de notre serveur (extraits d'un serveur de journalisation).Création d'une base de données SQL volumineuse et bien structurée

Au début c'était correct, car j'ai mis plus de données dedans, plus il est lent ... Il y a maintenant des millions de lignes.

Alors j'ai pensé qu'il serait préférable de décomposer chaque serveur à sa propre table, ce qui rend l'interrogation spécifique beaucoup plus rapide.

Le problème est: que se passe-t-il si je veux rechercher un événement sur tous les serveurs?

Alors je viens ici pour quelques conseils sur la façon de configurer correctement mes tables. Vous trouverez ci-dessous un copier-coller de la structure de chaque table, en remplaçant 'serveur1' par le nom réel.

 
     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 

J'ai joint une ligne de données à partir d'un serveur ... chaque table est très similaire, sauf la colonne « machinename » est spécifique au serveur que la table contient les événements.

 
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 

Toute aide sur la création d'une base de données bien structuré que je peux interroger sur toutes les tables serait grandement appréciée!

+1

Je ne pense pas qu'il est sage de décomposer chaque serveur dans sa propre table. Si quelque chose vous devriez avoir une table pour 'servers' et une table pour' logs'. Vous affectez ensuite une sortie 'log' à un' serveur' basé sur la clé étrangère 'server_id'. Cela vous permettrait d'afficher uniquement les journaux pour un serveur spécifique. –

+0

Les trois mots clés les plus importants: * type de données *, * nullable * et * index *. Et non: ne divisez pas cela en plusieurs tables! – Shnugo

+0

Comme les autres personnes l'ont dit, vous ne devriez pas diviser les tables. Toutefois, si vous interrogez généralement un seul serveur, cela constitue un cas d'utilisation typique pour le partitionnement. –

Répondre

1

WOW. Tant de choses mal à cela, mais comme un début:

  1. Créer un index de clé et en cluster primaire sur la plus couramment utilisée colonne clé (s) ou la clé artificielle (? Ressemble id dans ce cas)
  2. Modifier vos types de données ... Varchar (MAX) est une chaîne de longueur illimitée ... Vos colonnes Id devraient probablement être des colonnes Ints et des chaînes d'événements limitées à leur longueur maximale raisonnable.
  3. faire des colonnes obligatoires index non annulable
  4. Créer non-cluster sur une jointure/trier/où les colonnes

Est-ce pas créer une table pour chaque serveur. Il suffit de créer un index sur la colonne ServerId ...

P.S. Etes-vous sûr que vous avez besoin de toutes ces colonnes? Comment les insérez-vous? Quelques-uns ont l'air d'entrer simplement le type de l'objet, par exemple. System.Diagnostics.Eventing.Reader.EventProperty dans la dernière colonne. Vous avez probablement besoin d'un .ToString() ou quelque chose pour obtenir la valeur réelle. Mais je me demande si vous avez vraiment besoin de toutes ces colonnes.

+0

Je suis heureux de savoir que je suis sur le même genre de longueur d'onde que quelqu'un d'autre sur cette question, réponse décente. –

+0

D'accord! Un point supplémentaire est que si pour une raison quelconque les données doivent être découpées par serveur (ou par date ou type d'événement ou autre), utilisez le partitionnement et laissez le moteur de base de données s'occuper des mécanismes pour vous. Toujours un dernier recours dans la plupart des cas. – LoztInSpace