SQL - 从旧结构到新结构的复杂数据迁移

时间:2015-12-29 20:22:44

标签: sql sql-server tsql

好的,所以这是一个有趣的问题......

我想将数据从 OldApplicationLogs 表移到两个表中:

  1. UserSessionLogs
  2. ApplicationLogs
  3. 这是OldApplicationLogs的结构:

    ID INT-PK
    UserID INT-FK
    PropertyID INT-FK
    Controller VARCHAR
    Action VARCHAR
    EntityType VARCHAR
    EntityKey VARCHAR
    AbsoluteURL VARCHAR
    IPAddress VARCHAR
    ...
    

    这些是我试图将其转化为的新结构:

    UserSessionLogs

    ID INT-PK
    UserID INT-FK
    PropertyID INT-FK
    IPAddress INT-FK
    ...
    

    ApplicationLogs

    ID INT-PK
    UserSessionLogID INT-FK
    EntityID INT-FK
    EntityKey INT
    Controller VARCHAR
    Action VARCHAR
    RelativeURL VARCHAR
    Created VARCHAR
    ...
    

    现在我想到的方法是:

    1. 将所有唯一的UserID,PropertyID,IPAddress视为一行 UserSessionLogs。
    2. 将数据从旧的应用程序日志结构移动到新的日志结构。
    3. 这是我开始编写的SQL语句......

      推荐给您的SQL代码http://kendtimothy.com/static/logs_so_30-12-2015.pdf

      否则,这是SQL代码:

      1. 将每个用户事件的过去数据映射为一个用户会话。

        SELECT 
            ID, PropertyID, UserID, IPAddress INTO UserSessionLogs 
        FROM
            OldApplicationLogs
        GROUP BY 
            PropertyID, UserID, IPAddress
        
      2. 问题1:遍历结果并插入UserSessionLogs。

        INSERT INTO UserSessionLogs (PropertyID, IPAddress, UserID, StartDate)
        VALUES (UserSessionLogs.PropertyID, UserSessionLogs.IPAddress, UserSessionLogs.UserID)
        
        1. 将所有应用程序日志的过去数据映射到新结构。

          SELECT * 
          INTO AppLogs 
          FROM OldApplicationLogs
          
        2. 问题2:同样,我需要遍历结果并插入ApplicationLogs

          INSERT INTO ApplicationLogs (UserSessionLogID, [Action], Controller, Operation, Created, EntityID, EntityKey, RelativeURL)
          VALUES (
          

          问题3:如何获得UserIDPropertyIDUserID组合匹配的相关IPAddress

          UserSessions.ID,
          AppLogs.Action,
          AppLogs.Controller,
          AppLogs.Operation,
          AppLogs.LoggedDate
          

          获取具有相同表名的EntityID

          (SELECT TableName 
           FROM Entities 
           WHERE AppLogs.EntityType = Entities.TableName),
          

          将之前的VARCHAR EntityKey投放到INT?的EntityKey。保持原样。

          CAST(AppLogs.EntityKey AS INT),
          

          将绝对URL(从过去的结构)转换为相对URL。

          问题4 /建议:任何有关更好方法的建议都是超级欢迎:)

          REPLACE(AppLogs.AbsoluteURL, 'www.myapp.com/', '')
          )
          

          我真的很感激这方面的帮助/建议,欢呼:)

1 个答案:

答案 0 :(得分:1)

这里不需要循环。在处理数据集时,SQL是最好的。

如果没有表格的完整DDL,这可能会有所不同。

INSERT INTO [UserSessionLogs]([PropertyID], [IPAddress], [UserID])
SELECT [PropertyID], [UserID], [IPAddress]
FROM [OldApplicationLogs]
GROUP BY [PropertyID], [UserID], [IPAddress];

INSERT INTO [ApplicationLogs]([UserSessionLogID], [Action], [Controller], [Operation], [Created], [EntityID], [EntityKey], [RelativeURL])
SELECT 
    B.[ID],
    A.[Action], 
    A.[Controller],
    A.[Operation],
    A.[LoggedDate],
    C.[TableName],
    CAST(A.[EntityKey] AS INT),
    REPLACE(A.[AbsoluteURL],'www.myapp.com/','')
FROM [OldApplicationLogs] A
INNER JOIN [UserSessionLogs] B
ON      A.[UserID] = B.[UserID]
LEFT JOIN [Entities] C
ON      A.[EntityType] = C.[TableName]

根据C.[TableName]的定义,ApplicationLogs似乎是VARCHAR而不是ID。也许您打算使用EntityID代替TableName