sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man lagrar historiska poster i en historiktabell i SQL Server

I grund och botten vill du spåra/granska ändringar i en tabell samtidigt som den primära tabellen håller liten storlek.

Det finns flera sätt att lösa detta problem. Nackdelarna och fördelarna med varje sätt diskuteras nedan.

1 - Revision av tabellen med triggers.

Om du funderar på att granska tabellen (infogar, uppdateringar, raderingar), titta på min hur man förhindrar oönskade transaktioner - SQL Saturday slide deck w/code - http://craftydba.com/?page_id=880. Triggern som fyller granskningstabellen kan innehålla information från flera tabeller, om du väljer, eftersom data sparas som XML. Därför kan du ta bort en åtgärd om det behövs genom att analysera XML. Den spårar vem och vad som gjorde förändringen.

Alternativt kan du ha granskningstabellen på sin egen filgrupp.

Description:
    Table Triggers For (Insert, Update, Delete)
    Active table has current records.
    Audit (history) table for non-active records.

Pros:
    Active table has smaller # of records.
    Index in active table is small.
    Change is quickly reported in audit table.
    Tells you what change was made (ins, del, upd)

Cons:
    Have to join two tables to do historical reporting.
    Does not track schema changes.

2 - Effektiv datering av journalerna

Om du aldrig kommer att rensa data från granskningstabellen, varför inte markera raden som raderad men behålla den för alltid? Många system som människor soft använder effektiv dejting för att visa om en post inte längre är aktiv. I BI-världen kallas detta en typ 2-dimensionell tabell (långsamt ändrande dimensioner). Se artikeln om datalagerinstitutet. http://www.bidw.org/datawarehousing/scd-type-2/ Varje post har ett start- och slutdatum.

Alla aktiva poster har ett slutdatum på null.

Description:
    Table Triggers For (Insert, Update, Delete)
    Main table has both active and historical records.

Pros:
    Historical reporting is easy.
    Change is quickly shown in main table.

Cons:
    Main table has a large # of records.
    Index of main table is large.
    Both active & history records in same filegroup.
    Does not tell you what change was made (ins, del, upd)
    Does not track schema changes.

3 - Ändra datainsamling (företagsfunktion).

Micorsoft SQL Server 2008 introducerade funktionen för ändring av datainsamling. Även om detta spårar dataförändringar (CDC) med hjälp av en LOG-läsare i efterhand, saknas saker som vem och vad som gjorde förändringen. MSDN-detaljer - http://technet.microsoft.com/en-us/library/bb522489(v=sql.105).aspx

Denna lösning är beroende av CDC-jobben som körs. Eventuella problem med sql-agenten kommer att orsaka förseningar när data visas.

Se ändra datainsamlingstabeller.http://technet.microsoft.com/en-us/library/bb500353(v=sql.105).aspx

Description:
    Enable change data capture

Pros:
    Do not need to add triggers or tables to capture data.
    Tells you what change was made (ins, del, upd) the _$operation field in 
    <user_defined_table_CT>
    Tracks schema changes.    

Cons:
    Only available in enterprise version.
    Since it reads the log after the fact, time delay in data showing up.
    The CDC tables do not track who or what made the change.
    Disabling CDC removes the tables (not nice)!
    Need to decode and use the _$update_mask to figure out what columns changed.

4 - Ändra spårningsfunktion (alla versioner).

Micorsoft SQL Server 2008 introducerade funktionen för ändringsspårning. Till skillnad från CDC kommer den med alla versioner; Det kommer dock med ett gäng TSQL-funktioner som du måste ringa för att ta reda på vad som hände.

Den designades för att synkronisera en datakälla med SQL-server via en applikation. Det finns en hel synkroniseringsram på TechNet.

http://msdn.microsoft.com/en-us/library/bb933874.aspxhttp://msdn.microsoft.com/en-us/library/bb933994.aspxhttp://technet.microsoft.com/en-us/ library/bb934145(v=sql.105).aspx

Till skillnad från CDC anger du hur länge ändringar varar i databasen innan de rensas. Infogar och raderingar registrerar inte heller data. Uppdateringar registrerar bara vilket fält som ändrats.

Eftersom du synkroniserar SQL-serverkällan till ett annat mål fungerar detta bra. Det är inte bra för granskning om du inte skriver ett periodiskt jobb för att ta reda på ändringar.

Du måste fortfarande lagra den informationen någonstans.

Description:
    Enable change tracking

Cons:
    Not a good auditing solution

De tre första lösningarna kommer att fungera för din revision. Jag gillar den första lösningen eftersom jag använder den flitigt i min miljö.

Med vänlig hälsning

John

Kodavsnitt från presentation (Autos Database)

-- 
-- 7 - Auditing data changes (table for DML trigger)
-- 


-- Delete existing table
IF OBJECT_ID('[AUDIT].[LOG_TABLE_CHANGES]') IS NOT NULL 
  DROP TABLE [AUDIT].[LOG_TABLE_CHANGES]
GO


-- Add the table
CREATE TABLE [AUDIT].[LOG_TABLE_CHANGES]
(
  [CHG_ID] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
  [CHG_DATE] [datetime] NOT NULL,
  [CHG_TYPE] [varchar](20) NOT NULL,
  [CHG_BY] [nvarchar](256) NOT NULL,
  [APP_NAME] [nvarchar](128) NOT NULL,
  [HOST_NAME] [nvarchar](128) NOT NULL,
  [SCHEMA_NAME] [sysname] NOT NULL,
  [OBJECT_NAME] [sysname] NOT NULL,
  [XML_RECSET] [xml] NULL,
 CONSTRAINT [PK_LTC_CHG_ID] PRIMARY KEY CLUSTERED ([CHG_ID] ASC)
) ON [PRIMARY]
GO

-- Add defaults for key information
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_CHG_DATE] DEFAULT (getdate()) FOR [CHG_DATE];
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_CHG_TYPE] DEFAULT ('') FOR [CHG_TYPE];
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_CHG_BY] DEFAULT (coalesce(suser_sname(),'?')) FOR [CHG_BY];
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_APP_NAME] DEFAULT (coalesce(app_name(),'?')) FOR [APP_NAME];
ALTER TABLE [AUDIT].[LOG_TABLE_CHANGES] ADD CONSTRAINT [DF_LTC_HOST_NAME] DEFAULT (coalesce(host_name(),'?')) FOR [HOST_NAME];
GO



--
--  8 - Make DML trigger to capture changes
--


-- Delete existing trigger
IF OBJECT_ID('[ACTIVE].[TRG_FLUID_DATA]') IS NOT NULL 
  DROP TRIGGER [ACTIVE].[TRG_FLUID_DATA]
GO

-- Add trigger to log all changes
CREATE TRIGGER [ACTIVE].[TRG_FLUID_DATA] ON [ACTIVE].[CARS_BY_COUNTRY]
  FOR INSERT, UPDATE, DELETE AS
BEGIN

  -- Detect inserts
  IF EXISTS (select * from inserted) AND NOT EXISTS (select * from deleted)
  BEGIN
    INSERT [AUDIT].[LOG_TABLE_CHANGES] ([CHG_TYPE], [SCHEMA_NAME], [OBJECT_NAME], [XML_RECSET])
    SELECT 'INSERT', '[ACTIVE]', '[CARS_BY_COUNTRY]', (SELECT * FROM inserted as Record for xml auto, elements , root('RecordSet'), type)
    RETURN;
  END

  -- Detect deletes
  IF EXISTS (select * from deleted) AND NOT EXISTS (select * from inserted)
  BEGIN
    INSERT [AUDIT].[LOG_TABLE_CHANGES] ([CHG_TYPE], [SCHEMA_NAME], [OBJECT_NAME], [XML_RECSET])
    SELECT 'DELETE', '[ACTIVE]', '[CARS_BY_COUNTRY]', (SELECT * FROM deleted as Record for xml auto, elements , root('RecordSet'), type)
    RETURN;
  END

  -- Update inserts
  IF EXISTS (select * from inserted) AND EXISTS (select * from deleted)
  BEGIN
    INSERT [AUDIT].[LOG_TABLE_CHANGES] ([CHG_TYPE], [SCHEMA_NAME], [OBJECT_NAME], [XML_RECSET])
    SELECT 'UPDATE', '[ACTIVE]', '[CARS_BY_COUNTRY]', (SELECT * FROM deleted as Record for xml auto, elements , root('RecordSet'), type)
    RETURN;
  END

END;
GO



--
--  9 - Test DML trigger by updating, deleting and inserting data
--

-- Execute an update
UPDATE [ACTIVE].[CARS_BY_COUNTRY]
SET COUNTRY_NAME = 'Czech Republic'
WHERE COUNTRY_ID = 8
GO

-- Remove all data
DELETE FROM [ACTIVE].[CARS_BY_COUNTRY];
GO

-- Execute the load
EXECUTE [ACTIVE].[USP_LOAD_CARS_BY_COUNTRY];
GO 

-- Show the audit trail
SELECT * FROM [AUDIT].[LOG_TABLE_CHANGES]
GO

-- Disable the trigger
ALTER TABLE [ACTIVE].[CARS_BY_COUNTRY] DISABLE TRIGGER [TRG_FLUID_DATA];

** Utseende och känsla av revisionstabell **



  1. SQL SELECT för nybörjare

  2. Skiftlägeskänslig sortering i MySQL

  3. 3 sätt att konvertera HEX till INT i SQL Server (T-SQL)

  4. Definiera stegen för SQL Server Cursor - SQL Server / TSQL Tutorial