使用DBI

    DBI将与DBMS的连接分为“前端”和“后端”。应用程序只使用公开的前端API。与特定的dbms (SQLite, MySQL, PostgreSQL, MonetDB等)通信的后端设施由司机(其他包),通过S4方法自动调用。

    下面的例子说明了其中的一些DBI功能:

    创建一个临时的内存RSQLite数据库con <- dbConnect(RSQLite::SQLite(), dbname = ":memory:") dbListTables(con) dbWriteTable(con, "mtcars", mtcars) dbListTables(con) dbListFields(con, "mtcars") dbReadTable(con, "mtcars")res <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") dbFetch(res) dbClearResult(res) #或一次一个chunk res <- dbSendQuery(con, "SELECT * FROM mtcars WHERE cyl = 4") while(!dbHasCompleted(res)){chunk <- dbFetch(res, n = 5) print(nrow(chunk))} dbClearResult(res) dbDisconnect(con)

    安装DBI

    • 从CRAN获取发布版本:install.packages (DBI)
    • 从GitHub获取开发版本:devtools: install_github(“rstats-db / DBI”)

    相关的讨论DBI和相关的数据库包发生R-SIG-DB

    类结构

    主要有四种DBI类,其中三个类分别由单独的数据库后端扩展:

    • DBIObject:所有人的通用基类DBI

    • DBIDriver:表示DBMS整体属性的基类。通常生成器函数实例化驱动程序对象如下RSQLite ()RPostgreSQL ()RMySQL ()等。

    • DBIConnection:表示与特定数据库的连接

    • DBIResult: DBMS查询或语句的结果。

    所有类虚拟:它们不能被直接实例化,必须被子类化。

    历史

    DBI的以下历史是由David James贡献的,他是DBI开发背后的驱动力,以及许多实现它的包。

    将S(最初是S3和S4)连接到RDBMS的想法/工作可以追溯到20世纪90年代中后期的贝尔实验室。我做的第一个玩具界面是为了实现John Chamber的早期概念“S中的数据管理”(1991)。在处理非常大的数据库时,它的实现紧跟该接口,并立即显示出一些限制;如果我没记错的话,当时的问题是基于实例的语言,例如,如果你将RDBMS连接到search ()路径,然后需要解析一个符号“foo”,你必须有效地将数据库中的所有对象检查它们的模式/类,即,实例对象本身具有元数据作为属性。实验表明,S3实现的“数据管理”并不真正适合于大型外部RDBMS(可能它从来没有打算这样做)。(但是,请注意,从那时起,John和Duncan Temple Lang在S4中对数据管理进行了大量的概括,包括Duncan在他的robjectables包中的实现,其中他考虑了很多与DBI相关的同步/缓存问题,更普遍的是,与大多数外部接口相关)。

    那时,我们与朗讯的微电子制造部门密切合作——我们那里的同事拥有巨大的Oracle数据库(大部分),我们需要不断地通过这些数据库进行查询SQL * +.我的同事Jake Luciani当时正在用C语言和SQL开发高级应用程序,我们两个人提出了S3直接连接Oracle的第一个实现。我记得的是LinuxPRO * C预编译器(在C代码中嵌入SQL)有很多bug -我们花了很多时间寻找变通方法和技巧,直到我们运行了C接口。当时,贝尔实验室的其他项目开始使用MySQL,我们(在Doug Bates的学生Saikat DebRoy的帮助下,当时是一个暑期实习生)转移到MySQL,并没有打算回头看看非常困难的Oracle界面。正是在这个时候,我将所有的代码从S3方法转移到了S4类和方法,并开始向S/R社区寻求建议和想法等。所有(大部分)这些工作都是在贝尔实验室(Bell Labs)的S3和S4版本上完成的,但我确保它能与S-Plus兼容。在2000年左右的某个时候(我不记得确切的时间),我将所有代码移植到R回归到S3方法,之后(一旦S4类和方法在R中可用),我将所有代码重新实现到R中的S4类和方法(一个痛苦的来回)。就是在这个时候,我决定完全放弃s +。那时,我遇到了一个SQLite的早期实现,我非常感兴趣,认为它是一个非常好的RDBMS,可以用于各种实验等,所以在DBI上实现它是非常容易的。

    在R社区中,有相当多的人对定义数据库的公共接口表现出兴趣,但只有少数人真正提供代码/建议/等等。(Tim Keitt最活跃的是dbi/PostgreSQL包——他也在考虑他所谓的“代理”对象,这让人想起了Duncan一直在做的事情)。Kurt Hornick、Vincent Carey、Robert Gentleman等人对DBI定义提供了建议/评论/支持。卡塔尔世界杯欧洲预选赛赛程表到2003年左右,DBI或多或少地像今天一样得到了实施。

    我相信我会忘记一些(最应该感谢的各种包),但此刻我想到的名字是杰克Luciani (ROracle),并MacQueen和其他早期ROracle用户(超级有帮助),道格·贝茨和他的学生Saikat DebRoy RMySQL,范陈(当时Ripley教授的学生)也导致RMySQL,蒂姆Keitt (PostgrSQL致力于早期S3接口),Torsten Hothorn(与mSQL和MySQL),Ripley教授负责/扩展RODBC包,另外还有John Chambers和Duncan Temple-Lang提供了非常重要的意见和建议。

    实际上,DBI背后的真正动力一直是分布式统计计算提供另一种导入/导出机制,这种观点是由John和Duncan在系统间计算、COM、CORBA等方面的远见和工作所驱动的。我不确定我们中有多少人(即使是现在)真的欣赏到这些想法和概念的全部程度。就像其他语言(C的ODBC, Java的JDBC, Perl的DBI/DBD, Python的dbapi)一样,R/S DBI旨在统一与RDBMS的接口,这样R/S应用程序就可以在DBI之上开发,而不是硬编码到任何一个关系数据库上。我试图遵循的最接近的接口是Python的DBAPI——我已经有一段时间没有研究这个主题了,但我仍然觉得Python的DBAPI是S语言中最干净、最相关的。