Sử dụng SQL để đọc và ghi vào cơ sở dữ liệu

1. Trước khi bắt đầu

Bạn đang dùng nhiều ứng dụng trực tiếp lưu trữ dữ liệu trên thiết bị. Ứng dụng Đồng hồ lưu trữ các chuông báo định kỳ của bạn, ứng dụng Google Maps lưu danh sách các lượt tìm kiếm gần đây của bạn, và ứng dụng Danh bạ cho phép bạn thêm, chỉnh sửa và xoá thông tin liên hệ của mình.

Việc duy trì dữ liệu – duy trì hoặc lưu trữ dữ liệu trên thiết bị – là một phần quan trọng trong quá trình phát triển Android. Dữ liệu được duy trì ổn định sẽ đảm bảo nội dung do người dùng tạo sẽ không bị mất khi ứng dụng bị đóng hoặc lưu lại dữ liệu tải từ Internet xuống để sau này không cần tải xuống lại.

SQLite là một công cụ phổ biến do SDK Android cung cấp cho các ứng dụng Android để lưu trữ dữ liệu. SQLite cung cấp một cơ sở dữ liệu quan hệ cho phép bạn trình bày dữ liệu theo cách tương tự như cách sắp xếp dữ liệu bằng các lớp Kotlin. Lớp học lập trình này sẽ chỉ cho bạn kiến thức cơ bản về SQL (Structured Query Language — Ngôn ngữ truy vấn có cấu trúc). Tuy không thực sự là một ngôn ngữ lập trình, nhưng SQL cung cấp cho bạn cách thức để đọc và sửa đổi cơ sở dữ liệu SQLite đơn giản và linh hoạt chỉ với một vài dòng mã.

Trong bài này, sau khi nắm được kiến thức cơ bản về SQL, sau này bạn có thể sử dụng thư viện Room để duy trì cho các ứng dụng của mình.

2. Các khái niệm chính về cơ sở dữ liệu quan hệ

Cơ sở dữ liệu là gì?

Nếu đã quen thuộc với chương trình bảng tính như Google Trang tính, thì chắc hẳn bạn cũng đã quen thuộc với một hình thức tương tự là cơ sở dữ liệu (database).

Một bảng tính bao gồm nhiều bảng dữ liệu riêng biệt hoặc từng bảng tính riêng lẻ trong cùng một bảng tính lớn.

1f2b00d3ca083c4a.png

Mỗi bảng gồm các cột xác định nội dung mà dữ liệu sẽ đại diện, cùng các dòng đại diện cho từng mục với giá trị tương ứng cho mỗi cột. Ví dụ: bạn có thể xác định cột cho mã nhận dạng, tên, chuyên ngành và điểm của học viên.

a441da5cc7be346b.png

Mỗi dòng chứa dữ liệu của một học viên, với các giá trị cho mỗi cột tương ứng.

6131d8a59996f521.png

Cơ sở dữ liệu quan hệ cũng hoạt động theo cách tương tự.

  • Các bảng xác định các nhóm dữ liệu cấp cao mà bạn muốn đại diện, chẳng hạn như học viên và giảng viên.
  • Các cột xác định dữ liệu mà mỗi dòng trong bảng chứa.
  • Các dòng chứa dữ liệu thực tế bao gồm các giá trị tương ứng với mỗi cột trong bảng.

Cấu trúc của cơ sở dữ liệu quan hệ cũng phản ánh những kiến thức bạn đã biết về các lớp (class) và đối tượng (object) Kotlin.

data class Student(
    id: Int,
    name: String,
    major: String,
    gpa: Double
)
  • Các lớp (chẳng hạn như các bảng) sẽ mô hình hoá dữ liệu mà bạn muốn biểu thị trong ứng dụng.
  • Các thuộc tính (chẳng hạn như các cột) sẽ xác định các phần dữ liệu cụ thể mà mỗi thực thể của lớp phải chứa.
  • Các đối tượng (chẳng hạn như các dòng) là dữ liệu thực tế. Các đối tượng chứa giá trị cho mỗi thuộc tính được xác định trong lớp, tương tự như dòng chứa giá trị cho mỗi cột được xác định trong bảng dữ liệu.

Cũng giống như một bảng tính có thể chứa nhiều trang tính và một ứng dụng có thể chứa nhiều lớp, một cơ sở dữ liệu có thể chứa nhiều bảng. Một cơ sở dữ liệu sẽ được gọi là cơ sở dữ liệu quan hệ (relational database) khi cơ sở dữ liệu đó có thể lập mô hình mối quan hệ giữa các bảng. Ví dụ: một học viên cao học chỉ có thể có một giáo sư với vai trò là cố vấn luận văn tiến sĩ, trong khi giáo sư đó có thể là cố vấn luận văn tiến sĩ cho nhiều học viên.

7f1b56e05520dc3.png

Mỗi bảng trong cơ sở dữ liệu quan hệ chứa một giá trị nhận dạng duy nhất cho các hàng, chẳng hạn như một cột nơi giá trị trong mỗi hàng là một số nguyên tăng tự động. Giá trị nhận dạng này được gọi là khoá chính.

Khi một bảng tham chiếu đến khoá chính của một bảng khác, thì khoá đó sẽ được gọi là khoá ngoại (foreign key). Sự hiện diện của một khoá ngoại chứng tỏ là có mối quan hệ giữa các bảng.

SQLite là gì?

SQLite là một cơ sở dữ liệu quan hệ thường dùng. Cụ thể, SQLite là một thư viện C gọn nhẹ để quản lý cơ sở dữ liệu quan hệ bằng Ngôn ngữ truy vấn có cấu trúc, được gọi là SQL và đôi khi phát âm nhanh là "sequel".

Bạn không cần phải học C hoặc bất cứ ngôn ngữ lập trình mới nào để xử lý được cơ sở dữ liệu quan hệ. SQL chỉ đơn giản là một cách thức để bạn thêm và truy xuất dữ liệu qua cơ sở dữ liệu quan hệ, bằng một vài dòng mã.

Biểu thị dữ liệu bằng SQLite

Trong Kotlin, bạn đã quen thuộc với các kiểu dữ liệu như IntBoolean. Cơ sở dữ liệu SQLite cũng sử dụng các kiểu dữ liệu! Các cột trong bảng dữ liệu phải có một kiểu dữ liệu cụ thể. Bảng sau đây liên kết các kiểu dữ liệu Kotlin phổ biến với các kiểu dữ liệu tương đương trong SQLite.

Kiểu dữ liệu Kotlin

Kiểu dữ liệu SQLite

Int

INTEGER (SỐ NGUYÊN)

String

VARCHAR hoặc TEXT (VĂN BẢN)

Boolean

BOOLEAN

Float, Double

REAL (SỐ THỰC)

Các bảng trong cơ sở dữ liệu và các cột trong mỗi bảng được gọi chung là giản đồ. Trong phần tiếp theo, bạn sẽ tải tập dữ liệu khởi động xuống và tìm hiểu thêm về giản đồ của tập dữ liệu này.

3. Tải tập dữ liệu khởi động xuống

Cơ sở dữ liệu mà lớp học lập trình này sẽ tạo là dành cho một ứng dụng email giả định. Lớp học lập trình này sử dụng các ví dụ quen thuộc, chẳng hạn như sắp xếp và lọc thư, hoặc tìm kiếm theo văn bản tiêu đề hoặc người gửi, để minh hoạ tất cả những tính năng mạnh mẽ mà bạn có thể tận dụng ở SQL. Ví dụ này cũng đảm bảo rằng bạn sẽ có kinh nghiệm về các tình huống có thể gặp trong một ứng dụng trước khi xử lý Room trong lộ trình tiếp theo.

Tải dự án khởi động xuống qua nhánh compose của kho lưu trữ SQL cơ bản trên GitHub tại đây.

Sử dụng Trình kiểm tra cơ sở dữ liệu

Để sử dụng Trình kiểm tra cơ sở dữ liệu, hãy thực hiện các bước sau:

  1. Chạy ứng dụng SQL Basics trong Android Studio. Khi ứng dụng khởi chạy, bạn sẽ thấy màn hình sau.

76e94dfe2234c2b1.png

  1. Trong Android Studio, hãy nhấp vào View > Tool Windows > App Inspection (Xem > Cửa sổ công cụ > Kiểm tra ứng dụng).

cd5dd859d31cbab3.png

Lúc này, bạn sẽ thấy một thẻ mới ở dưới cùng có nhãn App Inspection (Kiểm tra ứng dụng) có thẻ Database Inspector (Trình kiểm tra cơ sở dữ liệu) đã chọn sẵn. Ngoài ra còn có thêm hai thẻ khác, nhưng bạn chưa cần sử dụng. Có thể mất vài giây để tải, nhưng bạn sẽ thấy một danh sách ở bên trái chứa các bảng dữ liệu mà bạn có thể chọn để chạy truy vấn.

5ace24ac5cc15abc.png

  1. Nhấp vào nút Open New Query Tab (Mở thẻ truy vấn mới) để mở một ngăn và chạy truy vấn trên cơ sở dữ liệu.

277ecff401ca5f1a.png

Bảng email có 7 cột:

  • id: Khoá chính.
  • subject: Dòng tiêu đề của email.
  • sender: Địa chỉ email của người đã gửi email đó.
  • folder: Thư mục để tìm email, chẳng hạn như Inbox (Hộp thư đến) hoặc Spam (Thư rác).
  • starred: Người dùng có gắn dấu sao cho email đó hay không.
  • read: Người dùng có đọc email đó hay không.
  • received: Dấu thời gian khi nhận được email.

4. Đọc dữ liệu bằng câu lệnh SELECT

Câu lệnh SQL SELECT

Câu lệnh SQL (đôi khi được gọi là truy vấn) được dùng để đọc hoặc thao tác trên cơ sở dữ liệu.

Bạn sẽ dùng câu lệnh SELECT để đọc dữ liệu qua cơ sở dữ liệu SQLite. Câu lệnh SELECT đơn giản gồm có từ khoá SELECT, theo sau là tên cột, sau đó là từ khoá FROM, tiếp đến là tên bảng. Mỗi câu lệnh SQL kết thúc bằng dấu chấm phẩy (;).

2d7ff99736b072b9.png

Câu lệnh SELECT cũng có thể trả về dữ liệu từ nhiều cột. Bạn phải phân tách các tên cột bằng dấu phẩy.

cf94edd5de825043.png

Nếu muốn chọn tất cả cột từ bảng, bạn sẽ sử dụng ký tự đại diện (*) thay cho tên cột.

fb75d3033c59949a.png

Trong cả hai trường hợp, một câu lệnh SELECT đơn giản như trên sẽ trả về mọi dòng trong bảng. Bạn chỉ cần chỉ định tên cột mà mình muốn trả về.

Dùng câu lệnh SELECT để đọc dữ liệu email

Một trong những chức năng chính mà ứng dụng email cần thực hiện là hiển thị một danh sách thư. Với cơ sở dữ liệu SQL, bạn có thể lấy thông tin này bằng câu lệnh SELECT.

  1. Hãy đảm bảo bạn đã chọn bảng email trong Database Inspector (Trình kiểm tra cơ sở dữ liệu).

ffc77f938ea09071.png

  1. Trước tiên, hãy thử chọn từng cột trong mỗi dòng trong bảng email.
SELECT * FROM email;
  1. Nhấp vào nút Run (Chạy) ở góc dưới cùng bên phải của hộp văn bản. Lưu ý rằng toàn bộ bảng email đều được trả về.

4c3ea237c6ed2b57.png

  1. Bây giờ, hãy cố gắng chỉ chọn tiêu đề (subject) cho mỗi dòng.
SELECT subject FROM email;
  1. Xin lưu ý rằng truy vấn này một lần nữa trả về mọi dòng nhưng chỉ đối với một cột đó.

69a20935721dcc2.png

  1. Bạn cũng có thể chọn nhiều cột. Hãy thử chọn tiêu đề (subject) và người gửi (sender).
SELECT subject, sender FROM email;
  1. Lưu ý rằng truy vấn sẽ trả về mọi dòng trong bảng email, nhưng chỉ trả về các giá trị của cột tiêu đề (subject) và người gửi (sender).

4ae739dad54397ea.png

Xin chúc mừng! Bạn vừa thực thi truy vấn đầu tiên của mình. Vậy là tốt rồi, nhưng hãy xem đó như là bước đầu làm quen với SQL.

Bạn có thể viết các câu lệnh SELECT cụ thể hơn nhiều bằng cách thêm mệnh đề để chỉ định một tập hợp con dữ liệu và thậm chí thay đổi cách định dạng đầu ra. Trong các phần sau, bạn sẽ tìm hiểu về các mệnh đề thường dùng của câu lệnh SELECT và cách định dạng dữ liệu.

5. Sử dụng câu lệnh SELECT với các hàm tổng hợp và các giá trị riêng biệt

Giảm số cột có hàm tổng hợp

Các câu lệnh SQL có thể làm được nhiều việc hơn là chỉ trả về các dòng. SQL cung cấp nhiều hàm có thể thực hiện một phép toán hoặc một phép tính trên một cột cụ thể, chẳng hạn như tìm giá trị lớn nhất hoặc có thể đếm số giá trị riêng biệt đối với một cột cụ thể. Các hàm này được gọi là hàm tổng hợp (aggregate function). Từ một cột cụ thể, thay vì trả về tất cả dữ liệu của một cột cụ thể, bạn có thể trả về một giá trị duy nhất.

Ví dụ về hàm tổng hợp SQL:

  • COUNT(): Trả về tổng số dòng phù hợp với truy vấn.
  • SUM(): Trả về giá trị tổng của tất cả giá trị từ các dòng đã chọn trong cột.
  • AVG(): Trả về giá trị trung bình (trung bình cộng) của tất cả giá trị đã chọn trong cột.
  • MIN(): Trả về giá trị nhỏ nhất trong cột đã chọn.
  • MAX(): Trả về giá trị lớn nhất trong cột đã chọn.

Thay vì tên cột, bạn có thể gọi một hàm tổng hợp rồi truyền một tên cột vào làm đối số giữa các dấu ngoặc đơn.

6730a62d583a0d9.png

Thay vì trả về giá trị của cột đó cho mỗi dòng trong bảng, một giá trị duy nhất sẽ được trả về khi gọi hàm tổng hợp.

Hàm tổng hợp có thể là một cách hiệu quả để thực hiện các phép tính trên một giá trị khi bạn không cần đọc tất cả dữ liệu trong cơ sở dữ liệu. Ví dụ: Bạn có thể tìm trung bình cộng của các giá trị trong một cột mà không cần tải toàn bộ cơ sở dữ liệu vào Danh sách và thực hiện việc này theo cách thủ công.

Hãy xem một số hàm tổng hợp đang hoạt động trong bảng email:

  1. Có thể ứng dụng muốn biết tổng số email nhận được. Bạn có thể thực hiện việc này bằng cách sử dụng hàm COUNT() và ký tự đại diện (*).
SELECT COUNT(*) FROM email;
  1. Truy vấn trả về một giá trị duy nhất. Bạn có thể hoàn toàn thực hiện việc này bằng truy vấn SQL, mà không cần mã Kotlin để đếm các dòng theo cách thủ công.

5d49b987545184bb.png

  1. Để biết thời gian nhận thư gần đây nhất, bạn có thể sử dụng hàm MAX() trên cột thư đã nhận (received) vì dấu thời gian Unix gần đây nhất là số lớn nhất.
SELECT MAX(received) FROM email;
  1. Truy vấn này trả về một kết quả duy nhất, dấu thời gian cao nhất (gần đây nhất) trong cột đã nhận.

d0241dce845c3955.png

Lọc kết quả trùng lặp bằng DISTINCT

Khi chọn một cột, bạn có thể đặt từ khoá DISTINCT trước cột này. Có thể đây sẽ là phương pháp hữu ích nếu bạn muốn xoá các cột trùng lặp khỏi kết quả truy vấn.

4f02533256302f26.png

Ví dụ: nhiều ứng dụng email có tính năng tự động hoàn thành địa chỉ email. Có thể bạn muốn đưa tất cả địa chỉ email đã gửi thư cho bạn vào danh sách và cho thấy danh sách địa chỉ này.

  1. Hãy chạy truy vấn sau để trả về cột sender đối với từng dòng.
SELECT sender FROM email;
  1. Bạn sẽ quan sát thấy kết quả chứa nhiều nội dung trùng lặp. Chắc chắn đây không phải là một trải nghiệm lý tưởng!

4f0489d1668dbede.png

  1. Hãy thêm từ khoá DISTINCT trước cột người gửi rồi chạy lại truy vấn.
SELECT DISTINCT sender FROM email;
  1. Lưu ý rằng hiện tại thì kết quả nhỏ hơn nhiều và mọi giá trị đều riêng biệt.

43a47ad8d18fee6e.png

Bạn cũng có thể đặt từ khoá DISTINCT trước tên cột trong hàm tổng hợp.

55c45cb9c258e882.png

Giả sử bạn muốn biết số người gửi riêng biệt trong cơ sở dữ liệu. Bạn có thể đếm số lượng người gửi riêng biệt bằng hàm tổng hợp COUNT() và với từ khoá DISTINCT trên cột sender.

  1. Thực hiện câu lệnh SELECT, truyền DISTINCT sender vào hàm COUNT().
SELECT COUNT(DISTINCT sender) FROM email;
  1. Lưu ý truy vấn này cho chúng ta biết rằng có 14 người gửi riêng biệt.

19ae43b0bc9a927e.png

6. Lọc truy vấn bằng mệnh đề WHERE

Nhiều ứng dụng email cung cấp cho bạn tính năng lọc thư dựa trên một số tiêu chí nhất định (ví dụ: dữ liệu, cụm từ tìm kiếm, thư mục, người gửi, v.v.). Đối với những loại trường hợp sử dụng này, bạn có thể thêm mệnh đề WHERE vào truy vấn SELECT.

Sau tên bảng, trên một dòng mới, bạn có thể thêm từ khoá WHERE theo sau là một biểu thức. Khi viết các truy vấn SQL phức tạp hơn, chúng ta thường đặt mỗi mệnh đề trên một dòng mới để dễ đọc.

707b0641aa2de0f.png

Truy vấn này thực hiện việc kiểm tra boolean cho từng dòng đã chọn. Nếu kết quả kiểm tra trả về là đúng (true), kết quả này sẽ đưa dòng đó vào kết quả của truy vấn. Các dòng mà truy vấn này trả về sai (false) sẽ không được đưa vào kết quả.

Ví dụ: Một ứng dụng email có thể có các bộ lọc cho thư rác, thùng rác, thư nháp hoặc bộ lọc do người dùng tạo. Các phần hướng dẫn sau sẽ giúp bạn thực hiện điều này bằng mệnh đề WHERE:

  1. Chạy câu lệnh SELECT để trả về toàn bộ cột (*) trên bảng email, bao gồm cả mệnh đề WHERE để kiểm tra điều kiện folder = 'inbox'. Không, đó không phải là lỗi đánh máy: bạn sẽ sử dụng một dấu bằng để kiểm tra đẳng thức trong SQL, đồng thời dùng dấu ngoặc đơn thay vì dấu ngoặc kép để biểu thị giá trị chuỗi.
SELECT * FROM email
WHERE folder = 'inbox';
  1. Kết quả chỉ trả về các dòng tương ứng với thư trong hộp thư đến của người dùng.

6e9f2a17186d7faa.png

Toán tử logic với mệnh đề WHERE

Các mệnh đề WHERE của SQL không được giới hạn ở chỉ một biểu thức. Bạn có thể sử dụng từ khoá AND, tương đương với toán tử and của Kotlin (&&), để chỉ đưa vào những kết quả đáp ứng cả hai điều kiện.

d8a698416e55d11b.png

Ngoài ra, bạn có thể dùng từ khoá OR, tương đương với toán tử Kotlin or của Kotlin (||), để đưa các dòng đáp ứng một trong hai điều kiện vào kết quả.

f3cecac289e7650d.png

Để dễ đọc, bạn cũng có thể phủ định một biểu thức bằng từ khoá NOT.

27300a0a38ef0343.png

Nhiều ứng dụng email cho phép có nhiều bộ lọc (ví dụ: chỉ thể hiện các email chưa đọc).

Hãy thử những mệnh đề WHERE phức tạp hơn trên bảng email:

  1. Ngoài việc chỉ trả về các thư trong hộp thư đến của người dùng, hãy thử giới hạn kết quả thành các thư chưa đọc (có giá trị của cột đã đọc (read) là sai (false)).
SELECT * FROM email
WHERE folder = 'inbox' AND read = false;
  1. Lưu ý rằng sau khi chạy truy vấn này, các kết quả chỉ chứa các email chưa đọc trong hộp thư đến của người dùng.

d9ebd307a146d320.png

  1. Trả về tất cả email trong thư mục quan trọng (important) OR có gắn dấu sao (starred) (starred = true). Tức là kết quả sẽ gồm có các email trong các thư mục, miễn là các email đó được gắn dấu sao.
SELECT * FROM email
WHERE folder = 'important' OR starred = true;
  1. Quan sát kết quả.

fd2f0dc7b6444956.png

Tìm kiếm văn bản bằng LIKE

Mệnh đề WHERE có thể giúp bạn thực hiện một việc cực kỳ hữu ích là tìm kiếm văn bản trong một cột cụ thể. Bạn sẽ đạt được kết quả này khi chỉ định tên cột, theo sau là từ khoá LIKE, tiếp đến là chuỗi tìm kiếm.

6692c0d491b6f9af.png

Chuỗi tìm kiếm bắt đầu bằng ký hiệu phần trăm (%), theo sau là văn bản cần tìm (Search term – Cụm từ tìm kiếm), tiếp theo là ký hiệu phần trăm (%).

c69c15f654645ee2.png

Nếu bạn đang tìm kiếm một tiền tố (kết quả bắt đầu bằng văn bản đã chỉ định), hãy bỏ qua ký hiệu phần trăm đầu tiên (%).

fbe6a94daaf173ae.png

Hoặc, nếu bạn đang tìm kiếm một hậu tố, hãy bỏ qua ký hiệu phần trăm cuối cùng (%).

141f567c9cbc4029.png

Có nhiều trường hợp sử dụng mà ứng dụng có thể dùng tính năng tìm kiếm bằng văn bản, chẳng hạn như tìm kiếm email chứa văn bản cụ thể trong dòng tiêu đề hoặc cập nhật đề xuất tự động hoàn thành khi người dùng đang nhập.

Các hướng dẫn sau đây sẽ cho phép bạn sử dụng tính năng tìm kiếm bằng văn bản khi truy vấn bảng email.

  1. Các nhân vật của Shakespeare (cũng như các nhân vật trong cơ sở dữ liệu của chúng ta) thích nói về những kẻ lừa gạt (fool). Chạy truy vấn sau để biết tổng số email có dòng chữ "fool" trong dòng tiêu đề.
SELECT COUNT(*) FROM email
WHERE subject LIKE '%fool%';
  1. Quan sát kết quả.

fd2ff96969824b0d.png

  1. Chạy truy vấn sau để trả về tất cả cột từ tất cả dòng có tiêu đề kết thúc bằng chữ "fool".
SELECT * FROM email
WHERE subject LIKE '%fool';
  1. Quan sát thấy 2 hàng bị trả về.

a23379e507e39c0b.png

  1. Chạy truy vấn sau để trả về các giá trị riêng biệt của cột sender bắt đầu bằng chữ cái h.
SELECT DISTINCT sender FROM email
WHERE sender LIKE 'h%';
  1. Lưu ý rằng truy vấn này trả về 3 giá trị: helena@example.com , hyppolytus@example.comhermia@example.com.

47ada07aee5cd8d9.png

7. Nhóm, sắp xếp thứ tự và giới hạn kết quả

Nhóm các kết quả bằng GROUP BY

Bạn vừa xem cách sử dụng các hàm tổng hợp và mệnh đề WHERE để lọc và giảm bớt kết quả. SQL cung cấp một số mệnh đề khác có thể giúp bạn định dạng kết quả truy vấn. Trong số này có các mệnh đề giúp bạn nhóm, sắp xếp và giới hạn kết quả.

Bạn có thể sử dụng mệnh đề GROUP BY để nhóm các kết quả sao cho mọi dòng có cùng giá trị đối với một cột nhất định được nhóm cạnh nhau trong kết quả. Mệnh đề này không thay đổi kết quả, mà chỉ thay đổi thứ tự mà kết quả được trả về.

Để thêm mệnh đề GROUP BY vào câu lệnh SELECT, hãy thêm từ khoá GROUP BY theo sau là tên cột bạn muốn nhóm kết quả theo.

6be095e981498bbf.png

Một trường hợp sử dụng phổ biến là ghép một mệnh đề GROUP BY với một hàm tổng hợp. Mục đích là để phân vùng kết quả của một hàm tổng hợp trên nhiều bộ chứa, chẳng hạn như các giá trị của một cột. Dưới đây là một ví dụ. Giả sử bạn muốn biết được số lượng email trong mỗi thư mục: 'inbox', 'spam', v.v. Bạn có thể chọn cả cột folder và hàm tổng hợp COUNT(), sau đó chỉ định cột folder trong mệnh đề GROUP BY.

  1. Thực hiện truy vấn sau để chọn cột thư mục và kết quả của hàm tổng hợp COUNT(). Sử dụng mệnh đề GROUP BY để nhóm kết quả theo giá trị trong cột folder.
SELECT folder, COUNT(*) FROM email
GROUP BY folder;
  1. Hãy quan sát kết quả. Truy vấn này trả về tổng số email cho từng thư mục.

13b9eb8f5c8230c4.png

Sắp xếp kết quả bằng ORDER BY

Bạn cũng có thể dùng mệnh đề ORDER BY khi sắp xếp các kết quả truy vấn để thay đổi thứ tự kết quả. Thêm từ khoá ORDER BY, theo sau là tên cột, sau đó là hướng sắp xếp.

9cf561c6346ed6e0.png

Theo mặc định, hướng sắp xếp là atheo thứ tự tăng dần (bạn có thể bỏ qua trong mệnh đề ORDER BY). Nếu bạn muốn sắp xếp các kết quả theo thứ tự giảm dần, hãy thêm DESC vào sau tên cột.

Có thể bạn dự kiến rằng một ứng dụng email sẽ cho thấy các email gần đây nhất trước tiên. Các hướng dẫn sau đây giúp bạn thực hiện việc này với mệnh đề ORDER BY.

  1. Thêm mệnh đề ORDER BY để sắp xếp các email chưa đọc, dựa trên cột received. Vì thứ tự tăng dần (thấp nhất hoặc cũ nhất) là thứ tự mặc định, bạn cần sử dụng từ khoá DESC.
SELECT * FROM email
ORDER BY received DESC;
  1. Quan sát kết quả.

6e28aef784a16d1b.png

Bạn có thể sử dụng một mệnh đề ORDER BY với một mệnh đề WHERE. Giả sử người dùng muốn tìm những email cũ có chứa chữ fool. Họ có thể sắp xếp kết quả để cho thấy những email cũ nhất theo thứ tự tăng dần.

  1. Chọn tất cả email có tiêu đề chứa chữ "fool" rồi sắp xếp kết quả theo thứ tự tăng dần. Do thứ tự là tăng dần (đây là thứ tự mặc định khi không có thứ tự nào được chỉ định), bạn không bắt buộc phải dùng từ khoá ASC với mệnh đề ORDER BY.
SELECT * FROM email
WHERE subject LIKE '%fool%'
ORDER BY received ASC;
  1. Hãy lưu ý rằng bạn sẽ thấy kết quả có giá trị cũ nhất (thấp nhất trong cột thư đã nhận) trước tiên trong kết quả đã lọc được trả về.

77ada71b663afab6.png

Giới hạn số lượng kết quả với LIMIT

Cho đến nay, tất cả ví dụ đều trả về từng kết quả riêng biệt trong cơ sở dữ liệu khớp với truy vấn. Trong nhiều trường hợp, bạn chỉ cần cho thấy một số ít dòng trong cơ sở dữ liệu. Bạn có thể thêm mệnh đề LIMIT vào truy vấn để chỉ trả về một số lượng kết quả cụ thể. Thêm từ khoá LIMIT, theo sau là số dòng tối đa mà bạn muốn trả về. Mệnh đề LIMIT (nếu có) sẽ đứng sau mệnh đề ORDER BY.

122152adf15a9fca.png

Nếu muốn, bạn có thể thêm từ khoá OFFSET, theo sau là một con số khác biểu thị số hàng muốn "bỏ qua". Ví dụ: nếu muốn có 10 kết quả tiếp theo, sau 10 kết quả đầu tiên, nhưng không muốn trả về tất cả 20 kết quả, thì bạn có thể sử dụng LIMIT 10 OFFSET 10.

37ad836862573d55.png

Trong một ứng dụng, có thể bạn muốn các email tải nhanh hơn bằng cách chỉ trả về 10 email đầu tiên trong hộp thư đến của người dùng. Sau đó, người dùng có thể cuộn để xem các trang email tiếp theo. Các hướng dẫn sau đây sử dụng mệnh đề LIMIT để đạt được hành vi này.

  1. Thực hiện câu lệnh SELECT sau đây để nhận tất cả email trong hộp thư đến của người dùng theo thứ tự giảm dần và giới hạn 10 kết quả đầu tiên.
SELECT * FROM email
WHERE folder = 'inbox'
ORDER BY received DESC
LIMIT 10;
  1. Lưu ý rằng chỉ có 10 kết quả được trả về.

5b228d8053956489.png

  1. Sửa đổi và chạy lại truy vấn để đưa vào từ khoá OFFSET có giá trị 10.
SELECT * FROM email
WHERE folder = 'inbox'
ORDER BY received DESC
LIMIT 10 OFFSET 10;
  1. Truy vấn này sẽ trả về 10 kết quả theo thứ tự giảm dần. Tuy nhiên, truy vấn này bỏ qua tập hợp gồm 10 kết quả đầu tiên.

83a6ddbf6ef92b89.png

8. Chèn, cập nhật và xoá dữ liệu trong cơ sở dữ liệu

Chèn dữ liệu vào cơ sở dữ liệu

Ngoài việc đọc từ cơ sở dữ liệu, vẫn còn có các câu lệnh SQL khác nhau để ghi vào cơ sở dữ liệu. Bạn có thấy rằng ngay từ đầu mình cần có một cách thức để thực hiện những điều này trên dữ liệu?

Bạn có thể thêm một dòng mới vào cơ sở dữ liệu bằng câu lệnh INSERT. Câu lệnh INSERT bắt đầu bằng INSERT INTO, theo sau là tên bảng mà bạn muốn chèn một dòng mới. Từ khoá VALUES xuất hiện trên một dòng mới, theo sau là một bộ dấu ngoặc đơn chứa danh sách các giá trị được phân tách bằng dấu phẩy. Bạn cần liệt kê các giá trị theo cùng thứ tự các cột cơ sở dữ liệu.

97b93929d6de2d0e.png

Giả sử người dùng nhận được một email mới, và chúng ta cần lưu trữ email đó trong cơ sở dữ liệu của ứng dụng. Chúng ta có thể sử dụng câu lệnh INSERT để thêm một dòng mới vào bảng email.

  1. Đối với một email mới, hãy thực hiện câu lệnh INSERT với dữ liệu sau đây. Vì là email mới nên ban đầu email này xuất hiện trong folder Hộp thư đến (inbox) và chưa đọc (unread). Giá trị của NULL được cung cấp cho cột id, tức là id sẽ tự động được tạo với số nguyên tự động tăng dần có mặt tiếp theo.
INSERT INTO email
VALUES (
    NULL, 'Lorem ipsum dolor sit amet', 'sender@example.com', 'inbox', false, false, CURRENT_TIMESTAMP
);
  1. Lưu ý rằng kết quả được chèn vào cơ sở dữ liệu bằng id44.
SELECT * FROM email
WHERE sender = 'sender@example.com';

12a3e77309771dd8.png

Cập nhật dữ liệu hiện có trong cơ sở dữ liệu

Sau khi đã chèn dữ liệu vào một bảng, thì sau này bạn vẫn có thể thay đổi bảng đó. Bạn có thể cập nhật giá trị của một hoặc nhiều cột bằng cách dùng câu lệnh UPDATE. Câu lệnh UPDATE bắt đầu bằng từ khoá UPDATE, theo sau là tên bảng, sau đó là mệnh đề SET.

8ee88a5985aec77e.png

Mệnh đề SET gồm từ khoá SET, theo sau là tên cột bạn muốn cập nhật.

bc255ece789859f.png

Câu lệnh UPDATE thường gồm mệnh đề WHERE để chỉ định một dòng hoặc nhiều dòng mà bạn muốn cập nhật bằng cặp giá trị cột đã chỉ định.

e64b7b343feb6224.png

Chẳng hạn, nếu người dùng muốn đánh dấu một email là đã đọc, thì bạn sẽ dùng câu lệnh UPDATE để cập nhật cơ sở dữ liệu. Các hướng dẫn sau đây cho phép bạn đánh dấu email được chèn ở bước trước là đã đọc.

  1. Thực hiện câu lệnh UPDATE sau đây để đặt dòng có id44 sao cho giá trị của cột readtrue.
UPDATE email
SET read = true
WHERE id = 44;
  1. Chạy câu lệnh SELECT cho dòng cụ thể đó để xác thực kết quả.
SELECT read FROM email
WHERE id = 44;
  1. Lưu ý rằng giá trị của cột đã đọc hiện là 1 cho giá trị "true" thay vì 0 cho giá trị "false".

74e9af167fa49ba3.png

Xoá một dòng khỏi cơ sở dữ liệu

Cuối cùng, bạn có thể dùng câu lệnh DELETE SQL để xoá một hoặc nhiều dòng khỏi bảng. Câu lệnh DELETE bắt đầu bằng từ khoá DELETE, theo sau là từ khoá FROM, sau đó là tên bảng, sau cùng là mệnh đề WHERE để chỉ định dòng hoặc các dòng mà bạn muốn xoá.

a7e56405c5e5aaab.png

Những hướng dẫn sau đây sử dụng câu lệnh DELETE để xoá dòng đã chèn trước đó và sau đó đã được cập nhật khỏi cơ sở dữ liệu.

  1. Thực hiện câu lệnh DELETE sau để xoá dòng có id44 khỏi cơ sở dữ liệu.
DELETE FROM email
WHERE id = 44;
  1. Xác thực nội dung thay đổi bằng câu lệnh SELECT.
SELECT * FROM email
WHERE id = 44;
  1. Lưu ý rằng một dòng có id44 không còn tồn tại nữa.

b026810cf2fd6e44.png

9. Tóm tắt

Xin chúc mừng! Bạn đã học được rất nhiều kiến thức! Giờ đây, bạn có thể đọc một cơ sở dữ liệu bằng cách dùng câu lệnh SELECT, gồm cả mệnh đề WHERE, GROUP BY, ORDER BYLIMIT để lọc kết quả. Bạn cũng đã tìm hiểu các hàm tổng hợp thường dùng, từ khoá DISTINCT để chỉ định kết quả riêng biệt và từ khoá LIKE để tìm kiếm văn bản trong các giá trị trong một cột. Cuối cùng, bạn đã tìm hiểu cách INSERT, UPDATEDELETE các dòng trong bảng dữ liệu.

Bạn sẽ trực tiếp áp dụng những kỹ năng này trong Room, và nhờ vào kiến thức của bạn về SQL, bạn sẽ có được hành trang tốt hơn để đảm bảo việc duy trì dữ liệu trong các ứng dụng sau này.

Cú pháp câu lệnh SELECT:

346bed4fda774ca7.png

10. Tìm hiểu thêm

Tuy chúng tôi chỉ tập trung vào các khái niệm cơ bản về SQL và một số trường hợp sử dụng phổ biến trong quá trình phát triển Android, nhưng SQL còn có thể làm được rất nhiều việc khác. Hãy tham khảo các tài nguyên sau đây như một nguồn tham khảo bổ sung cho những điều bạn đã tìm hiểu hoặc để tìm hiểu thêm về chủ đề này.