具有庞大数据集的数据库结构的建议

时间:2010-12-22 09:45:14

标签: sql-server performance database-design data-warehouse

在我看来,这个问题将没有准确的答案,因为需要过于复杂的分析并深入研究我们系统的细节。

我们分发了传感器网。信息收集在一个数据库中并进一步处理。

当前的数据库设计是每月分区一个巨大的表。我们尝试将其保持在10亿(通常为6到8亿条记录),因此填充率为每天20-50万条记录。

数据库服务器目前是MS SQL 2008 R2,但我们从2005年开始,在项目开发期间进行升级。

表本身包含SensorId,MessageTypeId,ReceiveDate和Data字段。目前的解决方案是将传感器数据保存在数据字段(二进制,16字节固定长度)中,并部分解码其类型并将其存储在messageTypeId中。

我们通过传感器发送不同类型的消息类型(当前约为200),并且可以根据需要进一步增加。

主要处理在应用服务器上完成,该服务器按需获取记录(按类型,sensorId和日期范围),解码并执行所需的处理。目前的速度足以满足这样的数据量。

我们要求将系统的容量提高10到20倍,我们担心的是我们当前的解决方案能够做到这一点。

我们还有两个想要“优化”我想要讨论的结构的想法。

1传感器的数据可以分为多种类型,为了简单起见,我将使用2个主要数据:(值)级别数据(具有值范围的模拟数据),状态数据(固定数值)

因此,我们可以使用以下规则将我们的表重新设计为一堆小表:

  • 对于每个固定类型值(状态类型)使用SensorId和ReceiveDate创建自己的表(因此我们避免存储类型和二进制blob),所有依赖(扩展)状态将存储在自己的表中类似的外键,因此,如果我们State的值为AB,并且依赖(或其他)状态为12,那么我们会以表格{{1}结尾},StateA_1StateA_2StateB_1。因此,表名由它代表的固定状态组成。

  • 对于我们创建单独表格的每个模拟数据,它将是类似的第一类型,但是可以附加具有传感器值的字段;

优点:

  • 仅存储所需的数据量(目前我们的二进制blob数据包含最大值的空间)和减小的数据库大小;
  • 要获取特定类型的数据,我们获取访问权限表而不是按类型过滤;

缺点:

  • AFAIK,它违反了推荐做法;
  • 需要框架开发来自动化表管理,因为DBA将手动维护它;
  • 表格数量可能相当大,因为需要全面覆盖可能的值;
  • 引入新传感器数据时的DB模式更改甚至已定义状态的新状态值因此可能需要进行复杂的更改;
  • 复杂的管理导致容易出错;
  • 在这样的表orgranisation中插入值可能是DB引擎地狱吗?
  • DB结构不固定(不断变化);

可能所有人都减轻了一些专业人士,但如果我们获得显着的性能提升和/或(不太优选但也很有价值)存储空间,我们可能会遵循这种方式。

2也许只是每个传感器的分割表(它将是大约10万个表)或更好的传感器范围和/或移动到具有专用服务器的不同数据库,但我们希望尽可能避免硬件跨度。

3保持原样。

4切换到不同类型的DBMS,例如面向列的DBMS(HBase和类似的)。

你怎么看?也许你可以为进一步阅读建议资源?

更新 传感器的一些数据甚至可以在一个月的延迟(通常是1-2周延迟)到达系统的性质,有些总是在线,某种传感器最终有内存和上线。每个传感器消息都有相关的事件引发日期和服务器接收日期,因此我们可以区分最近收集的数据。处理包括一些统计计算,参数偏差检测等。我们构建了汇总报告以便快速查看,但是当我们从传感器更新旧数据(已经处理)获取数据时,我们必须从头开始重建一些报告,因为它们取决于所有可用的无法使用数据和聚合值。所以我们通常会保留3个月的数据以便快速访问和其他存档。我们努力减少存储数据所需的数量,但我们认为我们需要一切来保持结果准确。

UPDATE2:

此处包含主要数据的表格。正如我在评论中提到的,我们在“需要速度”期间删除了它的所有依赖关系和约束,因此它仅用于存储。

StateB_2

来自其中一台服务器的示例数据:

CREATE TABLE [Messages](
    [id] [bigint] IDENTITY(1,1) NOT NULL,
    [sourceId] [int] NOT NULL,
    [messageDate] [datetime] NOT NULL,
    [serverDate] [datetime] NOT NULL,
    [messageTypeId] [smallint] NOT NULL,
    [data] [binary](16) NOT NULL
)

4 个答案:

答案 0 :(得分:1)

只是想提出一些想法,希望它们有用 - 它们是我正在考虑/思考/研究的一些事情。

分区 - 您提到该表按月分区。是您自己手动分区,还是使用Enterprise Edition中提供的分区功能?如果是手动,请考虑使用内置的分区功能将数据分区更多,这样可以提高可扩展性/性能。 Kimberly Tripp关于MSDN的这篇“Partitioned Tables and Indexes”文章很棒 - 那里有很多很好的信息,我不会通过释义来表达不公正!值得考虑的是,每个传感器手动创建1个表,这可能更难以维护/实施,因此增加了复杂性(简单=好)。当然,只有你有企业版。

已过滤的索引 - 请查看this MSDN article

当然有硬件元素 - 毫无疑问,带有大量RAM /快速磁盘等的内容丰富的服务器将会起作用。

答案 1 :(得分:1)

与数据库无关的一种技术是切换到记录值的变化 - 每分钟至少有n条记录。因此,例如,如果传感器没有1发送类似的东西:

Id  Date              Value
-----------------------------
1 2010-10-12 11:15:00 100
1 2010-10-12 11:15:02 100
1 2010-10-12 11:15:03 100
1 2010-10-12 11:15:04 105

然后只有第一个和最后一个记录将在DB中结束。为确保传感器处于“实时”状态,每分钟最少输入3条记录。这样就可以减少数据量。

不确定这是否有帮助,或者在您的应用中是否可行 - 只是一个想法。

修改

是否可以根据访问概率归档数据?说旧数据比新数据更不可能被访问是否正确?如果是这样,您可能需要查看Bill Inmon的下一代数据仓库的 DW 2.0架构,其中讨论了通过不同DW区域移动数据的模型(交互式,集成式,近端式) Line,Archival)基于访问概率。访问时间从非常快(交互区)到非常慢(存档)。每个区域都有不同的硬件要求。目标是防止大量数据堵塞DW。

答案 2 :(得分:1)

存储方面你可能会好起来的。 SQL Server将处理它。

令我担心的是您的服务器将承担的负载。如果您经常收到交易,那么今天每秒约有400笔交易。将此值提高20倍,您可以查看每秒约8,000笔交易。考虑到您正在报告相同的数据,这不是一个小数字......

顺便说一句,我是否正确理解您在处理传感器数据时丢弃传感器数据?那么你的总数据集将是“滚动”的10亿行?或者你只是附加数据?

答案 3 :(得分:0)

您可以将日期时间戳存储为整数。我相信datetime标记使用8个字节,整数只在SQL中使用4个。你不得不离开这一年,但由于你按月分区,这可能不是问题。

所以'12 / 25/2010 23:22:59'将被存储为1225232259 -MMDDHHMMSS

只是一个想法...