0

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

每 15 秒我运行一个 php 脚本来检查 +5 个服务器的状态。它得到ping,status和. 数据应存储两周,之后可以将其删除。versionmotd

目前我会这样存储它:

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

4 回答 4

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;

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

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 和时间戳的组合创建唯一键的索引

于 2013-11-03T11:36:40.010 回答
0

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

从表中删除 x = y

于 2013-11-03T10:41:21.953 回答
0

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

如果您需要显示具有小时分辨率的 2 周图表,我建议您首先检查您当前的设置是否不够快,并且仅当它太慢时才创建一个额外的表来存储聚合数据(这可能是由某些工作人员查询生成的)例如每隔几分钟主表)

于 2013-11-03T10:59:32.673 回答
0

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

一个选项是 Hash,但也许您也可以在Redis之类的东西中使用 Sorted Set 。使用排序集,您可以非常快速地添加、删除或更新元素(时间与元素数量的对数成正比)。

Sorted Set 的每个成员都与 score 相关联,用于将 sorted set 从小到大排序。虽然成员是唯一的,但分数可能会重复。

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

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

ZADD yourset 1383553120 "<JSON OBJECT>"

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

ZREMRANGEBYSCORE yourset -inf 1382344314

最后的争论应该是两周前的Epoch Time。

JSON 和 PHP 玩得很好,所以它可能是你可以研究的东西。

于 2013-11-04T08:34:47.067 回答