【问题标题】:MySQL Array SELECT & UPDATE Statements Based on Index PositionMySQL Array 基于索引位置的 SELECT 和 UPDATE 语句
【发布时间】:2020-03-10 14:56:06
【问题描述】:

请考虑下面我的表格图片,我的问题涉及在sensor_values 列上执行UPDATESELECT

sensor_values 列是一个长度为 86,400 的数组,对应于一天中每一秒的传感器值。我现在将其设置为 JSON 数据类型。

我的问题

如何对特定索引执行UPDATE

  • 更改当天的第 5 秒,或将 [4] 索引为值 300.25

我如何SELECT 一天的前 300 秒? 下面的伪代码

SELECT sensor_values[0:299] FROM facts WHERE d_date = '2020-03-10' AND dim_tag = 'Water_Temp'

这是一个指向 PostGresql 的 DBFiddle 的链接,它做的事情与我在 MariaDB 中尝试完成的事情非常相似。 https://dbfiddle.uk/?rdbms=postgres_12&fiddle=6999d2607c48a809ff995c8844c7f7bb

编辑:下面是我的系统的高级概述

我有一个 Python 数据管道,可以读取数千个传感器的值并执行计算。它负责存储在其他表中的所有数据汇总。

我需要易于访问第二级的数据以进行分析,我正在尝试以本问题中所说的方式进行分析。我的想法是在 Python 中获取当天的第二天,并将其用作要更新的数组索引,如下所示:

now = datetime.datetime.now()
midnight = now.replace(hour=0, minute=0, second=0, microsecond=0)
secondsSinceMidnight = (now - midnight).seconds

sensorValue =  300.25
sensorTag = "Water_Temp"

sqlQuery = 
"""
UPDATE facts
SET sensor_values[%s] = %s
WHERE d_date = %s AND dim_tag = %s
"""
sqlValues = secondsSinceMidnight, sensorValue, datetime.datetime.today().strftime('%Y-%m-%d'), sensorTag

dbOps.update(sqlQuery, sqlValues)

我不想整天跟踪 Python 中的值,然后执行INSERT,因为如果程序崩溃,我会丢失所有数据,并且使用 预先形成的数组 让我以编程方式快速确定程序的其他区域中缺少数据的位置(即sensor_value 是一天中的一组秒数的0)。

我使用术语预先形成的数组,因为我计划让我的程序定期检查以确保当前和第二天的每个传感器始终有一行可用,从而确保在午夜无缝转换因为颗粒很小。

正如 Bill Karwin 的回答所建议的那样,这是我的第一种方法 - 但是有数千个传感器,每个传感器都会每秒发布一次。数据库将呈指数增长:1000 * 86400 = 86.4M 每天输入的行数。

所以,它不一定是JSON,只是一个可以这种格式修改的数组。我认为这是MySQL 的正确方法。更新了帖子的标题以更好地反映问题。

【问题讨论】:

    标签: mysql json mariadb


    【解决方案1】:

    如果您想使用 SQL 处理一组传感器值的各个元素,请不要将其存储在 JSON 中。将其作为行存储在普通表中。

    CREATE TABLE facts (
     d_date DATE NOT NULL,
     second INT NOT NULL,
     dim_tag VARCHAR(...) NOT NULL,
     sensor_value NUMERIC(5,2) NOT NULL,
     PRIMARY KEY (d_date, second)
    );
    

    那么你想要的查询在 SQL 中更直接:

    UPDATE facts SET sensor_value = 300.25 WHERE d_date = '2020-03-10' AND second = 4;
    
    SELECT sensor_value FROM facts WHERE d_date = '2020-03-10' AND second < 300;
    

    如果您坚持将传感器值存储为 JSON 数组,则没有使用 SQL 操作单个元素的简单方法。您应该只将整个数组提取到您的应用程序中,然后将 JSON 解压缩到您可以使用代码读取或更改的数组中。

    这是使用 JSON 的弱点:很容易将一组值插入到单个列中,并且很容易将整个集合作为一个单元获取。但是,如果您想使用 SQL 逻辑来处理该集合的各个元素,那就很尴尬了。

    有人可以发布一个答案,为您提供您在上述问题中要求的结果吗?可能,但开发时间太长,下次你想用这些数据做任何其他类型的任务时,你必须再次寻求帮助。

    当你真的想要离散数据元素时使用 JSON 不是一个可持续的设计,因为它会导致软件开发成本增加太高。


    关于您的附加信息:

    MySQL 不支持数组数据类型或任何使用数组下标的语法。

    我同意每天 8640 万行是一个快速增长的速度。您将在不到两周的时间内达到超过 10 亿行。

    您可能需要时间序列数据库而不是关系数据库。时间序列数据库针对类似数据的长流进行优化,并在列上运行聚合查询。它们接受这些数据流的快速摄取,并且比 InnoDB 等数据库引擎更紧凑地存储数据。

    你应该看看其中之一:

    【讨论】:

    • 比尔,非常感谢您的洞察力。我已经编辑了这个问题,以包含有关我的系统的更多信息 - 我想保持一般性,以使其更适用于将来登陆这里的人,但我希望额外的信息将有助于确定我的解决方案问题。
    • 比尔,谢谢你的信息。这是我需要的正确方向的推动。我正在使用 TimeScaleDB(基于 PostGres),因为它接近我熟悉的 SQL 语法并且能够用它完成我的项目。
    • 酷,我会将 TimeScaleDB 的链接添加到我上面的答案中。很高兴您找到了一个好的解决方案!
    猜你喜欢
    • 2012-04-07
    • 1970-01-01
    • 2018-09-17
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 2021-02-23
    • 1970-01-01
    • 2015-12-05
    相关资源
    最近更新 更多