shiny工程化实践之数据库

dplyr:翻译R到SQL

  • 基本数学运算: +, -, *, /, %%, ^html

  • 数学函数: abs, acos, acosh, asin, asinh, atan, atan2, atanh, ceiling, cos, cosh, cot, coth, exp, floor, log, log10, round, sign, sin, sinh, sqrt, tan, tanhreact

  • 逻辑判断: <, <=, !=, >=, >, ==, %in%web

  • 异或判断: &, &&, |, ||, !, xorsql

  • 聚合函数: mean, sum, min, max, sd, var数据库

支持常见的 SparkHiveMySQL做为计算引擎。apache

使用 explain 函数能够查看到对应的SQL翻译:segmentfault

explain(your_dplyr_manipulation_chain)

pool:链接池管理

为何在操做数据库上不是直接使用DBI,而是要多加一层pool呢?答案很简单,由于使用pool能够作链接池的管理,复用连接提高性能。pool为使用者提供了一个伪连接,若是是一条以前请求过的SQL,那么pool会将以前请求过的数据直接返回而无需等待。服务器

Shiny中,pool会在全部session都结束的时候自动地回收资源而不须要其余操做。session

这里是shiny官方blog上的一个例子:函数

library(shiny)
library(DBI)
library(pool)

pool <- dbPool(
  drv = RMySQL::MySQL(),
  dbname = "shinydemo",
  host = "shiny-demo.csa7qlmguqrf.us-east-1.rds.amazonaws.com",
  username = "guest",
  password = "guest"
)

ui <- fluidPage(
  textInput("ID", "Enter your ID:", "5"),
  tableOutput("tbl"),
  numericInput("nrows", "How many cities to show?", 10),
  plotOutput("popPlot")
)

server <- function(input, output, session) {
  output$tbl <- renderTable({
    sql <- "SELECT * FROM City WHERE ID = ?id;"
    query <- sqlInterpolate(pool, sql, id = input$ID)
    dbGetQuery(pool, query)
  })
  output$popPlot <- renderPlot({
    query <- paste0("SELECT * FROM City LIMIT ",
                    as.integer(input$nrows)[1], ";")
    df <- dbGetQuery(pool, query)
    pop <- df$Population
    names(pop) <- df$Name
    barplot(pop)
  })
}

shinyApp(ui, server)

数据库操做之事务

原来的显示事务操做

conn <- poolCheckout(pool)

dbWithTransaction(conn, {
  dbGetQuery(conn, A)
  dbGetQuery(conn, B)
})

poolReturn(conn)

如今的隐式事务操做

dbWithTransaction(pool, {
  dbGetQuery(pool, A)
  dbGetQuery(pool, B)
})

输入异常处理

由于有了req函数,咱们能够在响应式代码块中轻松应对下面几类类似地空值判断:

  1. FALSE

  2. NULL

  3. ""

  4. 空的原子向量

  5. 仅仅包含缺失值的原子向量

  6. try-error 类的对象中出现包含的 FALSE 的逻辑向量 (可见于 ?base::try)

  7. 是否点击了 actionButton

下面是shiny 官方博客中的一个例子

library(shiny)

ui <- fluidPage(
  selectInput("datasetName", "Dataset", c("", "pressure", "cars")),
  plotOutput("plot"),
  tableOutput("table")
)

server <- function(input, output, session) {
  dataset <- reactive({
    # Make sure requirements are met
    req(input$datasetName)

    get(input$datasetName, "package:datasets", inherits = FALSE)
  })

  output$plot <- renderPlot({
    plot(dataset())
  })

  output$table <- renderTable({
    head(dataset(), 10)
  })
}

shinyApp(ui, server)

参考资料