Самый эффективный способ доступа к базе данных SQL с блестящей панели? - PullRequest
0 голосов
/ 04 сентября 2018

В настоящее время я работаю над личным проектом по созданию блестящей информационной панели, которая отслеживает ежемесячные финансы (доходы, расходы, сбережения и т. Д.) И визуализирует их. Этот проект также является инструментом для меня, чтобы научиться применять 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) извлекать релевантные данные только тогда, когда функция требует этого (но много раз)

...