什么是存储大量列的好方法?


18

我在决定如何将这些数据存储在数据库中时遇到问题。关于最佳方法的任何建议吗?我可能对数据库一无所知。

我的数据格式如下,但不是4,列数约为240,因此每个日期都有240个与之关联的唯一值:

Date/Time 200,00 202,50 205,00  
2010.11.12  13:34:00  45,8214 43,8512  41,5369   
2010.11.12  13:35:00  461,9364  454,2612  435,5222 

此外,行与DataSite关联。

我的第一个想法是要有一个像这样的表:DataID(pk),DataSiteID,ParameterID,Date,Value,以及在DataSite,Parameter和Date上的索引。ParameterID引用另一个存储输入列标题的表(200,00 202,50 205,00 ...)。

我的第二个想法只是简单地拥有一个包含所有240多个列的表。我想出了其他几种方法,但是它们也很不令人满意。

我的第一个解决方案有一个问题(不是一个很大的问题,但我不喜欢它),因为该输入行中的所有240个值都将重复使用Date和DataSiteID,所以使用了很多时间多余的空间。

每年大约会有40gb的数据传入(采用上述文本格式),并且将通过DataSite,Parameter和Date搜索数据。传入的数据量很可能在一年左右的时间内翻两番。

有什么好主意吗?谢谢,詹姆斯

编辑:这是时间序列数据,列是在不同波长下的测量值。想要在相对窄的波长范围内分析数据。将来某个时候可能还会添加额外的波长。

编辑:谢谢你们的回答,我真的很感激:)我想我可能可以找到时间用500GB左右的测试数据进行一些实验。我会把任何结论寄回去;)


2
我从各列的命名中猜测这是某种观测时间序列数据。如果这是科学数据,那么我想看看科学学科是否具有组织数据的典型方式,或者至少是利用这些数据的科学用例。

确实是时间序列数据:)原始帖子,带有更多信息。
詹姆斯

Answers:


10

您可以采用任何一种方式,但如果要使用数据进行分析,并且您经常想同时查看该数据中的多列,请使用宽表。确保您知道数据库的列数和行大小限制。确保正确获得数据类型。如果许多列为空,则SQL Server允许您为此优化表。您也可以考虑使用NOSQL(不仅SQL)解决方案来分析此类数据。

如果要减少分析的数据量,您可能需要按照问题中的说明对其进行归一化。


6

我遇到的情况与您的情况非常相似,每年有257个字段,每年输入30-50gb。最后我只是保持简单,SQL Server中有一个长大的男孩表。我的数据受到了相当多的查询,但主要是在日期上,并且运行良好。

我可以将数据分解成较小的逻辑卡盘(每组50个左右),但是在这种情况下,它实际上并没有太大优势,因此我省去了麻烦。

如果我现在觉得很花哨,我可能会考虑使用NoSQL选项,该选项在理论上更合适,但是关键任务数据尝试新事物并不总是让人感到神经紧张。


6

因此,为了晚点回答我自己的问题(该项目最终没有进行到最后),当我设法获得一些业余时间时,我用500gb的数据填满了一个测试表,该表的排列方式如下:

我的第一个想法是要有一个像这样的表:DataID(pk),DataSiteID,ParameterID,Date,Value,以及在DataSite,Parameter和Date上的索引。ParameterID引用另一个存储输入列标题的表(200,00 202,50 205,00 ...)。

数据库设置是在3GB RAM的旧双核计算机上安装的标准PostgreSQL。我运行了大约十二种不同的查询,仅通过DataSite Date和ParameterID选择数据,在1小时时间段,1天时间段内对数据进行平均,然后插入新的数据块。从内存中,所有查询只需不到一秒钟的时间即可执行。它肯定比我预期的要快得多,并且很有用。我没有想到的一件事是,使用这种方式对表建立索引后,索引文件也几乎达到了500gb,因此拥有240列宽的表当然可以节省大量磁盘空间。


但是在节省空间的同时,它肯定会影响索引速度。如果有机会,您可以重试并继续旋转它。
jcolebrand

3

在Postgres中,我会用Oracle中的数组类型varray优雅地解决此问题。


那会行得通,唯一的陷阱是我需要将DataSite的列标题存储在某个地方,因为没有它,数据就没有任何意义,它们可能会发生变化/变化(原本不应该,但是我见过猪飞过...)
詹姆斯

在这种情况下,我的主数据表中将有另一列称为“版本”,并且还有另一个表映射版本与列标题数组(因此,数组索引与数据数组匹配)。
Gaius

3

我不知道它是否对您的问题有用,但是对于列,我不需要直接请求(我从未在WHERE条件下输入的列),并且仅在我需要有关某个列的所有信息时才有用特定的行,我将它们合并为JSON格式的博客字段。


此外,压缩该斑点。在客户端中进行压缩,这样就不会给网络和服务器增加负担。
里克·詹姆斯

2

我可能会根据所查询的parameter_ids的分布情况来做出设计的最终决定。也就是说,如果几乎只查询了几个parameter_id,我会将它们的值放到一个热表中,将剩余的值放到另一个冷表中

Otoh,如果他们的查询分布或多或少均匀,我会将价值几天的样本集加载到一个表中,其中一个记录保留所有值,以查看记录/数据库块之间的比率是多少(或者甚至存在行链接问题,这很可能)。因此,我将做出进一步的设计决策。

好了,阅读完之后,我可能会同时采用两种方法进行决策。


2

我正在重新阅读这个问题-如果我有正确的答案,那么在您输入的每条记录中,都会跟踪不同的值(基于ParameterID):

ParameterID引用另一个存储输入列标题的表(200,00 202,50 205,00 ...)。

...我对您如何与数据进行交互的了解不多,但是我倾向于使用另一个选项-每个参数ID都有一个单独的表,然后在必要时使用一个视图按日期和位置将各种不同的参数连接到更宽的表(240列)中;如果保持数据ID在视图中的访问很重要,则可以使用UNION而不是JOIN,但是这些列将被稀疏地填充。


参数I是指列标题或波长。我曾经想过要这样做,但是拥有240张桌子感觉有点笨拙:)
James

@James ...不应是240个表...只能与唯一的ParameterIDs 一样多。这样,视图将与您在其上测量的离散波长数一样宽(加上独立变量)。...您可能想看看OPeNDAP社区如何处理事情,因为它们面向时间序列数据。我处理的大多数数据都是图像(望远镜,日冕仪,磁力仪),因此它们的内容不适合我的工作,因此我不知道它们如何处理存储。(它可能只是HDF / CDF / NetCDF / ASCII表)。

不幸的是,这里有240多个独特的参数:(感谢链接:)
James

@James:也是,它是辐照度数据吗?如果是这样,您可能想问LISIRD的人们……我认为他们是通过实验将其分成单独的数据集,而且我不知道他们是将其保存在数据库中还是仅保存在平面文件中。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.