


[分享]基于mysql的分页程序完全解决方案(含普普通通分页/分段分页/原始分页/微博的since_id类分页)
[分享]基于mysql的分页程序完全解决方案(含普通分页/分段分页/原始分页/微博的since_id类分页)
本文博客地址: http://blog.csdn.net/lgg201/article/details/7757494
本文涉及的源代码可在http://download.csdn.net/user/lgg201下载, 也可在对应博文中查看.
SQL解析有很多不足之处, 请各位大牛指正.
0. 下载:
本程序可自由修改, 自由分发, 可在http://download.csdn.net/user/lgg201下载
1. 分页的需求
信息的操纵和检索是当下互联网和企业信息系统承担的主要责任. 信息检索是从大量的数据中找到符合条件的数据以用户界面展现给用户.
符合条件的数据通常会有成千上万条, 而用户的单次信息接受量是很小的, 因此, 如果一次将所有符合用户条件的数据展现给用户, 对于多数场景, 其中大部分数据都是冗余的.
信息检索完成后, 是需要经过传输(从存储介质到应用程序)和相关计算(业务逻辑)的, 因此, 我们需要一种分段的信息检索机制来降低这种冗余.
分页应运而生.
2. 分页的发展
基本的分页程序, 将数据按照每页记录数(page_size)将数据分为ceil(total_record / page_size)页, 第一次为用户展现第一段的数据, 后续的交互过程中, 用户可以选择到某一页对数据进行审阅.
后来, 主要是在微博应用出现后, 由于其信息变化很快, 而其特性为基于时间线增加数据, 这样, 基本的分页程序不能再满足需求了: a) 当获取下一页时, 数据集可能已经发生了很多变化, 翻页随时都可能导致数据重复或跳跃; b) 此类应用采用很多采用一屏展示多段数据的用户界面, 更加加重了数据重复/跳跃对用户体验的影响. 因此, 程序员们开始使用since_id的方式, 将下一次获取数据的点记录下来, 已减轻上述弊端.
在同一个用户界面, 通过用户阅读行为自动获取下一段/上一段数据的确比点击"下一页"按钮的用户体验要好, 但同样有弊端: a) 当用户已经到第100页时, 他要回到刚才感兴趣的第5页的信息时, 并不是很容易, 这其实是一条设计应用的规则, 我们不能让用户界面的单页屏数过多, 这样会降低用户体验; b) 单从数据角度看, 我们多次读取之间的间隔时间足够让数据发生一些变化, 在一次只展示一屏时, 我们很难发现这些问题(因此不影响用户体验), 然而当一页展示100屏数据时, 这种变化会被放大, 此时, 数据重复/跳跃的问题就会再次出现; c) 从程序的角度看, 将大量的数据放置在同一个用户界面, 必然导致用户界面的程序逻辑受到影响. 基于以上考虑, 目前应用已经开始对分页进行修正, 将一页所展示的屏数进行的限制, 同时加入了页码的概念, 另外也结合since_id的方式, 以达到用户体验最优, 同时保证数据逻辑的正确性(降低误差).
3. 分页的讨论
感谢xp/jp/zq/lw四位同事的讨论, 基于多次讨论, 我们分析了分页程序的本质. 主要的结论点如下:
1) 分页的目的是为了分段读取数据
2) 能够进行分页的数据一定是有序的, 哪怕他是依赖数据库存储顺序. (这一点换一种说法更容易理解: 当数据集没有发生变化时, 同样的输入, 多次执行, 得到的输出顺序保持不变)
3) 所有的分段式数据读取, 要完全保证数据集的一致性, 必须保证数据集顺序的一致性, 即快照
4) 传统的分页, 分段式分页(每页内分为多段)归根结底是对数据集做一次切割, 映射到mysql的sql语法上, 就是根据输入求得limit子句, 适用场景为数据集变化频率低
5) since_id类分页, 其本质是假定已有数据无变化, 将数据集的某一个点的id(在数据集中可以绝对定位该数据的相关字段)提供给用户侧, 每次携带该id读取相应位置的数据, 以此模拟快照, 使用场景为数据集历史数据变化频率低, 新增数据频繁
6) 如果存在一个快照系统, 能够为每一个会话发起时的数据集产生一份快照数据, 那么一切问题都迎刃而解
7) 在没有快照系统的时候, 我们可以用since_id的方式限定数据范围, 模拟快照系统, 可以解决大多数问题
8) 要使用since_id方式模拟快照, 其数据集排序规则必须有能够唯一标识其每一个数据的字段(可能是复合的)
4. 实现思路
1) 提供SQL的转换函数
2) 支持分段式分页(page, page_ping, ping, ping_size), 传统分页(page, page_size), 原始分页(offset-count), since_id分页(prev_id, next_id)
3) 分段式分页, 传统分页, 原始分页在底层均转换为原始分页处理
5. 实现定义
ping_to_offset
输入:
page #请求页码, 范围: [1, total_page], 超过范围以边界计, 即0修正为1, total_page + 1修正为total_page
ping #请求段号, 范围: [1, page_ping], 超过范围以边界计, 即0修正为1, page_ping + 1修正为page_ping
page_ping #每页分段数, 范围: [1, 无穷]
count #要获取的记录数, 当前应用场景含义为: 每段记录数, 范围: [1, 无穷]
total_record #总记录数, 范围: [1, 无穷]
输出:
offset #偏移量
count #读取条数
offset_to_ping
输入:
offset #偏移量(必须按照count对齐, 即可以被count整除), 范围: [0, 无穷]
page_ping #每页分段数, 范围: [1, 无穷]
count #读取条数, 范围: [1, 无穷]
输出:
page #请求页码
ping #请求段号
page_ping #每页分段数
count #要获取的记录数, 当前应用场景含义为: 每段记录数
page_to_offset
输入:
page #请求页码, 范围: [1, total_page], 超过范围以边界计, 即0修正为1, total_page + 1修正为total_page
total_record #总记录数, 范围: [1, 无穷]
count #要获取的记录数, 当前应用场景含义为: 每页条数, 范围: [1, 无穷]
输出:
offset #偏移量
count #读取条数
offset_to_page
输入:
offset #偏移量(必须按照count对齐, 即可以被count整除), 范围: [0, 无穷]
count #读取条数, 范围: [1, 无穷]
输出:
page #请求页码
count #要获取的记录数, 当前应用场景含义为: 每页条数
sql_parser #将符合mysql语法规范的SQL语句解析得到各个组件
输入:
sql #要解析的sql语句
输出:
sql_components #SQL解析后的字段
sql_restore #将SQL语句组件集转换为SQL语句
输入:
sql_components #要还原的SQL语句组件集
输出:
sql #还原后的SQL语句
sql_to_count #将符合mysql语法规范的SELECT语句转换为获取计数
输入:
sql_components #要转换为查询计数的SQL语句组件集
alias #计数字段的别名
输出:
sql_components #转换后的查询计数SQL语句组件集
sql_add_offset
输入:
sql_components #要增加偏移的SQL语句组件集, 不允许存在LIMIT组件
offset #偏移量(必须按照count对齐, 即可以被count整除), 范围: [0, 无穷]
count #要获取的记录数, 范围: [1, 无穷]
输出:
sql_components #已增加LIMIT组件的SQL语句组件集
sql_add_since #增加since_id式的范围
输入:

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



HQL dan SQL dibandingkan dalam rangka kerja Hibernate: HQL (1. Sintaks berorientasikan objek, 2. Pertanyaan bebas pangkalan data, 3. Keselamatan jenis), manakala SQL mengendalikan pangkalan data secara langsung (1. Piawaian bebas pangkalan data, 2. Boleh laku kompleks pertanyaan dan manipulasi data).

"Penggunaan Operasi Bahagian dalam OracleSQL" Dalam OracleSQL, operasi bahagi ialah salah satu operasi matematik yang biasa. Semasa pertanyaan dan pemprosesan data, operasi pembahagian boleh membantu kami mengira nisbah antara medan atau memperoleh hubungan logik antara nilai tertentu. Artikel ini akan memperkenalkan penggunaan operasi pembahagian dalam OracleSQL dan memberikan contoh kod khusus. 1. Dua cara operasi bahagi dalam OracleSQL Dalam OracleSQL, operasi bahagi boleh dilakukan dalam dua cara berbeza.

Oracle dan DB2 ialah dua sistem pengurusan pangkalan data hubungan yang biasa digunakan, setiap satunya mempunyai sintaks dan ciri SQL tersendiri. Artikel ini akan membandingkan dan membezakan antara sintaks SQL Oracle dan DB2, dan memberikan contoh kod khusus. Sambungan pangkalan data Dalam Oracle, gunakan pernyataan berikut untuk menyambung ke pangkalan data: CONNECTusername/password@database Dalam DB2, pernyataan untuk menyambung ke pangkalan data adalah seperti berikut: CONNECTTOdataba

Apakah Identity dalam SQL? Contoh kod khusus diperlukan Dalam SQL, Identity ialah jenis data khas yang digunakan untuk menjana nombor penambahan automatik. Ia sering digunakan untuk mengenal pasti setiap baris data dalam jadual. Lajur Identiti sering digunakan bersama dengan lajur kunci utama untuk memastikan setiap rekod mempunyai pengecam unik. Artikel ini akan memperincikan cara menggunakan Identiti dan beberapa contoh kod praktikal. Cara asas untuk menggunakan Identity ialah menggunakan Identit semasa membuat jadual.

Tafsiran teg SQL dinamik MyBatis: Penjelasan terperinci tentang penggunaan teg Set MyBatis ialah rangka kerja lapisan kegigihan yang sangat baik Ia menyediakan banyak teg SQL dinamik dan boleh membina pernyataan operasi pangkalan data secara fleksibel. Antaranya, tag Set ialah tag yang digunakan untuk menjana klausa SET dalam kenyataan UPDATE, yang sangat biasa digunakan dalam operasi kemas kini. Artikel ini akan menerangkan secara terperinci penggunaan teg Set dalam MyBatis dan menunjukkan kefungsiannya melalui contoh kod tertentu. Apakah itu Set tag Set tag digunakan dalam MyBati

Sebab tamat masa permintaan ping termasuk hos sasaran yang tidak dapat dicapai, kesesakan rangkaian, tetapan firewall atau keselamatan dan isu resolusi DNS. Pengenalan terperinci: 1. Hos sasaran tidak dapat dicapai Masa tamat permintaan Ping mungkin bermakna hos sasaran tidak boleh diakses melalui rangkaian Ini mungkin disebabkan oleh hos sasaran menutup sambungan rangkaian, rangkaian tempat hos sasaran berada gagal , alamat IP hos sasaran ditetapkan dengan tidak betul, dsb. 2. Kesesakan rangkaian mungkin juga disebabkan oleh kesesakan rangkaian mungkin disebabkan oleh penghantaran data yang banyak, kegagalan peralatan rangkaian, dsb.

Rangkaian tidak boleh ping, apa yang berlaku? Sebenarnya, ini adalah masalah yang sangat biasa Ia terbahagi kepada dua situasi: ping gagal pada segmen rangkaian yang sama dan ping gagal pada segmen rangkaian yang berbeza. Biasanya terdapat dua sebab mengapa arahan ping tidak boleh disambungkan ke segmen rangkaian yang sama: satu ialah alamat IP yang tidak boleh diping dalam segmen rangkaian yang sama, dan satu lagi ialah alamat IP yang tidak boleh diping dalam segmen rangkaian yang berbeza. Kedua-dua situasi ini mempunyai penyelesaian yang berbeza. Mula-mula, mari kita bincangkan situasi di mana ping gagal dalam segmen rangkaian yang sama. 1. Ping gagal pada segmen rangkaian yang sama, dan hasilnya ialah "Tidak dapat mengakses hos sasaran dan IP sumber berada pada segmen rangkaian yang sama dan hasil ping ialah &l

Penyelesaian: 1. Semak sama ada pengguna log masuk mempunyai kebenaran yang mencukupi untuk mengakses atau mengendalikan pangkalan data, dan pastikan pengguna mempunyai kebenaran yang betul 2. Semak sama ada akaun perkhidmatan SQL Server mempunyai kebenaran untuk mengakses fail yang ditentukan atau folder, dan pastikan akaun Mempunyai kebenaran yang mencukupi untuk membaca dan menulis fail atau folder 3. Semak sama ada fail pangkalan data yang ditentukan telah dibuka atau dikunci oleh proses lain, cuba tutup atau lepaskan fail, dan jalankan semula pertanyaan 4 . Cuba sebagai pentadbir Jalankan Studio Pengurusan seperti dsb.
