寻求有关数据库架构的建议——鉴于我的问题,我应该学习哪些工具?

数据挖掘 r 数据库 sql nosql
2021-10-02 12:10:08

我是一个相当有经验的 R 用户,但直到现在我还没有充分的理由学习使用数据库。现在我遇到了一个问题,我正在处理需要保存到磁盘的模型输出,然​​后查询另一个进程。如果数据更小,我会将所有内容存储在list带有分层元素的 , 中。例如,如果我的对象被称为output.OLS

1> summary(output.OLS)
        Length Class  Mode
SEP0307 3      -none- list
SEP0308 3      -none- list
SEP0306 3      -none- list
SEN0308 3      -none- list
<<snip -- hundreds of sub-lists>>
SEN0307 3      -none- list

层次结构的第二层:

1> summary(output.OLS[[1]])
      Length Class  Mode
c1  11     -none- list
c2  11     -none- list
c2  11     -none- list

第三:

1> summary(output.OLS[[1]][[1]])
         Length Class      Mode
Baseline 1008   data.frame list
CanSEM45 1008   data.frame list
CanSEM85 1008   data.frame list
CCSM45   1008   data.frame list
CCSM85   1008   data.frame list
GISS45   1008   data.frame list
GISS85   1008   data.frame list
HadGEM45 1008   data.frame list
HadGEM85 1008   data.frame list
MIROC45  1008   data.frame list
MIROC85  1008   data.frame list

我们可以看到现在我们正在查看data.frames

1> dim(output.OLS[[1]][[1]][[1]])
[1]   33 1008
1> colnames(output.OLS[[1]][[1]][[1]])[1:10]
 [1] "scen"     "year"     "region"     "size"    "amount"     "mean" 
 [7] "semean"   "varres"   "result.1" "result.2" 
<<snip>> 
[1006] "result.998"  "result.999"  "result.1000"

有四个这样的输出对象,总共大约 6GB。他们并不都有列meansemean并且varres

这个列表大约有 1.5 个演出,考虑到我想用它做什么,这很笨拙。从数据库中读取它的子集会好得多。我可以想到两种潜在的架构:

架构 1:单个、巨大的表变量名称将是region(最外层的层次结构)、cx(即:c1、c2、c3)、model(基线、CanSEM 等),然后是所有结果:result.1, result.2, ..., result.1000

这将是最方便的。问题是桌子既深又宽。据我所知,对于最简单的数据库 SQLLite 来说太宽了。

架构二::一张keyvalue表,多张数据表。键值表将具有以下列: cx, scenario, year, place, keyvalue = coerce_to_integer(unique(scenario, year, place, cx))

数据表看起来像这样 keyvalue, result_number, result

这个选项使用层次结构,实际上是一个关系数据库(通过键值关系,对吧)?

但它的缺点是它几乎将我的数据大小增加了三倍:对于每个数据,我需要存储一个键值和一个索引(result_number)。这似乎没有任何意义。

是否有其他选择 例如,是否有类似于 R 的数据库lists可以存储在内存中并从内存中读取?这有点像 NoSQL 数据库吗?

所以,我的问题

  1. 什么样的数据库架构对这个问题有意义?
  2. 我应该从哪里开始学习这些类型的数据库?
  3. R如何与它们交互?我可以从 R 创建数据库吗?如果是这样,怎么做?
2个回答

我使用 R 已经好几年了,但后来转向 Python,所以我很难理解 output.OLS 的数据层次结构。尽管如此,这是我的想法。

内存中数据库:如果您正在努力将 R 对象放入内存中,那么我猜内存要求对于您的笔记本电脑来说太大了(即问题不是由于安装了 32 位 R)。如果是这种情况,在您的笔记本电脑上放置一个内存数据库(如 MongoDB)只会将内存问题转移到一项新技术上。换句话说,R 中的 6 GB 将是 Mongo 中的 6 GB,因此,如果您的笔记本电脑根本无法处理 6 GB,那么您如何将它放在那里并不重要。您可以在 AWS 上设置一个 MongoDB,它可以容纳 100 GB,但是如果您没有 AWS 经验,这可能会很昂贵并且也很困难。

另一方面,MongoDB 擅长存储分层数据,如列表和哈希表/字典(我忘了 R 的术语是什么),如果你有足够的内存,它会很快。

关系数据库(RDMS):我建议走这条路并创建一个宽而深的表。即使您的机器内存有限,您仍然可以从 RDBMS 中获得价值,因为所有内容都有效地存储在磁盘上。如果您在您希望使用/过滤/选择最多的列上创建表索引,即使您的数据是多个 GB,您也可以非常快速地查询您想要的数据。如果您不创建表索引,您的查询将非常缓慢,并且您可能会完全放弃 RDBMS 工作(因此请确保建立索引)。

很久以前,我通过 R 访问 MySQL 的首选包是RMySQLMySQL 已经存在很多年了,所以您可以在 Goggle 上找到大多数问题的答案,但是像 Sequel Pro(仅适用于 Mac)这样的 MySQL 用户界面在维护方面有点落后,所以设置表和数据库可能比以前更具挑战性。您现在必须走命令行路线。

Postgres 现在已取代 MySQL 成为首选的开源数据库,但它缺乏良好的用户界面支持,因此您可能必须通过命令行设置所有内容。我在停止使用 R 后开始使用 Postgres,所以我从未使用过 Postgres R 包,但看起来这里有一个。

无论您使用 MySQL 还是 Postgres,您可能都必须使用 R 之外的命令行来设置数据库,但之后创建、删除、连接或查询表都可以通过 R 完成。RDBMS 系统是也很棒,因为您可以通过创建主键来保证数据质量(无重复)——我发现此功能对我的 R 建模非常有帮助。无论如何,SQL 是每个面向数据的人都应该知道的非常基本的语言,因此设置 RDBMS 并可能学习 SQL 是值得学习的技能。

作为上面的用户,我更多地在 Python 方面,所以我不知道 R 的最佳解决方案是什么,但我建议使用 HDF5 文件。

您可以将不同的对象存储在文件内的不同表中,并且每个表都可以有其层次结构。卷和内存也不应该是限制,因为您不需要将整个文件加载到内存中。