- Konu sahibi
- #1
İlk sayfayı almak için sonuç kümesine sabit bir sıralama verip veritabanına kaç satır atlayacağını ve kaç satır döndüreceğini belirtin. Örneğin PostgreSQL ve MySQL gibi sistemlerde
Sayfalama için önce sayfa başına kaç kayıt gösterileceğini, sonra da istenen sayfadan önce kaç kaydın atlanacağını hesaplayın:
Burada
Uygulama kodunda sayfa numarası ve sayfa boyutu dışarıdan geliyorsa
Ardından bu iki değer, kullandığınız programlama dili veya veritabanı istemcisinin güvenli parametre bağlama yöntemiyle sorguya aktarılmalıdır. Kullanıcıdan gelen metni SQL cümlesine doğrudan birleştirmeyin. Sayfa numarasını ve sayfa boyutunu önce tam sayıya dönüştürmek, aralıklarını doğrulamak ve sorgu değerlerini parametre olarak göndermek SQL ekleme riskini azaltır.
Sayfalama komutu kullandığınız veritabanına göre değişebilir. Temel yaklaşım aynı olsa da
SQL Server ve
Bu sorgular aynı mantığı uygular: ilk 40 kaydı atlar ve sonraki 20 kaydı döndürür. Sonucun boş gelmesi, sayfa numarasının mevcut kayıt sayısını aşmış olabileceğini gösterir; tek başına sorgunun hatalı olduğunu kanıtlamaz. Uygulama bu durumda boş liste gösterebilir veya istenen sayfayı son geçerli sayfaya çekebilir.
Kullanıcıya toplam sayfa sayısını göstermek için aynı filtrelerle ayrı bir
Örneğin sonuç 157 ve sayfa boyutu 20 ise toplam sayfa sayısı yukarı yuvarlanarak 8 olur. Son sayfada 17 kayıt bulunması normaldir.
Toplam sayıyı hesaplamak ek bir sorgu ve özellikle karmaşık filtrelerde ek maliyet oluşturabilir. Toplam sayfa bilgisi gerekli değilse yalnızca kayıt sorgusunu çalıştırmak daha uygun olabilir. Ayrıca
Bu durumda son alınan kaydın sıralama anahtarını sonraki sorguya gönderin. İlk istek:
Son dönen kaydın
Bu yaklaşımda tarih eşitliğini
İlk sayfada başlangıç imleci bulunmaz; sonraki isteklerde son kaydın sıralama değerleri gönderilir. Sonuç sayfa boyutundan azsa başka sayfa bulunmadığı anlaşılır. Bu yöntem toplam sayfa sayısını kendiliğinden vermez; kullanıcıya
Küçük veya orta büyüklükteki listelerde, kullanıcı belirli bir sayfaya doğrudan gidecekse
Sonsuz kaydırma, “daha fazlasını yükle” düğmesi, çok büyük tablolar veya sık güncellenen kayıtlar için anahtar tabanlı sayfalama daha uygundur. Her iki yöntemde de sayfalamada kullanılan
Filtre sorgusunda
Sayfa sorgusu ile toplam sayı sorgusu arasında veri değişebileceğini de hesaba katın. Bir işlem sırasında tutarlı bir görünüm kesin olarak gerekiyorsa veritabanınızın işlem yalıtımı ve tutarlı okuma özelliklerini ayrıca değerlendirmeniz gerekir; normal liste ekranlarında ise boş veya eksik bir son sayfa, verilerin değişmesinin doğal sonucu olabilir.
LIMIT 20 OFFSET 40, üçüncü sayfanın 20 satırını getirir. Ancak büyük tablolar veya sık değişen veriler için OFFSET yerine son görülen kaydın anahtarından devam eden anahtar tabanlı sayfalama daha güvenilir ve verimli olur.LIMIT ve OFFSET ile temel sayfalama
Sayfalama için önce sayfa başına kaç kayıt gösterileceğini, sonra da istenen sayfadan önce kaç kaydın atlanacağını hesaplayın:
SQL:
-- Varsayımsal olarak 20 kayıt gösteriliyor.
-- 3. sayfa için: (3 - 1) * 20 = 40
SELECT id, baslik, created_at
FROM yazilar
ORDER BY created_at DESC, id DESC
LIMIT 20 OFFSET 40;
Burada
ORDER BY zorunlu olmasa bile pratikte mutlaka kullanılmalıdır. Sıralama verilmezse veritabanı satırları belirli bir düzende döndürmek zorunda değildir; aynı sayfa isteği farklı sırayla sonuç verebilir. created_at değerleri eşit olabileceği için id ikinci sıralama ölçütü olarak eklenmiştir. Böylece sıralama mümkün olduğunca kararlı hâle gelir.Uygulama kodunda sayfa numarası ve sayfa boyutu dışarıdan geliyorsa
page değerinin en az 1, page_size değerinin de makul bir üst sınır içinde olduğunu kontrol edin. Atlanacak kayıt sayısı şu şekilde hesaplanır:
Kod:
offset = (page - 1) * page_size
Ardından bu iki değer, kullandığınız programlama dili veya veritabanı istemcisinin güvenli parametre bağlama yöntemiyle sorguya aktarılmalıdır. Kullanıcıdan gelen metni SQL cümlesine doğrudan birleştirmeyin. Sayfa numarasını ve sayfa boyutunu önce tam sayıya dönüştürmek, aralıklarını doğrulamak ve sorgu değerlerini parametre olarak göndermek SQL ekleme riskini azaltır.
Farklı SQL sistemlerinde sözdizimi
Sayfalama komutu kullandığınız veritabanına göre değişebilir. Temel yaklaşım aynı olsa da
LIMIT, OFFSET ve FETCH ifadeleri her sistemde aynı biçimde kullanılmaz.| Veritabanı | Örnek sayfalama sözdizimi |
|---|---|
| PostgreSQL / MySQL | ORDER BY... LIMIT 20 OFFSET 40 |
| SQL Server | ORDER BY... OFFSET 40 ROWS FETCH NEXT 20 ROWS ONLY |
| Oracle 12c ve sonrası | ORDER BY... OFFSET 40 ROWS FETCH NEXT 20 ROWS ONLY |
FETCH kullanan sistemlerde ORDER BY ifadesi gerekir. Örneğin:
SQL:
SELECT id, baslik, created_at
FROM yazilar
ORDER BY created_at DESC, id DESC
OFFSET 40 ROWS FETCH NEXT 20 ROWS ONLY;
Bu sorgular aynı mantığı uygular: ilk 40 kaydı atlar ve sonraki 20 kaydı döndürür. Sonucun boş gelmesi, sayfa numarasının mevcut kayıt sayısını aşmış olabileceğini gösterir; tek başına sorgunun hatalı olduğunu kanıtlamaz. Uygulama bu durumda boş liste gösterebilir veya istenen sayfayı son geçerli sayfaya çekebilir.
Toplam sayfa sayısını hesaplama
Kullanıcıya toplam sayfa sayısını göstermek için aynı filtrelerle ayrı bir
COUNT(*) sorgusu çalıştırılır:
SQL:
SELECT COUNT(*) AS toplam_kayit
FROM yazilar
WHERE durum = 'yayinda';
Örneğin sonuç 157 ve sayfa boyutu 20 ise toplam sayfa sayısı yukarı yuvarlanarak 8 olur. Son sayfada 17 kayıt bulunması normaldir.
COUNT(*) sorgusundaki WHERE koşulları, asıl liste sorgusundaki koşullarla aynı değilse gösterilen toplam sayfa sayısı listeyle uyuşmaz.Toplam sayıyı hesaplamak ek bir sorgu ve özellikle karmaşık filtrelerde ek maliyet oluşturabilir. Toplam sayfa bilgisi gerekli değilse yalnızca kayıt sorgusunu çalıştırmak daha uygun olabilir. Ayrıca
COUNT(*) sonucu, kayıtlar sorgular arasında eklenip silinebileceği için kesin ve değişmez bir görüntü sağlamaz; sayfalama anındaki yaklaşık durumu gösterir.Büyük tablolar için anahtar tabanlı sayfalama
OFFSET değeri büyüdükçe veritabanının atlanacak satırları bulup geçmesi pahalılaşabilir. Ayrıca kullanıcı bir sayfayı görüntülerken araya yeni kayıtlar eklenirse sonraki sayfada bazı kayıtlar tekrar görünebilir veya bazıları atlanabilir.Bu durumda son alınan kaydın sıralama anahtarını sonraki sorguya gönderin. İlk istek:
SQL:
SELECT id, baslik, created_at
FROM yazilar
ORDER BY created_at DESC, id DESC
LIMIT 20;
Son dönen kaydın
created_at ve id değerlerini, örneğin 2026-10-20 12:30:00 ve 145 olarak aldığınızı varsayalım. Sonraki sayfa için bu kayıttan daha eski olanları isteyin:
SQL:
SELECT id, baslik, created_at
FROM yazilar
WHERE (created_at, id) < ('2026-10-20 12:30:00', 145)
ORDER BY created_at DESC, id DESC
LIMIT 20;
Bu yaklaşımda tarih eşitliğini
id ile çözdüğünüz için yalnızca tarihe göre filtreleme yapmaktan daha güvenilir bir sıralama elde edersiniz. Veritabanınız satır değerlerinden oluşan karşılaştırmayı desteklemiyorsa eşdeğer koşulu açıkça yazabilirsiniz:
SQL:
WHERE created_at < :son_tarih
OR (created_at = :son_tarih AND id < :son_id)
İlk sayfada başlangıç imleci bulunmaz; sonraki isteklerde son kaydın sıralama değerleri gönderilir. Sonuç sayfa boyutundan azsa başka sayfa bulunmadığı anlaşılır. Bu yöntem toplam sayfa sayısını kendiliğinden vermez; kullanıcıya
1 / 8 gibi kesin bir gösterim sunmanız gerekiyorsa ayrıca toplam kayıt sayısını hesaplamanız gerekir.Hangi yöntemi seçmelisiniz?
Küçük veya orta büyüklükteki listelerde, kullanıcı belirli bir sayfaya doğrudan gidecekse
LIMIT/OFFSET kullanımı daha basittir. Sayfa numarasını URL'de taşımak ve toplam sayfa sayısını göstermek de bu modelle kolaydır.Sonsuz kaydırma, “daha fazlasını yükle” düğmesi, çok büyük tablolar veya sık güncellenen kayıtlar için anahtar tabanlı sayfalama daha uygundur. Her iki yöntemde de sayfalamada kullanılan
ORDER BY sütunlarına uygun bir dizin oluşturulması sorgu performansını iyileştirebilir; hangi dizinin uygun olduğu filtre koşullarına, sıralamaya ve kullandığınız veritabanına bağlıdır.Sık karşılaşılan hatalar
ORDER BY kullanmadan sayfalama yapmak, sayfalar arasında kararlı bir sıra beklemenize neden olabilir. Sıralama sütununda eşit değerler bulunmasına rağmen ikinci bir benzersiz ölçüt eklememek de aynı sorunu doğurur.Filtre sorgusunda
WHERE durum = 'yayinda' kullanıp toplam sayıyı filtresiz COUNT(*) ile almak, olduğundan fazla sayfa gösterir. Ayrıca sayfa boyutunu sınırsız bırakmak, istemcinin çok büyük bir sonuç kümesi istemesine yol açabilir. Bu nedenle sayfa boyutuna uygulamanıza uygun bir üst sınır koyun ve istemciden gelen değerleri sorguya güvenli biçimde bağlayın.Sayfa sorgusu ile toplam sayı sorgusu arasında veri değişebileceğini de hesaba katın. Bir işlem sırasında tutarlı bir görünüm kesin olarak gerekiyorsa veritabanınızın işlem yalıtımı ve tutarlı okuma özelliklerini ayrıca değerlendirmeniz gerekir; normal liste ekranlarında ise boş veya eksik bir son sayfa, verilerin değişmesinin doğal sonucu olabilir.