从闪亮的仪表板访问SQL数据库的最有效方法?

时间:2018-09-04 06:06:28

标签: r sqlite shiny shinydashboard rsqlite

我目前正在一个个人项目上,制作一个闪亮的仪表板,以跟踪每月的财务状况(收入,支出,储蓄等)并将其可视化。这个项目也是我学习如何应用SQL的工具,因此我正在使用RSQLite来管理数据库。

当前,我正在考虑闪亮的应用程序如何与SQL数据库交互。我想到了几种解决方案:

1)在会话开始时,该应用程序将数据库整体复制到一个反应变量中,该变量将继续进行计算并生成图。如果数据库很大,这可能会占用大量内存。 这是一个最小的工作示例

## creating example database
require("RSQLite")
require("shiny")
require("ggplot2")
require("reshape2")

db <- dbConnect(RSQLite::SQLite(), "")
dbSendQuery(conn = db,
            "CREATE TABLE db 
            (month TEXT,
             income REAL,
             expense REAL,
             savings REAL)")
dbSendQuery(conn = db,
            "INSERT INTO db VALUES
            ('September',
            4000,
            2800,
            1200)")
dbSendQuery(conn = db,
            "INSERT INTO db VALUES
            ('October',
            4000,
            3000,
            1000)")

## copy db into reactive
if (interactive()) {
  options(device.ask.default = FALSE)


  app <- shinyApp(
    ui = fluidPage(
      textOutput("avg.spend"),
      textOutput("avg.save"),
      plotOutput("plot")
    ),
    server = function(input, output) {
      df <- reactiveValues(x = dbGetQuery(conn = db, 'SELECT * FROM db'))
      output$avg.spend <- renderText({
        expense <- paste0("Average expenses: $", mean(df$x$expense))
        print(expense)
      })
      output$avg.save <- renderText({
        savings <- paste0("Average savings: $", mean(df$x$savings))
        print(savings)
      })
      output$plot <- renderPlot({
        df.melt <- melt(df$x, id = "month")
        p <- ggplot(df.melt, aes(month)) + geom_bar(aes(weight = value, fill = variable), position = "identity")
        plot(p)
      })
    }
  )

  runApp(app)
}

2)每当需要进行计算或需要生成图时,应用程序都会查询SQL数据库以获取所需的条目。但是,这可能意味着多个重复查询。 此处的示例(仅显示闪亮的应用程序部分以避免重复):

app <- shinyApp(
    ui = fluidPage(
      textOutput("avg.spend"),
      textOutput("avg.save"),
      plotOutput("plot")
    ),
    server = function(input, output) {
      output$avg.spend <- renderText({
        qe <- dbGetQuery(conn = db, 'SELECT expense FROM db')
        expense <- paste0("Average expenses: $", mean(qe$expense))
        print(expense)
      })
      output$avg.save <- renderText({
        qs <- dbGetQuery(conn = db, 'SELECT savings FROM db')
        savings <- paste0("Average savings: $", mean(qs$savings))
        print(savings)
      })
      output$plot <- renderPlot({
        df <- dbGetQuery(conn = db, 'SELECT * FROM db')
        df.melt <- melt(df, id = "month")
        p <- ggplot(df.melt, aes(month)) + geom_bar(aes(weight = value, fill = variable), position = "identity")
        plot(p)
      })
    }
  )

哪个解决方案更优雅,资源占用更少?另外,在比较这两种解决方案时,我可能会错过一些事情吗?预先感谢!

编辑:添加了示例代码。想改一下我的问题:
1)一次将数据库存储为一个反应变量

2)仅在功能需要时(但多次)提取相关数据

0 个答案:

没有答案