我想知道,执行以下操作的最有效方法是什么?
我正在尝试实施某种审核系统,每次登录我的页面都会存储在数据库中。我使用SQL Server 2005数据库。存储审计数据的表显然不能没有上限。因此,它应该最多有1000个条目,然后在插入新条目时必须删除任何旧条目。问题是你如何以最有效的方式做到这一点 - 我是否需要添加任何特殊列,比如说一个序数条目号以便于清理?
编辑: 比如说,如果我的表的结构是(伪代码):
`id` BIGINT autoincrement
`date` DATETIME
`data1` NVARCHAR(256)
`data2` INT
你会如何编写这个清理程序?
答案 0 :(得分:1)
按日期而不是数字来做。看看你的统计数据,看看1000天/将会是多少天。删除任何旧版本。审计从来不是特别有效,但如果你有大量的数据无法帮助你效率很低......
答案 1 :(得分:1)
正如Tony所说,使用日期来识别插入内容。此外,在日期字段上使用聚簇索引,以便插入始终位于表的末尾,并且可以轻松有效地扫描和删除旧行。
如果使用数字,这样的事情应该有效:
DELETE FROM myTable WHERE someField < (SELECT MAX(someField) - 1000 FROM myTable)
对于某个日期,删除超过一天的所有内容将类似于:
DELETE FROM myTable WHERE someField < DateAdd('d', -1, getdate())
答案 2 :(得分:1)
如果我了解您的需求,这应该有效。我已经在SQL 2008R2上测试了它,但我看不出它为什么不适用于SQL Server 2005的任何原因。
使用登录触发器在审计表中插入一行。
在审计表上创建一个AFTER INSERT触发器,用于删除MIN(ID)行。
以下是一些可以使用的代码:
/ *创建审计表* /
CREATE TABLE ServerLogonHistory
(SystemUser VARCHAR(512),
ID BIGINT,
DBUser VARCHAR(512),
SPID INT,
LogonTime DATETIME)
GO
/ *创建登录触发器* /
CREATE TRIGGER Tr_ServerLogon
ON ALL SERVER FOR LOGON
AS
BEGIN
INSERT INTO TestDB.dbo.ServerLogonHistory
SELECT SYSTEM_USER, MAX(ID)+1 , USER,@@SPID,GETDATE()
FROM TestDB.dbo.ServerLogonHistory;
END
GO
/ *创建清理触发器* /
CREATE TRIGGER AfterLogin
ON TestDB.dbo.ServerLogonHistory
AFTER INSERT
AS
DELETE
FROM TestDB.dbo.ServerLogonHistory
WHERE ID =
(SELECT MIN(ID) FROM TestDB.dbo.ServerLogonHistory);
GO;
一句警告。如果您创建无效的登录触发器,您将无法登录到数据库。但不要惊慌!这都是学习的一部分。您将能够使用'sqlcmd'来删除错误的触发器。
我确实尝试在登录触发器中删除带有最小ID的行,但我无法使其工作。
答案 3 :(得分:1)
“ID”列是否为带有步骤1的标识列?
插入一行后
删除id为&lt; IDENTITY_CURRENT(YOUR_TABLE)-1000
的列