使用DISTINCT标准化数据

时间:2010-05-20 15:52:32

标签: sql normalization

我的每台PC每月有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)

..这样'事件'会有很多行,但是它们非常小,因此数据库大小是可管理的,并且可以为查询性能编制索引:

-- 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 个答案:

答案 0 :(得分:3)

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 的解决方案更优雅。

答案 1 :(得分:3)

我用

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

...但我会首先将其性能与Quassnoi的SELECT ... INTERSECT解决方案进行比较。