首页 文章

在DB中组织大量带时间戳的值(sql / nosql)

提问于
浏览
2

我有一个设备,我正在轮询很多不同的字段,设备每x毫秒返回一个id和值列表,我需要在DB中存储时间戳 .

系统用户需要能够查询此DB以查找历史日志以创建图表,或查询每个值的最后时间戳 .

一个简单的方法是用MySQL定义一个MySQL表

id,value_id,timestamp,value

并让用户选择

Select value form t where value_id=x order by timestamp desc limit 1

然后用时间戳和id上的索引推送那里的所有内容,但我的问题是设计架构的最佳方法性能/大小是什么?还是使用nosql?任何人都可以评论可能的设计权衡 . 这样的设计会有数百万条记录吗?

2 回答

  • 1

    当你说“...或查询每个值的最后一个时间戳”这是你的想法吗?

    select max(timestamp) from T where value = ?
    

    如果你有数百万条记录,并且上面是你的意思(即WHERE子句中的值是唯一的),那么你需要在value列上有一个索引,否则你必须进行全表扫描 . 但是如果查询总是在WHERE子句中有[timestamp]列,那么如果时间戳上有索引,则不需要[value]列上的索引 .

    如果用户将在WHERE子句中单独出现timestamp列的查询,则需要timestamp列上的索引:

    select * from T where timestamp > x and timestamp < y
    

    您可以索引所有三列,但是您希望确保写入不会因索引开销而减慢 .

    拥有一个非常大的数据库时的经验法则是每个查询都应该能够使用索引,这样就可以避免全表扫描 .

    编辑:

    在澄清之后添加一些额外的评论 .

    我想知道你将如何知道身份证? [id]可能是产品代码吗?

    如果没有很多不同的产品代码,即id是低基数索引,则id上的单个简单索引可能无法很好地扩展 . 树的重新 balancer 可能会减慢每x毫秒发生的批量插入 . (id,timestamp)上的复合索引优于简单索引 .

    如果您很少需要对多个产品进行排序,但通常基于单个产品代码进行选择,那么使用散列密钥稀疏表而非b树的非传统DBMS可能是一个非常可行的甚至是优秀的替代你 . 在这样的数据库中,给定密钥的所有记录都将在物理上找到同一组连续的“页面”;散列算法查看密钥并返回将在其中找到记录的页码 . 由于没有索引,因此无需重新 balancer 索引,因此您可以完全避免相关的扩展问题 .

    然而,虽然散列文件数据库在基于密钥值的低开销几乎即时检索方面表现优异,但它们在对属性上的大组记录进行排序时往往表现不佳,因为数据不是以任何有意义的顺序物理存储的,并且收集记录可能涉及很多颠簸 . 在您的情况下,时间戳将是该属性 . 如果我在你的位置,我会根据id的基数做出决定:在一百万条记录的数据集中,会找到多少个DISTINCT ID?

    由于本网站没有让我加入另一个答案,所以另一个编辑:

    最简单的方法是有两个表,一个是持续历史记录,总是插入新值,另一个只包含250条记录,每个部分一个,最新值覆盖/替换前一个记录 .

    Update latest
    set value = x
    where id = ?
    
  • 1

    你可以选择

    • 索引(复合;覆盖value_id,时间戳和值,或它们的某种组合):您应该使用不同的索引测试性能;复合和非复合,也要注意有很多显着不同的方法来获得'每组最大'(搜索所以,尤其是带变量的mysql版本)

    • 触发器 - 您可以使用触发器来维护另一个表中的最大行值(进一步选择的最佳性能;这是多余的并且可以保留在内存中)

    • 懒惰的统计信息/触发器,因为您的数据库经常更新,如果您定期更新统计信息,您可以保存周期(如果您可以允许统计信息为y秒,如果您每秒轮询1000次/次,那么您可能会节省y * 100 / x潜在更新;这可能是显而易见的,尤其是在可扩展性方面)

    如果您正在寻找最后一点性能,如果不是保持简单,则上述情况属实 .

相关问题