Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:将一个大表拆分为分区还是单独的表?_Mysql_Database_Partitioning_Large Data - Fatal编程技术网

MySQL:将一个大表拆分为分区还是单独的表?

MySQL:将一个大表拆分为分区还是单独的表?,mysql,database,partitioning,large-data,Mysql,Database,Partitioning,Large Data,我有一个MySQL数据库,包含20多个表,但其中一个表非常大,因为它从不同的传感器收集测量数据。它在磁盘上的大小约为145 GB,包含超过10亿条记录。所有这些数据也被复制到另一台MySQL服务器 我想把数据分成更小的“碎片”,所以我的问题是下面哪种解决方案更好。我会使用记录的“时间戳”将数据除以年份。几乎所有在此表上执行的SELECT查询都在查询的“where”部分包含“timestamp”字段 以下是我无法决定的解决方案: 使用MySQL分区并将数据按年份划分(例如分区1-2010、分区2-

我有一个MySQL数据库,包含20多个表,但其中一个表非常大,因为它从不同的传感器收集测量数据。它在磁盘上的大小约为145 GB,包含超过10亿条记录。所有这些数据也被复制到另一台MySQL服务器

我想把数据分成更小的“碎片”,所以我的问题是下面哪种解决方案更好。我会使用记录的“时间戳”将数据除以年份。几乎所有在此表上执行的SELECT查询都在查询的“where”部分包含“timestamp”字段

以下是我无法决定的解决方案:

  • 使用MySQL分区并将数据按年份划分(例如分区1-2010、分区2-2011等)
  • 创建单独的表格并将数据按年份划分(例如,测量表2010、测量表2011等)
  • 有没有我不知道的其他(更新的)可能的选择

    我知道,在第一种情况下,MySQL本身将从“碎片”中获取数据,而在第二种情况下,我必须为其编写一种包装器,并自己完成。对于第二种情况,是否有其他方法可以将所有单独的表视为“一个大表”来获取数据

    我知道这个问题过去已经被问过了,但也许有人提出了一些新的解决方案(我不知道),或者最佳实践解决方案现在已经改变了

    非常感谢你的帮助

    编辑:

    模式与此类似:

    device_id (INT)
    timestamp (DATETIME)
    sensor_1_temp (FLOAT)
    sensor_2_temp (FLOAT)
    etc. (30 more for instance)
    

    所有传感器温度在同一时刻每分钟写入一次。请注意,大约有30个不同的传感器测量值记录在一行中。这些数据主要用于显示图形和一些其他统计目的。

    关于如何使用/查询数据或模式是什么样子,您没有说太多,但我试图补充一些内容

  • 拆分表的一个方法是基于实体 (不同的传感器是不同的实体)。这是有用的,如果 不同的传感器需要不同的列。所以你不需要 强制它们进入一个适合所有模式(最不常见)的模式 多个)。不过,如果传感器被添加或移除,这并不好 动态地,因为您必须在运行时添加表
  • 另一种方法是根据时间分割表。这是 如果一段时间后数据可以“历史化”,并且不用于 实际的业务逻辑不再是为了统计目的
  • 这两种方法也可以结合使用。此外,请确保根据您的查询需要对表进行了正确的索引。

    我强烈反对任何通常需要在一段时间后添加表或类似内容的方法。像往常一样,在出现性能问题之前,我不会拆分任何内容

    编辑:
    我将明确地将表格重组为以下内容,而不是将其拆分:

    device_id (INT)
    timestamp (DATETIME)
    sensor_id (INT) -- could be unique or not. if sensor_id is not unique make a 
                    -- composite key from device_id and sensor_id given that you 
                    -- need it for queries
    sensor_temp (FLOAT)
    

    如果数据增长很快,并且您希望很快生成TB的数据,那么使用NoSQL方法会更好。但那是另一回事。

    好吧,如果你希望得到一个新的答案,那意味着你可能读过我的答案,我听起来像一张破唱片。有关分区有助于提高性能的少数用例,请参阅。你的听起来和这4个案子都不一样

    收缩
    设备\u id
    INT
    为4字节;你真的有数百万台设备吗
    TINYINT UNSIGNED
    为1字节,范围为0..255
    SMALLINT UNSIGNED
    为2个字节,范围为0..64K。那会使桌子缩小一点

    如果您真正的问题是如何管理这么多数据,那么让我们“跳出框框思考”。继续读下去

    绘图。。。你在画什么日期范围

    • “最后”小时/天/周/月/年
    • 任意的小时/天/周/月/年
    • 任意范围,不受日/周/月/年边界限制
    你在画什么

    • 一天的平均值
    • 一天内的最大/最小值
    • 烛台(等)的一天或一周或什么
    无论何种情况,您都应该构建(并增量维护)一个包含数据的汇总表。一行将包含一小时的摘要信息。我建议

    CREATE TABLE Summary (
        device_id SMALLINT UNSIGNED NOT NULL,
        sensor_id TINYINT UNSIGNED NOT NULL,
        hr TIMESTAMP NOT NULL,
        avg_val FLOAT NOT NULL,
        min_val FLOAT NOT NULL,
        max_val FLOAT NOT NULL
        PRIMARY KEY (device_id, sensor_id, hr)
    ) ENGINE=InnoDB;
    
    一个汇总表可能是9GB(对于当前数据量)

    选择人力资源,
    平均值,
    米努瓦尔,
    最大值
    摘自总结
    其中设备_id=?
    和传感器_id=?
    和hr>=?
    人力资源<?+间隔20天;
    
    将为您提供480小时的hi/lo/avg值;足够绘制图表吗?从汇总表中获取480行要比从原始数据表中获取60*480行快得多

    获得一年的类似数据可能会扼杀一个绘图包,因此可能值得建立一个摘要摘要——分辨率为一天。大约是0.4GB

    有几种不同的方法来构建汇总表;我们可以在你仔细思考它的美丽和阅读之后再讨论。也许收集一小时的数据,然后扩充汇总表是最好的方法。这有点像我们讨论的触发器

    如果你有每小时的总结,你真的需要每分钟的数据吗?考虑把它扔掉。或者,可能是一个月后的数据。这将导致使用分区,但这只是为了其删除旧数据的好处,如的“案例1”中所述。也就是说,您将有每日分区,每晚使用
    DROP
    recognization
    来改变“事实”表的时间。这将减少145GB的占用空间,但不会丢失太多数据。新占地面积:约12GB(每小时汇总+过去30天的逐分钟详细信息)


    附:说明如何获得标准偏差。

    谢谢您的回答。我对我的答案做了一点修改,所以也许它给了我们一个大局
    SELECT hr,
           avg_val,
           min_val,
           max_val
        FROM Summary
        WHERE device_id = ?
          AND sensor_id = ?
          AND hr >= ?
          AND hr  < ? + INTERVAL 20 DAY;