如何在数据库中存储大量数据并自动删除旧数据

时间:2013-11-03 10:26:37

标签: php database performance storage

这是我的问题的免费创建示例:

每15秒我运行一个php脚本来检查+5服务器的状态。它得到pingstatusversionmotd。数据应存储两周,此时间后可将其删除。

目前我会像这样存储它:

Table 1:
server_ID    |    name    |    ip    |    last_update

Table 2:
ID    |     server_ID    |    status    |    ping    |    version    |    motd    |    timestamp

我认为通过这种方式,没有任何东西加倍,我可以轻松地重命名服务器或更改其IP。

但是我应该如何删除旧行呢?如果我每次脚本运行(每15秒)执行此操作,是否太多了? 14*24*60*4 = 80640 rows per server for the two weeks

或者我应该如何存储数据,我能够获得最新数据以及显示2周折线图的数据?

可能是第三个表,每小时有一个数据。


修改

感谢您的回答。那怎么样:

在15秒更新时,我将所有数据放在表1中,但我更新了它,因此每个服务器只有一行。

然后我每小时使用一次这个触发器并将当前数据复制到一个新表中并删除超过2周的所有内容?

目前我已将表1中的server_ID和表2中的ID设置为主键,是否有充分理由将时间戳设置为主键?

4 个答案:

答案 0 :(得分:1)

首先让我们计算每5秒后2周内输入的记录数

60 / 5 = 12 times in a min
12 * 60 = 720 times in an hour
720 * 24 = 17280 times in a day
17280 * 14 = 241920 times two weeks

241920 * 5 = 1209600 records

每天都有大量的数据输入。我假设您正在使用MySQL数据库。由于您希望最新数据显示在折线图中。您必须创建事件触发器。

事件触发器

只有在您有权限的情况下才会使用事件触发器。因此,首先必须将事件触发器设置为:

SET GLOBAL event_scheduler = ON;

现在您的事件触发器为ON,创建以下事件触发器来执行操作:

CREATE EVENT 
    event_name
ON SCHEDULE AT
EVERY 5 MINUTE 
DO
  DELETE 
  FROM
     Database2 
  WHERE
     timestamp < (CURRENT_TIMESTAMP() - (60*60*24*14) )

将每隔5分钟安排一次,它将从当前时间和日期戳中删除2周大的记录。希望这能解决您的问题。由于该表只有2周的记录,每5分钟删除一次旧记录,插入将每5秒完成一次。

已编辑的问题

编辑过的问题改变了事情的方式。现在在table2中不断输入数据。现在每15秒更新一次table1,每小时创建一个新表并删除旧条目。我不明白你想要达到什么目的。但是,我会在最后回答有关主键的问题。

什么是主键

  • PRIMARY KEY约束唯一标识数据库表中的每条记录。

  • 主键必须包含唯一值。

  • 主键列不能包含NULL值。

  • 每个表都应该有一个主键,每个表只能有一个主键。

现在它取决于您的要求,如果您希望单个时间戳条目应该在那里然后将其更改为时间戳,但如果您想要单个服务器的单个条目,则将其更改为服务器。但是,我推荐你另一种方式,即你创建一个单独的列作为主键的ID,并创建唯一键的索引与两列的组合,即server_id和timestamps

答案 1 :(得分:0)

你的问题是如何删除行,对吧? 这可以通过删除...

DELETE FROM表WHERE x = y

答案 2 :(得分:0)

我假设您正在使用支持分区的数据库(例如,InnoDb的MySql&gt; = 5.5)。在这种情况下,我会将timestamp列添加到第二个表的主键(说Database2,你的意思是table2,我是对的吗?)并创建每日分区。然后删除旧数据只是放弃超过2周的每日分区(这应该是一个非常快的操作)。

如果你需要显示一个有小时分辨率的2周图表,我建议先检查你当前的设置是否不够快,只有当它太慢时才会创建一个额外的表来存储聚合数据(可能是由例如,每隔几分钟,一些工人查询主表。

答案 3 :(得分:0)

由于没有提到必须使用基于SQL的数据库,只是为了好玩,您可以避免将其存储在关系数据库结构中。

一个选项可能是哈希,但也许您也可以使用排序集,例如Redis。使用有序集,您可以非常快速地添加,删除或更新元素(时间与元素数量的对数成比例)。

排序集的每个成员都与分数相关联,分数用于从最小分数到最高分数对排序集进行排序。虽然成员是独一无二的,但可能会重复分数。

您的分数将是大纪元时间(或类似),该成员可能是您要存储的数据的JSON对象。

因为这种类型的操作非常快,所以您可以轻松回调所有JSON对象并自行排序。您可能希望将纪元时间存储在JSON对象中以确保唯一性。请注意,相对于Redis可以处理的内容,每个服务器80640行很小。添加:

ZADD yourset 1383553120 "<JSON OBJECT>"

第一个参数是当前的纪元时间。由于您知道当前的纪元时间,因此您可以轻松删除所有太旧的记录。删除:

ZREMRANGEBYSCORE yourset -inf 1382344314

最后争论应该是两周前的大纪元时间。

JSON and PHP play nice,所以它可能是您可以查看的内容。