我不确定说出这个问题的最好方法!
我有一个需要检索和存储过去24个数据值的mysql数据库,数据总是需要是最后24个数据值。
我完全有效,但我相信必须有更好的方法来做到这一点!
刚才,我的mysql数据库有id,timestamp等列,然后是24个数据列:
data_01
data_02
data_03
data_04
data_05
etc
不同的ID有多行。
我每小时运行一次cron作业,删除列' data_24',然后重命名所有列:
data_01 -> data_02
data_02 -> data_03
data_03 -> data_04
data_04 -> data_05
data_05 -> data_06
etc
然后添加一个新的空白列:
data_01
然后将新数据添加到这个新的空白列中。
这听起来像是一种明智的做法吗,还是有更好的方法?
我对这种方法的关注是,在检索新数据之前必须先删除,重命名和添加列,以便新列存在以添加数据。
如果数据检索因任何原因失败,那么我的表会有一个NULL为数据值的列。
答案 0 :(得分:2)
为这样的事情重命名列不是一个好主意。
我很好奇你如何插入和更新这些数据,但必须有更好的方法来做到这一点。
看似可行的两件事:
不重命名列,而是将数据移动到下一列:
update YourTable
set data1 = :newvalue,
data2 = data1,
data3 = data2,
...;
或者通过将数据分布在24行而不是24列。每个数据都是表中的一行(或者在您的id是外键的新表中)。每次插入新值时,您还可以删除该相同ID的最旧值。您可以在一个原子事务中执行此操作,因此每个id不会有多于或少于24行。
insert into YourTable(id, data)
values (:id, :newvalue);
delete from YourTable
where id = :id
order by timestamp desc
limit 1;
这会将行数(但不是数据量)乘以24,所以对于1000行(就像你提到的那样),你说的是24000行,如果你有正确的索引,它仍然是花生。
我们在MySQL中拥有超过1亿行的表。操作24000行比重写1000行的完整表更容易,这实际上就是通过重命名列来实现的。
所以第二种选择肯定有我的偏好。它将为您提供一个简单的结构,如果您决定不清理旧数据,或将其移动到单独的作业,或坚持100项而不是24项,那么您可以通过更改3行代码轻松地做到这一点而不是用它彻底改造你的表结构和应用程序。
答案 1 :(得分:0)
说实话,它并不是一种明智的做事方式。
恕我直言,拥有多行而不是宽表更灵活。
您可以定义列(id,entity_id,created)。然后,您就可以在" log"中编写您的记录。方式。
当您需要以与以前相同的方式选择数据时,可以使用MySQL视图。像
这样的东西 CREATE VIEW my_view AS
SELECT data_01, ..., data_24 -- here you should put the aggregated values aliased as data_01 ... data_24
FROM my_table
WHERE my_table.created >= DATE_SUB(NOW(), INTERVAL 1 DAY)
GROUP BY ... -- here you should aggregate the fields by hours
ORDER BY created;