Нормализация данных с помощью DISTINCT - PullRequest
2 голосов
/ 20 мая 2010

У меня есть 1 000 000 строк в месяц на ПК, генерируемых некоторыми программами мониторинга. Таблица DataToImport (временная) выглядит следующим образом:

EventID    int           NOT NULL   (Primary Key of denormalized table)
EventType  int           NOT NULL   -- A enumerated value
Computer   nvarchar(50)  NOT NULL   -- Usually computer name
When       DateTime      NOT NULL   
FileRef    int           NOT NULL   -- File generators reference 
FileDesc   nvarchar(100) NOT NULL   -- Humanly-readable description
FilePath   nvarchar(100) NOT NULL   -- Relative Path on disk

Я пытаюсь нормализовать эти данные в несколько таблиц:

Computer (UniqueID, Name)
File     (UniqueID, FileRef, FileDesc, FilePath)
Event    (ID, Type, ComputerUniqueID, When, FileUniqueID)

.. таким образом, что «Event» будет иметь миллион строк, но они достаточно малы, поэтому размер базы данных можно контролировать, а таблицы можно индексировать для производительности запросов:

-- Grab new computers
INSERT INTO Computer
SELECT [Computer] AS [Name]
FROM [DataToImport]
WHERE [DataToImport].[Computer] NOT IN (SELECT [Name] FROM [Computer])

-- Grab new files
INSERT INTO File
SELECT [FileRef], [FileDesc], [FilePath] 
FROM [DataToImport]
WHERE [FileRef] NOT IN (SELECT [FileRef] FROM File)

-- Normalize rows
INSERT INTO Event
SELECT [EventID], [EventType], [Computer].[UniqueID], [File].[UniqueID]
FROM [DataToImport]
  INNER JOIN [Computer] ON [DataToImport].[Computer] = [Computer].[Name]
  INNER JOIN [File] ON [DataToImport].[FileRef] = [File].[FileRef]

.. все это выглядит великолепно, за исключением того, что триплет (FileRef, FileDesc, FilePath) действительно является составным ключом, так как любой из трех элементов может различаться, и это представляет уникальную запись. Мне нужно извлечь различных триплетов, чтобы вставить их ...

-- Grab new distinct files
INSERT INTO File
SELECT DISTINCT [FileRef], [FileDesc], [FilePath] 
FROM [DataToImport]
WHERE [FileRef] NOT IN (errrrr....help!)

Как я могу убедиться, что уникальные строки файла нормализованы?

Ответы [ 2 ]

3 голосов
/ 20 мая 2010

Я бы использовал

INSERT [File] ([FileRef], [FileDesc], [FilePath])
 select distinct [FileRef], [FileDesc], [FilePath]
  from [DataToImport]
 except select [FileRef], [FileDesc], [FilePath]
  from [File]

... но я бы сначала сравнил его производительность с решением SELECT ... INTERSECT в Quassnoi.

3 голосов
/ 20 мая 2010
INSERT
INTO    File
SELECT  DISTINCT [FileRef], [FileDesc], [FilePath] 
FROM    [DataToImport] di
WHERE   NOT EXISTS
        (
        SELECT  di.FileRef, di.FileDesc, di.FilePath
        INTERSECT
        SELECT  FileRef, FileDesc, FilePath
        FROM    File
        )

Это не важно в вашем случае, но это также будет обрабатывать значения NULL как DISTINCT правильно, если столбцы обнуляются.

@ Philip Kelley * Хотя решение 1007 * более элегантно.

...