将数据组织到RDS模式或多个发电机数据库表中的多行列或表中是否更有效?

时间:2017-07-14 18:38:22

标签: mysql node.js database schema amazon-dynamodb

使用Node.JS,(Dynamo DB和Sequelize)

嘿那里,

我正在尝试解决以下统计报告数据的最佳方式,这些数据需要跟踪以实现长期可扩展性。原始架构师使用dynamoDB解决方案,因为它是No SQL,我们需要灵活地添加数据而不受架构的限制。但是,他将属性嵌套到列对象中,要求我们查询整个表,然后遍历结果,分别检查每一行以根据请求的搜索查询构建响应。

以下是最初存储在dynamoDB

中的示例report对象

示例1

{
  "boolData": null,
  "datetime": 1490391013471,
  "eventData": [
    {
      "eventType": 0,
      "location": "-16.3, 2.1, -70.8",
      "timestamp": 1490391033260
    }
  ],
  "floatData": {
    "averageAltitude": 1.79624987,
    "averageSpeed": 0,
    "maxAltitude": 3.55,
    "scorePercent": 0,
    "topSpeed": 0
  },
  "intData": {
    "altitudeViolations": 0,
    "closeCalls": 0,
    "crashCount": 1,
    "distanceToNoFlyViolations": 0,
    "lostLineOfSightViolations": 0,
    "moduleId": 2010,
    "moduleStatus": 0,
    "resetCount": 0,
    "sceneId": 1007,
    "score": 0,
    "tooCloseOrAbovePersonViolations": 0
  },
  "longData": {
    "moduleCompleted": 1490391033260,
    "moduleStartTime": 1490391023584,
    "moduleTotalTime": 9676
  },
  "objecttype": 1,
  "stringData": {
    "name": "test",
    "grade": "F",
    "moduleName": "HorizontalFlight1",
    "sceneName": "BasicTraining"
  },
  "userid": 1
}

由于上述原因,这显然不是存储数据的最佳方式,因为如果我想知道在特定模块或场景中发生的所有航班的averageAltitude是什么,我会' d必须查询所有数据,然后遍历所有结果并检查嵌套在floatDataintData中的属性,并与查询中请求的信息进行比较以构建响应。

所以我的下一个想法是为什么不将所有数据存储在自己的列中,就像EXAMPLE 2一样?我在Dynamo DB中使用此模式可以看到的唯一缺点是,行/项中允许的最大数据量为400KB,并且因为我们不知道将来要添加多少数据,这可能会导致缩放问题。解决方案只是限制返回的项目,并根据我们当前所知的项目大小对响应进行分页,并将其除以1mb扫描上限。

示例2

{
  "boolData": null,
  "datetime": 1490391013471,
  "eventData": [
    {
      "eventType": 0,
      "location": "-16.3, 2.1, -70.8",
      "timestamp": 1490391033260
    }
  ],
  "averageAltitude": 1.79624987,
  "averageSpeed": 0,
  "maxAltitude": 3.55,
  "scorePercent": 0,
  "topSpeed": 0
  "altitudeViolations": 0,
  "closeCalls": 0,
  "crashCount": 1,
  "distanceToNoFlyViolations": 0,
  "droneId": 0,
  "lostLineOfSightViolations": 0,
  "moduleId": 2010,
  "moduleStatus": 0,
  "resetCount": 0,
  "sceneId": 1007,
  "score": 0,
  "tooCloseOrAbovePersonViolations": 0
  "moduleCompleted": 1490391033260,
  "moduleStartTime": 1490391023584,
  "moduleTotalTime": 9676
  "objecttype": 1,
  "name": "test",
  "grade": "F",
  "moduleName": "HorizontalFlight1",
  "sceneName": "BasicTraining"
  "userid": 1
}

我正在考虑的另一个想法是将intDatafloatDatastringDataeventData分隔到他们自己的发电机数据库表中,索引为{{ 1}}相应地关联它们,然后构造响应。但是,我不确定dynamo DB是否是为这种关联/关系目的而设计的,而且我非常确定使用RDS会导致我的第二个提议更快。

如果我将reportId存储在Aurora / MySQL RDS中,并将EXAMPLE 1intDatafloatDatastringData字符串化以将其存储在对于eventData表,他们各自的TEXTBLOB列,我非常确定可扩展性的效率会大大降低。对数据进行字符串化会添加所有这些额外字节,即使它允许我们灵活地添加和删除要在这些列中跟踪的属性,我们仍然无法执行Reports之类的查询,因为这需要我完全按照解析字符串化JSON的额外步骤做了我正在做的事情。我查询所有报告并迭代检查SELECT * REPORTS WHERE averageAltitude >= 1.5属性averageAltitude,然后构建我的结果。因此,为了避免这种情况,使用以下模式为floatDataintDatafloatData,创建RDS表(仅显示intData示例目的)

intData

stringData

然后做一个Report.hasMany Association

id: {
      type: DataTypes.INTEGER.UNSIGNED,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true
    },
    name: {
      type: DataTypes.STRING(191),
      allowNull: false
    },
    value: {
      type: DataTypes.INTEGER,
      allowNull: false
    }

似乎是一个非常实用的方法,可以很好地工作,因为我可以轻松地将数据包含在查询中,并且对于每个报告插入的intData,floatData的数量是不可知的。这是最优化的方法吗?这种方法会将Dynamo数据库表一起删除,但肯定看起来比将db.Report.hasMany(db.IntData, { as: 'intData', foreignKey: 'reportId', constraints: false }); intData等存储为floatData列中的JSON字符串更为理想。我不确定从长远来看,这种方法是否具有成本效益的可扩展性,然后使用dynamo DB。我们希望尽可能推迟升级到大型RDS,查询报告绝对是最昂贵的电话。

感谢您的建议和意见。如果我完全错过一个比我建议的更好的解决方案,请告诉我一个替代解决方案。谢谢!

0 个答案:

没有答案