DBI: แนะนำ 4 ขั้นตอนในการเชื่อมต่อและ query ข้อมูลจาก database โดยใช้ภาษา R — ตัวอย่างการทำงานกับ Chinook database

ในบทความนี้ เราจะมาดู 4 ขั้นตอนในการเชื่อมต่อและทำงานกับ database ในภาษา R ด้วย DBI package กัน:

  1. Get started
  2. Explore the database
  3. Query the database
  4. Close the connection

ถ้าพร้อมแล้ว ไปเริ่มกันเลย


  1. 💻 Step 1. Get Started
    1. 📦 DBI Package
    2. ⬇️ Install & Connect
  2. 👀 Step 2. Explore the Database
    1. 1️⃣ dbListTable()
    2. 2️⃣ dbGetQuery()
  3. 🔍 Step 3. Query the Database
    1. 1️⃣ dbReadTable()
    2. 2️⃣ dbGetQuery()
    3. 3️⃣ dbSendQuery()
  4. 🤚 Step 4. Close the Connection
  5. 💪 Summary
  6. 😺 GitHub
  7. 📃 References
  8. ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

💻 Step 1. Get Started

📦 DBI Package

DBI (Database Interface) เป็น package สำหรับเชื่อมต่อกับ database ซึ่งทำให้เราทำงานกับ database ในภาษา R ได้โดยตรง

ในบทความนี้ เรามาลองดูการใช้งาน DBI ผ่านการทำงานกับ Chinook SQLite database กัน (เราสามารถโหลด Chinook เพื่อลองทำตามได้จาก GitHub)

.

⬇️ Install & Connect

ในขั้นแรกของการใช้งาน เราจะติดตั้งและโหลด DBI พร้อมกับ package สำหรับ database ที่เราจะทำงานด้วย

อย่างในกรณีนี้ เราจะติดตั้งและโหลด RSQLite package เพราะเราจะทำงานกับ SQLite database

Note: ถ้าเราทำงานกับ database อื่น เราจะต้องติดตั้งและโหลด package อื่น เช่น:

  • MySQL → RMySQL
  • PostgresSQL → RPostgresSQL
  • Oracle → ROracle

ติดตั้ง packages:

# Install
install.packages("DBI")
install.packages("RSQLite")

โหลด packages:

# Load
library(DBI)
library(RSQLite)

หลังติดตั้งและโหลด packages แล้ว เราจะเชื่อมต่อกับ database ด้วย dbConnect() แบบนี้:

# Connect to database
con <- dbConnect(RSQLite::SQLite(),
                 "chinook.sqlite")

Note: ในกรณีที่ database ไม่ได้อยู่ใน working directory เราจะต้องใช้ absolute file path แทนชื่อไฟล์ เช่น:

# Connect to database
con <- dbConnect(RSQLite::SQLite(),
                 "C:/Users/YourUser/Documents/R_Projects/my_data/chinook.sqlite")

เท่านี้ เราก็พร้อมที่จะทำงานกับ database กันแล้ว


👀 Step 2. Explore the Database

เริ่มแรก เราจะสำรวจ database เพื่อทำความเข้าใจโครงสร้างข้อมูลกันก่อน

เรามี 2 functions ที่ช่วยเราได้ ได้แก่:

  1. dbListTables(): ดูรายชื่อ tables ทั้งหมดใน database
  2. dbGetQuety(): ดู columns ใน table ที่ต้องการ

.

1️⃣ dbListTable()

ตัวอย่าง:

# List tables in the database
dbListTables(con)

ผลลัพธ์:

 [1] "Album"         "Artist"        "Customer"      "Employee"     
 [5] "Genre"         "Invoice"       "InvoiceLine"   "MediaType"    
 [9] "Playlist"      "PlaylistTrack" "Track"  

.

2️⃣ dbGetQuery()

ตัวอย่าง:

# List columns in a table
dbGetQuery(con,
           "PRAGMA table_info(Artist)")

ผลลัพธ์:

  cid     name          type notnull dflt_value pk
1   0 ArtistId       INTEGER       1         NA  1
2   1     Name NVARCHAR(120)       0         NA  0

ในกรณีที่เราต้องการดู columns ในทุก table เราสามารถใช้ for loop ช่วยได้แบบนี้:

# Get the table list
tables <- dbListTables(con)

# Get all columns
for (table_name in tables) {
  
  # Print the table name
  message(paste0("\\n👉 Table: ", table_name))
  
  # Get the columns
  column_info <- dbGetQuery(con,
                            paste0("PRAGMA table_info(",
                                   table_name, 
                                   ")"))
  
  # Print the columns
  print(column_info)
}

ผลลัพธ์:

👉 Table: Album
  cid     name          type notnull dflt_value pk
1   0  AlbumId       INTEGER       1         NA  1
2   1    Title NVARCHAR(160)       1         NA  0
3   2 ArtistId       INTEGER       1         NA  0
👉 Table: Artist
  cid     name          type notnull dflt_value pk
1   0 ArtistId       INTEGER       1         NA  1
2   1     Name NVARCHAR(120)       0         NA  0
👉 Table: Customer
   cid         name         type notnull dflt_value pk
1    0   CustomerId      INTEGER       1         NA  1
2    1    FirstName NVARCHAR(40)       1         NA  0
3    2     LastName NVARCHAR(20)       1         NA  0
4    3      Company NVARCHAR(80)       0         NA  0
5    4      Address NVARCHAR(70)       0         NA  0
6    5         City NVARCHAR(40)       0         NA  0
7    6        State NVARCHAR(40)       0         NA  0
8    7      Country NVARCHAR(40)       0         NA  0
9    8   PostalCode NVARCHAR(10)       0         NA  0
10   9        Phone NVARCHAR(24)       0         NA  0
11  10          Fax NVARCHAR(24)       0         NA  0
12  11        Email NVARCHAR(60)       1         NA  0
13  12 SupportRepId      INTEGER       0         NA  0
👉 Table: Employee
   cid       name         type notnull dflt_value pk
1    0 EmployeeId      INTEGER       1         NA  1
2    1   LastName NVARCHAR(20)       1         NA  0
3    2  FirstName NVARCHAR(20)       1         NA  0
4    3      Title NVARCHAR(30)       0         NA  0
5    4  ReportsTo      INTEGER       0         NA  0
6    5  BirthDate     DATETIME       0         NA  0
7    6   HireDate     DATETIME       0         NA  0
8    7    Address NVARCHAR(70)       0         NA  0
9    8       City NVARCHAR(40)       0         NA  0
10   9      State NVARCHAR(40)       0         NA  0
11  10    Country NVARCHAR(40)       0         NA  0
12  11 PostalCode NVARCHAR(10)       0         NA  0
13  12      Phone NVARCHAR(24)       0         NA  0
14  13        Fax NVARCHAR(24)       0         NA  0
15  14      Email NVARCHAR(60)       0         NA  0
👉 Table: Genre
  cid    name          type notnull dflt_value pk
1   0 GenreId       INTEGER       1         NA  1
2   1    Name NVARCHAR(120)       0         NA  0
👉 Table: Invoice
  cid              name          type notnull dflt_value pk
1   0         InvoiceId       INTEGER       1         NA  1
2   1        CustomerId       INTEGER       1         NA  0
3   2       InvoiceDate      DATETIME       1         NA  0
4   3    BillingAddress  NVARCHAR(70)       0         NA  0
5   4       BillingCity  NVARCHAR(40)       0         NA  0
6   5      BillingState  NVARCHAR(40)       0         NA  0
7   6    BillingCountry  NVARCHAR(40)       0         NA  0
8   7 BillingPostalCode  NVARCHAR(10)       0         NA  0
9   8             Total NUMERIC(10,2)       1         NA  0
👉 Table: InvoiceLine
  cid          name          type notnull dflt_value pk
1   0 InvoiceLineId       INTEGER       1         NA  1
2   1     InvoiceId       INTEGER       1         NA  0
3   2       TrackId       INTEGER       1         NA  0
4   3     UnitPrice NUMERIC(10,2)       1         NA  0
5   4      Quantity       INTEGER       1         NA  0
👉 Table: MediaType
  cid        name          type notnull dflt_value pk
1   0 MediaTypeId       INTEGER       1         NA  1
2   1        Name NVARCHAR(120)       0         NA  0
👉 Table: Playlist
  cid       name          type notnull dflt_value pk
1   0 PlaylistId       INTEGER       1         NA  1
2   1       Name NVARCHAR(120)       0         NA  0
👉 Table: PlaylistTrack
  cid       name    type notnull dflt_value pk
1   0 PlaylistId INTEGER       1         NA  1
2   1    TrackId INTEGER       1         NA  2
👉 Table: Track
  cid         name          type notnull dflt_value pk
1   0      TrackId       INTEGER       1         NA  1
2   1         Name NVARCHAR(200)       1         NA  0
3   2      AlbumId       INTEGER       0         NA  0
4   3  MediaTypeId       INTEGER       1         NA  0
5   4      GenreId       INTEGER       0         NA  0
6   5     Composer NVARCHAR(220)       0         NA  0
7   6 Milliseconds       INTEGER       1         NA  0
8   7        Bytes       INTEGER       0         NA  0
9   8    UnitPrice NUMERIC(10,2)       1         NA  0

🔍 Step 3. Query the Database

หลังสำรวจ database แล้ว เราสามารถ query ข้อมูลได้ด้วย 3 functions ได้แก่:

  1. dbReadTable()
  2. dbGetQuery()
  3. dbSendQuery()

.

1️⃣ dbReadTable()

เราจะใช้ dbReadTable() เมื่อต้องการดึงข้อมูลทั้งหมดมาจาก table ที่ต้องการ

ตัวอย่างเช่น ดูข้อมูลทั้งหมดใน Genre:

# Query with dbReadTable()
dbReadTable(con,
            "Genre")

ผลลัพธ์:

   GenreId               Name
1        1               Rock
2        2               Jazz
3        3              Metal
4        4 Alternative & Punk
5        5      Rock And Roll
6        6              Blues
7        7              Latin
8        8             Reggae
9        9                Pop
10      10         Soundtrack
11      11         Bossa Nova
12      12     Easy Listening
13      13        Heavy Metal
14      14           R&B/Soul
15      15  Electronica/Dance
16      16              World
17      17        Hip Hop/Rap
18      18    Science Fiction
19      19           TV Shows
20      20   Sci Fi & Fantasy
21      21              Drama
22      22             Comedy
23      23        Alternative
24      24          Classical
25      25              Opera

.

2️⃣ dbGetQuery()

ในกรณีที่เราต้องการดูข้อมูลแบบเจาะจง เราจะใช้ dbGetQuery() ซึ่งต้องการ 2 arguments:

  1. Connection ที่เชื่อมต่อกับ database
  2. SQL query ที่กำหนดข้อมูลที่ต้องการจาก database

ตัวอย่างการใช้งาน #1 – ดึงข้อมูลลูกค้าที่มาจากบราซิล:

# Query with dbGetQuery() - example 1
dbGetQuery(con,
           "SELECT
              CustomerId,
              FirstName,
              LastName, Email
            FROM
              Customer
            WHERE
              country = 'Brazil';")

ผลลัพธ์:

  CustomerId FirstName  LastName                         Email
1          1      Luís Gonçalves          luisg@embraer.com.br
2         10   Eduardo   Martins      eduardo@woodstock.com.br
3         11 Alexandre     Rocha              alero@uol.com.br
4         12   Roberto   Almeida roberto.almeida@riotur.gov.br
5         13  Fernanda     Ramos      fernadaramos4@uol.com.br

ตัวอย่าง #2 – คำนวณยอดขายรวมของแต่ละประเทศ โดยเรียงจากมากไปน้อย:

# Query with dbGetQuery() - example 2
dbGetQuery(con,
           "SELECT
              BillingCountry,
              SUM(Total) AS TotalSales
            FROM
              Invoice
            GROUP BY
              BillingCountry
            ORDER BY
              TotalSales DESC;")

ผลลัพธ์:

   BillingCountry TotalSales
1             USA     523.06
2          Canada     303.96
3          France     195.10
4          Brazil     190.10
5         Germany     156.48
6  United Kingdom     112.86
7  Czech Republic      90.24
8        Portugal      77.24
9           India      75.26
10          Chile      46.62
11        Ireland      45.62
12        Hungary      45.62
13        Austria      42.62
14        Finland      41.62
15    Netherlands      40.62
16         Norway      39.62
17         Sweden      38.62
18          Spain      37.62
19         Poland      37.62
20          Italy      37.62
21        Denmark      37.62
22        Belgium      37.62
23      Australia      37.62
24      Argentina      37.62

ตัวอย่าง #3 – ดึงชื่อเพลงและชื่ออัลบัม 10 อันดับแรก:

# Query with dbGetQuery() - example 3
dbGetQuery(con,
           "SELECT
              T.Name AS TrackName,
              A.Title AS AlbumTitle
            FROM
              Track AS T
            JOIN
              Album AS A ON T.AlbumID = A.AlbumID
            LIMIT 10;")

ผลลัพธ์:

                                 TrackName                            AlbumTitle
1  For Those About To Rock (We Salute You) For Those About To Rock We Salute You
2                        Balls to the Wall                     Balls to the Wall
3                          Fast As a Shark                     Restless and Wild
4                        Restless and Wild                     Restless and Wild
5                     Princess of the Dawn                     Restless and Wild
6                    Put The Finger On You For Those About To Rock We Salute You
7                          Let's Get It Up For Those About To Rock We Salute You
8                         Inject The Venom For Those About To Rock We Salute You
9                               Snowballed For Those About To Rock We Salute You
10                              Evil Walks For Those About To Rock We Salute You

.

3️⃣ dbSendQuery()

dbSendQuery() ทำงานเหมือนกับ dbGetQuery() แต่ต่างกันที่ dbGetQuery() จะยังส่งข้อมูลใด ๆ กลับมาจนกว่าเราจะเรียกดูด้วย dbFetch()

ยกตัวอย่างเช่น ดูข้อมูลลูกค้า 10 รายชื่อแรกเมื่อเรียงตามนามสกุล:

# Send query
res <- dbSendQuery(con,
                   "SELECT
                      CustomerId,
                      LastName,
                      FirstName,
                      Email
                    FROM
                      Customer
                    ORDER BY
                      LastName
                    LIMIT 10;")

# Fetch results
dbFetch(res)

ผลลัพธ์:

   CustomerId   LastName FirstName                         Email
1          12    Almeida   Roberto roberto.almeida@riotur.gov.br
2          28    Barnett     Julia           jubarnett@gmail.com
3          39    Bernard   Camille      camille.bernard@yahoo.fr
4          18     Brooks  Michelle             michelleb@aol.com
5          29      Brown    Robert              robbrown@shaw.ca
6          21      Chase     Kathy           kachase@hotmail.com
7          26 Cunningham   Richard      ricunningham@hotmail.com
8          41     Dubois      Marc       marc.dubois@hotmail.com
9          34  Fernandes      João           jfernandes@yahoo.pt
10         30    Francis    Edward           edfrancis@yachoo.ca

เมื่อเราเรียกดูข้อมูลทั้งหมดแล้ว เราจะไม่สามารถเรียกดูซ้ำได้:

# Fetch results
dbFetch(res)

ผลลัพธ์:

> dbFetch(res)
[1] CustomerId LastName   FirstName  Email     
<0 rows> (or 0-length row.names)

ทั้งนี้ เราสามารถกำหนดจำนวนข้อมูลที่จะเรียกดูในแต่ละครั้งได้ เช่น:

# Send query
res <- dbSendQuery(con,
                   "SELECT
                      CustomerId,
                      LastName,
                      FirstName,
                      Email
                    FROM
                      Customer
                    ORDER BY
                      LastName
                    LIMIT 10;")

# Fetch five, twice
dbFetch(res, n = 5)
dbFetch(res, n = 5)
dbFetch(res, n = 5)

ผลลัพธ์:

> dbFetch(res, n = 5)
  CustomerId LastName FirstName                         Email
1         12  Almeida   Roberto roberto.almeida@riotur.gov.br
2         28  Barnett     Julia           jubarnett@gmail.com
3         39  Bernard   Camille      camille.bernard@yahoo.fr
4         18   Brooks  Michelle             michelleb@aol.com
5         29    Brown    Robert              robbrown@shaw.ca
> dbFetch(res, n = 5)
  CustomerId   LastName FirstName                    Email
1         21      Chase     Kathy      kachase@hotmail.com
2         26 Cunningham   Richard ricunningham@hotmail.com
3         41     Dubois      Marc  marc.dubois@hotmail.com
4         34  Fernandes      João      jfernandes@yahoo.pt
5         30    Francis    Edward      edfrancis@yachoo.ca
> dbFetch(res, n = 5)
[1] CustomerId LastName   FirstName  Email     
<0 rows> (or 0-length row.names)

เราสามารถใช้ dbSendQuery() และ dbFetch() เพื่อดูข้อมูลเป็นชุด ๆ แทนที่จะดูข้อมูลทั้งหมดในครั้งเดียวแบบ dbGetQuery()

Note: ในกรณีที่เราต้องการลบ query ที่เราส่งไป database ด้วย dbSendQuery() ให้เราใช้ dbClearResult():

# Clear results
dbClearResult(res)

🤚 Step 4. Close the Connection

สุดท้าย เมื่อเราทำงานกับ database เสร็จแล้ว เราต้องสิ้นสุดการเชื่อมต่อกับ database ด้วย dbDisconnect():

# Close the connection
dbDisconnect(con)

เป็นอันจบการทำงานกับ database ด้วย DBI


💪 Summary

ในบทความนี้ เราได้ไปดูวิธีการใช้งาน DBI เพื่อทำงานกับ database กัน:

เชื่อมต่อ database:

  • dbConnect()

สำรวจ database:

  • dbListTables()
  • dbGetQuery()

Query ข้อมูล:

  • dbReadTable()
  • dbGetQuery()
  • dbSendQuery(), dbFetch(), และ dbClearResult()

ปิดการเชื่อมต่อ:

  • dbDisconnect()

😺 GitHub

ดู code และ database ในบทความนี้ได้ที่ GitHub


📃 References


✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

📕 ขอฝากหนังสือเล่มแรกในชีวิตด้วยนะครับ 😆

🙋 ใครที่กำลังเรียนจิตวิทยาหรือทำงานสายจิตวิทยา และเบื่อที่ต้องใช้ software ราคาแพงอย่าง SPSS และ Excel เพื่อทำข้อมูล

💪 ผมขอแนะนำ R Book for Psychologists หนังสือสอนใช้ภาษา R เพื่อการวิเคราะห์ข้อมูลทางจิตวิทยา ที่เขียนมาเพื่อนักจิตวิทยาที่ไม่เคยมีประสบการณ์เขียน code มาก่อน

ในหนังสือ เราจะปูพื้นฐานภาษา R และพาไปดูวิธีวิเคราะห์สถิติที่ใช้บ่อยกัน เช่น:

  • Correlation
  • t-tests
  • ANOVA
  • Reliability
  • Factor analysis

🚀 เมื่ออ่านและทำตามตัวอย่างใน R Book for Psychologists ทุกคนจะไม่ต้องพึง SPSS และ Excel ในการทำงานอีกต่อไป และสามารถวิเคราะห์ข้อมูลด้วยตัวเองได้ด้วยความมั่นใจ

แล้วทุกคนจะแปลกใจว่า ทำไมภาษา R ง่ายขนาดนี้ 🙂‍↕️

👉 สนใจดูรายละเอียดหนังสือได้ที่ meb:

Comments

One response to “DBI: แนะนำ 4 ขั้นตอนในการเชื่อมต่อและ query ข้อมูลจาก database โดยใช้ภาษา R — ตัวอย่างการทำงานกับ Chinook database”

Leave a comment