在我看来,由于需要太复杂的分析和对系统细节的深入研究,这个问题将无法得到准确的答案。
我们有分布式的传感器网络。信息收集在一个数据库中并进一步处理。
当前的数据库设计是每月划分一个大表。我们尝试将其保持在10亿条记录(通常为600-800百万条记录),因此填充率每天为20-50百万条记录。
数据库服务器当前为MS SQL 2008 R2,但我们从2005年开始,并在项目开发期间进行升级。
该表本身包含SensorId,MessageTypeId,ReceiveDate和Data字段。当前的解决方案是将传感器数据保留在Data字段(二进制,固定长度为16字节)中,并对其类型进行部分解码并将其存储在messageTypeId中。
我们通过传感器发送的消息类型有所不同(电流大约为200),并且可以根据需要进一步增加。
主处理在应用服务器上完成,该服务器按需获取记录(按类型,sensorId和日期范围),对其进行解码并执行所需的处理。对于这样的数据量,当前速度已足够。
我们要求将系统容量增加10到20倍,我们担心我们当前的解决方案能够做到这一点。
我也有2个想法可以“优化”结构。
1 Sensor的数据可以分为几种类型,为简单起见,我将使用2个主要的数据:(值)级别数据(具有值范围的模拟数据),状态数据(值的固定数量)
因此,我们可以使用以下规则将表重新设计为一堆小表:
对于每个固定类型值(状态类型),使用SensorId和ReceiveDate创建它自己的表(因此,避免使用存储类型和二进制Blob),所有依赖(扩展)状态将存储在自己的表中,类似于外键,因此,如果我们具有具有值State
和A
,以及它的依赖状态(或其他状态)B
和1
,我们以表2
,StateA_1
,StateA_2
,StateB_1
结尾。因此,表名由它表示的固定状态组成。
对于我们创建的单独的表,每个模拟数据将具有相似的第一种类型,但可以保留带有传感器值的其他字段;
优点:
仅存储所需数量的数据(当前,我们的二进制Blob数据包含最长值的空间)并减小了数据库大小;
要获取特定类型的数据,我们获取访问权限表,而不是按类型进行过滤;
缺点:
AFAIK,它违反了建议的做法;
需要数据库开发来自动执行表管理,因为手动维护它是DBA的工作。
由于需要完全覆盖可能的值,因此表的数量可能很大。
在引入新的传感器数据甚至是已定义状态的新状态值时,DB模式更改都可能需要进行复杂的更改;
复杂的管理容易导致错误;
也许DB引擎会在这种表组织中插入值?
数据库结构不是固定的(不断变化);
也许所有弊端都会超过一些优点,但是如果我们获得显着的性能提升和/或(也不太受欢迎,但也很有价值)存储空间,那么我们可能会采用这种方式。
2也许只是按传感器范围拆分每个传感器的表(大约是100 000个表),或者将其移动到具有专用服务器的不同数据库,但是如果可能的话,我们希望避免使用硬件跨度。
3保持原样。
4切换到其他类型的DBMS,例如面向列的DBMS(HBase和类似的数据库)。
你怎么看?也许您可以建议进一步阅读的资源?
更新:
传感器的某些数据甚至可以延迟一个月(通常为1-2周)到达,某些传感器始终在线,某种传感器具有板载内存并最终上线,这是系统的性质。每个传感器消息都有关联的事件引发日期和服务器接收日期,因此我们可以将最近的数据与一段时间前收集的数据区分开。处理过程包括一些统计计算,参数偏差检测等。我们构建了汇总报告以便快速查看,但是当我们从传感器更新中获取数据时(已处理)旧数据,我们必须从头开始重建一些报告,因为它们取决于所有可用数据数据和汇总值不能使用。因此,我们通常会保留3个月的数据以便快速访问和其他存档。我们尽力减少存储数据的需求,但决定我们需要所有这些信息以保持结果的准确性。
更新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
)
来自以下服务器之一的样本数据:
id sourceId messageDate serverDate messageTypeId data
1591363304 54 2010-11-20 04:45:36.813 2010-11-20 04:45:39.813 257 0x00000000000000D2ED6F42DDA2F24100
1588602646 195 2010-11-19 10:07:21.247 2010-11-19 10:08:05.993 258 0x02C4ADFB080000CFD6AC00FBFBFBFB4D
1588607651 195 2010-11-19 10:09:43.150 2010-11-19 10:09:43.150 258 0x02E4AD1B280000CCD2A9001B1B1B1B77
最佳答案
只是将一些想法提出来,希望它们有用-它们是我正在考虑/思考/研究的一些事情。
分区-您提到表是按月分区的。是您自己手动分区,还是您正在利用Enterprise Edition中可用的分区功能?如果是手动的,请考虑使用内置的分区功能将数据进行更多的分区,这将为您提供更高的可伸缩性/性能。金伯利·特里普(Kimberly Tripp)在MSDN上发表的这篇“ Partitioned Tables and Indexes”文章很棒-里面有很多很棒的信息,我不会通过措辞来说明这一点!值得考虑这一点,而不是为每个传感器手动创建1个表,这可能更难以维护/实施,因此增加了复杂性(简单=好)。当然,只有拥有企业版。
筛选索引-检出this MSDN article
当然有硬件元素-不用说,拥有大量RAM /快速磁盘等功能的多肉服务器将发挥作用。