Android & Kiến trúc

Phân trang theo khóa kép cho danh sách Android

Giữ đủ các mục trùng thời điểm khi đọc trang tiếp từ SQLite.

Vấn đề nghiên cứuNâng cao6 phút đọcPython

Thích và đánh giá Bình luận và hỏi đáp
Sắp theo mốc DESC, ID DESC; không chỉ lọc bằng mốc thời gian.
Sắp theo mốc DESC, ID DESC; không chỉ lọc bằng mốc thời gian. Mở hình lớn ↗

1. Tạo một thứ tự toàn phần

Danh sách xếp bài theo thời điểm mới nhất, nhưng nhiều bài có cùng thời điểm. Thêm mã duy nhất vào cuối thứ tự sắp xếp, chẳng hạn ORDER BY moc DESC, id DESC. Nếu con trỏ chỉ giữ mốc, truy vấn trang tiếp với điều kiện nhỏ hơn mốc sẽ bỏ sót các dòng còn lại có cùng mốc.

2. Tạo con trỏ từ dòng cuối thực tế

Với con trỏ (100, 3), dòng sau có mốc nhỏ hơn 100 hoặc cùng mốc nhưng mã nhỏ hơn 3. Dạng so sánh cặp trong SQLite diễn đạt trực tiếp điều này khi hai cột đều giảm dần và không có giá trị NULL. Với thứ tự tăng giảm trộn nhau, nên viết điều kiện từng cột cho đúng hướng.

3. Chạy mẫu SQLite ngay trên Python

Dữ liệu có ba dòng ở mốc 100 và một dòng ở mốc 99. Hai dòng đầu có mã 4 và 3, trang sau phải có 2 và 1. Mã chạy hai truy vấn rồi so kết quả. Hãy bỏ id khỏi điều kiện trang sau để tái hiện việc bỏ mất mã 2, mặc dù trang đầu hiển thị đúng.

Chạy ví dụ bằng python android_phan_trang_khoa_kep.py.

Môi trường thực hành. Python 3.10 trở lên. Ví dụ dùng thư viện chuẩn Python. Đây là mô hình Python để kiểm tra logic trước khi chuyển sang dự án Android.

Python · android_phan_trang_khoa_kep.pyTải mã nguồn
import sqlite3

with sqlite3.connect(":memory:") as db:
    db.execute("CREATE TABLE bai(id INTEGER PRIMARY KEY, moc INTEGER NOT NULL)")
    db.executemany("INSERT INTO bai VALUES (?, ?)", [(4, 100), (3, 100), (2, 100), (1, 99)])
    dau = db.execute("SELECT id, moc FROM bai ORDER BY moc DESC, id DESC LIMIT 2").fetchall()
    id_cuoi, moc_cuoi = dau[-1]
    sau = db.execute(
        "SELECT id, moc FROM bai WHERE (moc, id) < (?, ?) ORDER BY moc DESC, id DESC LIMIT 2",
        (moc_cuoi, id_cuoi),
    ).fetchall()
assert [row[0] for row in dau + sau] == [4, 3, 2, 1]
print(dau, sau)

4. Quyết định cách xử lý bản ghi thay đổi

Con trỏ ổn định đối với thứ tự đã định, nhưng việc cập nhật khóa sắp xếp giữa hai lần đọc vẫn có thể làm mục nhảy trang. Nếu cần ảnh chụp cố định, chọn phiên dữ liệu hoặc mốc chốt và nêu rõ dữ liệu thêm, sửa được xử lý thế nào. Kiểm tra thêm chỉ mục và kế hoạch truy vấn khi dữ liệu lớn.

Đọc thêm Ví dụ phân trang theo khóa của SQLite.