Sql-Server-2008-R2
Active Directory 組作為 SQL Server 中的架構
在 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