Sql-Server-2008-R2

Active Directory 組作為 SQL Server 中的架構

  • November 14, 2015

在 SQL Server 2008 R2 中,我們有一個由開發人員團隊維護的數據庫。他們每個人都應該有權執行 DDL 操作,例如添加列或創建表。但是,我們確實希望記錄開發人員完成的所有 DDL 操作。

由於審核不力,無法為每個人使用一個使用者,使用多個使用者(Active Directory 使用者)會導致他們的表具有單獨的架構名稱,這很不整潔。

有沒有辦法使用 Active Directory 組作為架構來享受這兩個世界?

不,Active Directory 組不能是架構,儘管我想您可以使用與 AD 組相同的文本命名架構,但這不會讓您獲得更多的可審核性。

如果單個登錄名都是 AD 組的成員,則預設情況下它們仍會作為其登錄名出現在數據庫中,而不是 AD 組名。(當然,您可以將數據庫使用者重命名為不同的名稱,但我看不出這對您有什麼幫助。)

但是,使用“多個使用者”(即每人一個登錄名和一個使用者)並不意味著他們都將創建自己的模式。您對這種行為有相當大的控制權。

創建使用者時,您可以將它們分配給預設架構,例如dbo. 同樣,如果您需要在事後進行設置,您可以:

ALTER USER userName  
    WITH DEFAULT_SCHEMA = schemaName

此外,您可以創建一個審計表並使用 DDL 觸發器通過跟踪您想了解的詳細資訊來跟踪對數據庫所做的更改。您還可以過濾掉令人討厭的更改,例如禁用和啟用索引等。

範例 DDL 審計觸發器:

CREATE TRIGGER [AuditDDLChanges] 
   ON DATABASE 
FOR DDL_DATABASE_LEVEL_EVENTS 
AS
SET NOCOUNT ON
DECLARE @Data XML

DECLARE 
   @EventType NVARCHAR(128),
   @DatabaseName NVARCHAR(128),
   @SchemaName NVARCHAR(128),
   @ObjectName NVARCHAR(128),
   @ObjectType NVARCHAR(128),
   @LoginName NVARCHAR(128),
   @TSQLCommand NVARCHAR(MAX),
   @IgnoreMarker NVARCHAR(1)

SET @Data = EVENTDATA()

SELECT 
   @DatabaseName = @data.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'nvarchar(128)'),
   @SchemaName =   @data.value('(/EVENT_INSTANCE/SchemaName)[1]',   'nvarchar(128)'),
   @ObjectName =   @data.value('(/EVENT_INSTANCE/ObjectName)[1]',   'nvarchar(128)'),
   @ObjectType =   @data.value('(/EVENT_INSTANCE/ObjectType)[1]',   'nvarchar(128)'),
   @EventType =    @data.value('(/EVENT_INSTANCE/EventType)[1]',    'nvarchar(128)'),
   @LoginName =    @data.value('(/EVENT_INSTANCE/LoginName)[1]',    'nvarchar(128)'),
   @TSQLCommand =  @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]',  'nvarchar(max)')

-- Clause to avoid tracking things you do not want in the event table
IF ( (IS_SRVROLEMEMBER('sysadmin',@LoginName) = 1) OR
    (@EventType LIKE '%STATISTICS') 
  )
  BEGIN
     SELECT @IgnoreMarker = 1 
  END
ELSE
  BEGIN
       INSERT AuditDatabase.dbo.ChangeLog
          (EventType, 
           PostTime,
           SPID,
           ServerName,
           LoginName,
           UserName,
           DatabaseName,
           SchemaName,
           ObjectName,
           ObjectType,
           TSQLCommand) 
          VALUES 
          (@data.value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(128)'), 
           @data.value('(/EVENT_INSTANCE/PostTime)[1]', 'datetime'), 
           @data.value('(/EVENT_INSTANCE/SPID)[1]', 'int'), 
           @data.value('(/EVENT_INSTANCE/ServerName)[1]', 'nvarchar(128)'), 
           @data.value('(/EVENT_INSTANCE/LoginName)[1]', 'nvarchar(128)'), 
           @data.value('(/EVENT_INSTANCE/UserName)[1]', 'nvarchar(128)'), 
           @data.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'nvarchar(128)'), 
           @data.value('(/EVENT_INSTANCE/SchemaName)[1]', 'nvarchar(128)'), 
           @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(128)'), 
           @data.value('(/EVENT_INSTANCE/ObjectType)[1]', 'nvarchar(128)'), 
           @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(max)') ) ;
     END
GO

引用自:https://dba.stackexchange.com/questions/121046