Hai phương pháp triển khai phân trang phổ biến hiện nay, bạn đang dùng cách nào?

Hai phương pháp triển khai phân trang phổ biến hiện nay, bạn đang dùng cách nào?

Tin ngắn hàng ngày dành cho bạn
  • Manus đã chính thức mở cửa cho tất cả người dùng rồi đấy mọi người. Cho những ai chưa biết thì đây là một công cụ viết báo cáo (làm mưa làm gió) giống như Deep Research của OpenAI á. Mỗi ngày được miễn phí 300 Credits để nghiên cứu. Mỗi lượt nghiên cứu tiêu tốn tuỳ thuộc vào độ phức tạp của yêu cầu. À với cả họ đang có chương trình tặng miễn phí Credits hay sao á. Như mình thì vào thấy được hẳn 2000.

    Mình dùng thử, so sánh với cùng một lệnh giống như đợt trước dùng bên Deep Research thì nội dung khác biệt nhau hoàn toàn. Manus báo cáo như kiểu viết văn hơn so với OpenAI là các gạch đầu dòng và bảng biểu.

    À lúc đăng ký xong có bắt nhập số điện thoại để xác minh, nếu lỗi thì các bạn đợi qua ngày thử lại xem có được không nhé.

    » Xem thêm
  • Mọi người chắc nghe nhiều về xu hướng tìm kiếm thông tin bằng AI chứ không cần công cụ tìm kiếm như Google nữa rồi đúng không? Không đâu xa ánh xạ vào bản thân thì thấy đúng thật, thi thoảng mới tìm kiếm thôi chứ còn đâu toàn hỏi tụi AI.

    Ngay từ đầu viết blog, thứ mà mình hướng đến là chia sẻ kinh nghiệm chứ không phải là những bài mang nặng tính kỹ thuật, máy móc, hướng dẫn từ đầu... Vì thời điểm đó đã có quá nhiều người làm nội dung này rồi và họ làm rất tốt, tại sao mình phải cố phát minh lại bánh xe? Một điều nữa là tin tưởng độc giả của mình có khả năng tìm hiểu vấn đề. Nếu bạn đọc đủ nhiều các bài viết trên blog thì thấy mình luôn cố gắng chèn thêm các liên kết tham khảo ngoài bài viết, nêu ra vấn đề mở và rất ít khi kết luận chắc chắn một điều gì đó.

    Mình đã cố gắng rèn luyện kỹ năng viết, kỹ năng trình bày và cả cách tương tác với độc giả để mang lại giá trị cho họ. Nhiều lúc ngồi lật lại các con số thống kê thấy lượng đọc bài viết tăng lên lại cảm thấy vui. Nhưng khi nguồn truy cập đến từ Google thì lại thấy buồn, vì điều đó chứng tỏ họ biết đến mình chỉ khi đang cố đi tìm giải pháp, có thể họ chỉ đọc chớp nhoáng, may ra tìm được cách giải quyết và thế là đóng cửa sổ trình duyệt rồi đi như một cơn gió.

    Chừng vài tháng đổ lại đây, một điều khiến mình rất vui đó là lượng người truy cập thẳng vào trang chủ mà không thông qua công cụ tìm kiếm đang tăng dần lên, có nhiều hôm lượng truy cập tự nhiên còn cao hơn cả đến từ Google. Điều đó chứng tỏ độc giả đã có thói quen quay lại trang của mình nhiều hơn và họ tìm thấy được giá trị từ blog mang lại. Vui mừng khôn xiết 🤩

    Bên cạnh đó thì lượng truy cập vào chuyên mục Threads - tức là mục mình đang viết bài này đang cao hơn bao giờ hết. Điều đó chứng tỏ xu hướng đi theo tin nhanh là đúng đắn. Mình có thể ngồi cả ngày để viết tin ngắn cho bạn đọc vì nó rất nhanh mà tiện, không tốn công đi tìm tài liệu để viết, không tốn cả thời gian viết nữa, còn mình thì có rất nhiều thứ để chia sẻ 😅. Nhưng không vì thế mà bỏ bê các bài viết dài, vì dài thì có nhiều thông tin để chia sẻ hơn.

    Vài lời tâm sự thế thôi chứ hơn một tháng nay mình chưa viết bài viết mới nào vì công việc bận quá. Xong lâu dần cứ trì hoãn lại thành lười. À với cả tháng 5 này rất thích hợp để đọc các cuốn sách về cách mạng á. Có hôm đọc đến 2 giờ sáng mới đi ngủ 🥱

    » Xem thêm
  • Mình mới nhìn thấy một trang web khá thú vị nói về các cột mốc đáng nhớ trong lịch sử phát triển Internet toàn cầu: Internet Artifacts

    Chỉ từ 1977 - khi Internet còn nằm trong hộp thí nghiệm thì nhìn xem - giờ đây Internet đã khiến mọi thứ phát triển đến mức nào 🫣

    » Xem thêm

Vấn đề

Phân trang là một trong những yêu cầu cơ bản đối với API lấy dữ liệu là danh sách. Phân trang nhằm giảm tải lượng dữ liệu cần truy vấn cũng như giảm tải lượng dữ liệu truyền về, vì việc lấy hết dữ liệu trong một danh sách rất dài là một điều lãng phí đối với hầu hết tính năng thông thường.

Bài viết ngày hôm nay tôi xin phép trình bày hai kĩ thuật phân trang phổ biến mà dễ dàng triển khai nhất. Mỗi loại có ưu nhược điểm thế nào và nên áp dụng trong trường hợp nào thì mời bạn đọc tiếp bài viết dưới đây nhé.

Phân trang bằng LIMIT & OFFSET

/articles?limit=10&offset=0

Chắc hẳn url trên khá quen thuộc với mọi người, đây là kĩ thuật phân trang dựa trên limitoffset. Nguyên tắc hoạt động của nó khá đơn giản: limit là giới hạn bản ghi còn offset là bắt đầu lấy dữ liệu sau offset hàng.

Ví dụ trên sẽ lấy 10 hàng bắt đầu từ hàng đầu tiên.

Thể hiện của kĩ thuật phân trang này là một tính năng trông giống như hình bên dưới.

Phân trang dựa trên limit offset

Các trang như 1,2,3... đến 30 được hiển thị, người dùng có thể dễ dàng bấm vào trang muốn xem để xem nội dung trong trang đó.

Về phần xử lý phía máy chủ, hầu hết việc lấy dữ liệu ra theo limitoffset là từ trong cơ sở dữ liệu. Hiện tại hầu như cơ sở dữ liệu nào cũng hỗ trợ cú pháp truy vấn limitoffset. Ví dụ như trong PostgreSQL:

SELECT * FROM articles LIMIT 10 OFFSET 0;

Với mỗi limitoffset người dùng gọi lên thay thế vào câu truy vấn bạn sẽ lấy được kết quả mong muốn.

Trong quá trình người dùng đang lấy dữ liệu liên tục, nếu như thời điểm đó có bản ghi được thêm vào hoặc bị xóa sẽ gây ra hiện tượng trùng lặp hoặc thiếu sót dữ liệu ở trang tiếp theo. Vì bản ghi được thêm sẽ đẩy dữ liệu tiếp theo xuống dưới, còn bản ghi bị xóa thì lại kéo dữ liệu lên.

Một điểm trừ nữa là khi số lượng bản ghi rất lớn, truy vấn theo offset có khả năng bị chậm. Nguyên nhân là do cách cơ sở dữ liệu xử lý offset. Hầu hết truy vấn theo offset phải duyệt qua tất cả các hàng cho đến đủ số lượng offset rồi mới bắt đầu lấy dữ liệu. Ví dụ bạn có offset = 1.000.000 thì nó phải duyệt qua 1 triệu hàng rồi bắt đầu lấy từ hàng 1.000.001.

Tóm lại, offsetlimit phù hợp trong trường hợp mong muốn triển khai nhanh, danh sách phân trang được hiển thị theo số thứ tự, khi đó người dùng nhanh chóng điều hướng đến trang họ muốn. Cần cân nhắc sử dụng kĩ thuật này trên tập dữ liệu lớn vì khi đó hiệu năng khả năng cao là bị ảnh hưởng.

Phân trang bằng Cursor

Bạn đã gặp kiểu phân trang này bao giờ chưa? Chỉ bao gồm hai nút Next và Previous như hình dưới đây.

Phân trang dựa trên cursor

Khả năng cao là đang áp dụng kĩ thuật phân trang bằng cursor. Điều đặc biệt của phương pháp này là không có danh sách số thứ tự trang như kĩ thuật limit, offset bên trên.

Một url phân trang bằng cursor có thể trông giống như thế này:

/articles?cursor=4n5pxq24kp

Nguyên tắc hoạt động của cursor khá đơn giản. Ở lượt truy vấn lấy danh sách lần đầu tiên trả về một cursor, sau đó bạn sử dụng cursor này để lấy dữ liệu trong trang tiếp theo. Cứ như thế cho đến khi cursor không trả về nữa tức là dữ liệu đã hết.

{
    "articles": [...],
    "next_cursor": "4n5pxq24kn",
    "prev_cursor": "4n5pxq24kp",
}

Dễ thấy đối với kĩ thuật này bạn không thể nhảy đến một trang xác định nào, vì "con trỏ" chỉ được trả về sau mỗi lần gọi. Thông thường cursor được mã hóa theo quy tắc mà chỉ máy chủ biết, khi truyền lên nó sẽ giải mã để lấy ra dữ liệu cần thiết bên trong.

Ở phía máy chủ, lệnh truy vấn không dùng LIMITOFFSET, thay vào đó là cách truy vấn "lớn hơn hoặc bằng" (>=) kết hợp với index dữ liệu.

Ví dụ, giả sử con trỏ 4n5pxq24kp được máy chủ mã hóa từ id = 10. Khi lấy trang tiếp theo câu lệnh truy vấn giống như là:

SELECT * FROM articles WHERE id > 10 LIMIT 10;

Dễ thấy, nếu đánh index trên trường id của bảng articles thì câu lệnh không cần phải duyệt qua 10 bản ghi đầu tiên để bỏ qua nữa mà nó lấy luôn dữ liệu đằng sau 10. Độ phức tạp lúc này là O(1).

Phương pháp này còn khắc phục được trường hợp dữ liệu được thêm hoặc xóa trong lúc đang phân trang. Đơn giản vì nó không dựa vào offset để lấy bản ghi tiếp theo mà nó dựa vào phép so sánh. Giả sử bản ghi thứ 10 bị xóa đi thì trang tiếp theo vẫn lấy được đủ 10 bản ghi kể từ bản ghi thứ 10 thay vì thứ 9 nếu áp dụng offset.

Rõ ràng cách tiếp cận này về mặt hiệu suất cao hơn hẳn so với limitoffset, tuy nhiên thời gian triển khai và độ phức tạp có thể cao hơn so với phương pháp thông thường. Người dùng không thể điều hướng đến một trang mong muốn và yêu cầu bạn phải có một trường dữ liệu có thể sắp xếp đã được đánh index.

Tổng kết

Trên đây, tôi vừa trình bày hai kĩ thuật phân trang phổ biến. limit, offset thì đơn giản dễ triển khai tuy nhiên gặp vấn đề về hiệu năng trên tập dữ liệu rất lớn. Cursor thì cho hiệu năng tốt nhưng lại có một vài hạn chế khi sử dụng cùng độ phức tạp cao hơn. Mỗi phương pháp đều thể hiện ra ưu nhược điểm, chúng ta không nhất thiết phải chọn cursor vì hiệu năng cao mà thay vào đó biết cách lựa chọn phương pháp cho phù hợp với bài toán mà bạn đang xử lý.

Cao cấp
Hello

Tôi & khao khát "chơi chữ"

Bạn đã thử viết? Và rồi thất bại hoặc chưa ưng ý? Tại 2coffee.dev chúng tôi đã có quãng thời gian chật vật với công việc viết. Đừng nản chí, vì giờ đây chúng tôi đã có cách giúp bạn. Hãy bấm vào để trở thành hội viên ngay!

Bạn đã thử viết? Và rồi thất bại hoặc chưa ưng ý? Tại 2coffee.dev chúng tôi đã có quãng thời gian chật vật với công việc viết. Đừng nản chí, vì giờ đây chúng tôi đã có cách giúp bạn. Hãy bấm vào để trở thành hội viên ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.

Bình luận (0)

Nội dung bình luận...