sql >> Databáze >  >> RDS >> Sqlserver

Jak ukládat historické záznamy do tabulky historie na SQL Server

V podstatě chcete sledovat/auditovat změny v tabulce a zároveň zachovat velikost primární tabulky.

Existuje několik způsobů, jak tento problém vyřešit. Nevýhody a výhody každého způsobu jsou popsány níže.

1 – Audit tabulky se spouštěči.

Pokud chcete provést audit tabulky (vkládání, aktualizace, mazání), podívejte se na můj návod, jak zabránit nechtěným transakcím - SQL Saturday slide deck w/code - http://craftydba.com/?page_id=880. Spouštěč, který vyplňuje tabulku auditu, může obsahovat informace z více tabulek, pokud se rozhodnete, protože data jsou uložena jako XML. Proto můžete v případě potřeby zrušit odstranění akce analýzou XML. Sleduje, kdo a co provedl změnu.

Volitelně můžete mít tabulku auditu ve vlastní skupině souborů.

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 – Efektivní datování záznamů

Pokud se nikdy nechystáte vymazat data z auditní tabulky, proč neoznačit řádek jako odstraněný, ale ponechat jej navždy? Mnoho systémů, jako jsou lidé soft, používá efektivní seznamování, aby ukázalo, zda záznam již není aktivní. Ve světě BI se tomu říká rozměrová tabulka typu 2 (pomalu se měnící rozměry). Viz článek institutu datového skladu. http://www.bidw.org/datawarehousing/scd-type-2/ Každý záznam má počáteční a koncové datum.

Všechny aktivní záznamy mají koncové datum 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 – Změna sběru dat (funkce Enterprise).

Microsoft SQL Server 2008 představil funkci sběru dat změn. I když to následně sleduje změnu dat (CDC) pomocí čtečky LOG, postrádá věci jako kdo a co provedl změnu. Podrobnosti MSDN – http://technet.microsoft.com/en-us/library/bb522489(v=sql.105).aspx

Toto řešení závisí na spuštěných úlohách CDC. Jakékoli problémy s agentem SQL způsobí zpoždění v zobrazování dat.

Viz tabulky zachycení změn dat.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 – Změna funkce sledování (všechny verze).

Microsoft SQL Server 2008 představil funkci sledování změn. Na rozdíl od CDC se dodává se všemi verzemi; Dodává se však se spoustou funkcí TSQL, které musíte zavolat, abyste zjistili, co se stalo.

Byl navržen pro účely synchronizace jednoho zdroje dat s SQL serverem prostřednictvím aplikace. Na TechNet funguje celý synchronizační rámec.

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

Na rozdíl od CDC určujete, jak dlouho změny v databázi potrvají, než budou vymazány. Také vkládání a mazání nezaznamenávají data. Aktualizace pouze zaznamenávají, jaké pole se změnilo.

Protože synchronizujete zdroj SQL serveru s jiným cílem, funguje to dobře. Není dobré pro auditování, pokud nenapíšete pravidelnou úlohu, abyste zjistili změny.

Stále budete muset tyto informace někde uložit.

Description:
    Enable change tracking

Cons:
    Not a good auditing solution

První tři řešení budou pro váš audit fungovat. Líbí se mi první řešení, protože jej ve svém prostředí intenzivně používám.

S pozdravem

John

Úryvek kódu z prezentace (databáze Autos)

-- 
-- 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];

** Vzhled a chování tabulky auditu **



  1. Správa uživatelských účtů, role, oprávnění, autentizace PHP a MySQL

  2. CHYBA PostgreSQL:zrušení příkazu kvůli konfliktu s obnovou

  3. Zkrácení všech tabulek v databázi Postgres

  4. Oracle FOR LOOP REVERSE Příklad