最有效的方法来维持SQL Server数据库表中的最大条目数

时间:2012-01-14 23:06:59

标签: sql sql-server sql-delete

我想知道,执行以下操作的最有效方法是什么?

我正在尝试实施某种审核系统,每次登录我的页面都会存储在数据库中。我使用SQL Server 2005数据库。存储审计数据的表显然不能没有上限。因此,它应该最多有1000个条目,然后在插入新条目时必须删除任何旧条目。问题是你如何以最有效的方式做到这一点 - 我是否需要添加任何特殊列,比如说一个序数条目号以便于清理?

编辑: 比如说,如果我的表的结构是(伪代码):

`id` BIGINT autoincrement
`date` DATETIME
`data1` NVARCHAR(256)
`data2` INT

你会如何编写这个清理程序?

4 个答案:

答案 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的任何原因。

  1. 使用登录触发器在审计表中插入一行。

  2. 在审计表上创建一个AFTER INSERT触发器,用于删除MIN(ID)行。

  3. 以下是一些可以使用的代码:

    / *创建审计表* /

    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

的列