我的日常开发记录日志
首页
  • Laravel
  • Thinkphp
  • Swoole
  • Workman
  • php
  • HTML
  • CSS
  • JavaScript
  • Vue
  • ES6
  • 小程序
  • Mysql
  • Redis
  • Es
  • MongoDb
  • Git
  • Composer
  • Linux
  • Nginx
  • Docker
  • Vpn
  • 开发实战
  • 开发工具类
  • 友情链接
💖关于
💻收藏
  • 分类
  • 标签
  • 归档数据
GitHub (opens new window)

我的日常开发记录日志

never give up
首页
  • Laravel
  • Thinkphp
  • Swoole
  • Workman
  • php
  • HTML
  • CSS
  • JavaScript
  • Vue
  • ES6
  • 小程序
  • Mysql
  • Redis
  • Es
  • MongoDb
  • Git
  • Composer
  • Linux
  • Nginx
  • Docker
  • Vpn
  • 开发实战
  • 开发工具类
  • 友情链接
💖关于
💻收藏
  • 分类
  • 标签
  • 归档数据
GitHub (opens new window)
  • mysql

    • Mysql
    • 哈希分表
      • 严格模式
      • 单表数据过大的解决方案
      • 分表分库带来的新问题
      • 数据容量查询
      • 海量数据生成和删除
      • mysql编辑的sql
      • showprocess用法
    • redis

    • mongodb

    • es

    • 数据库
    • mysql
    窝窝侠
    2024-06-17

    哈希分表

    在进行分表操作后,如果需要进行筛选、分页查询和排序,复杂度会进一步增加。以下是一个详细的示例,展示了如何在分表的情况下进行筛选、分页查询和排序。

    # 分表示例

    假设我们有一个用户表users,我们将其按用户ID的哈希取模分成多个表,例如users_0,users_1,users_2等。

    # 分表策略

    我们可以使用以下方法将用户ID分配到不同的表中:

    $table_index = hash('crc32', $user_id) % $num_tables;
    
    1

    其中,$num_tables是分表的数量。

    # 数据筛选、分页查询和排序

    为了实现筛选、分页和排序查询,我们需要在应用层进行一些处理。以下是一个PHP代码示例,展示了如何使用哈希取模进行分表后的筛选、分页和排序查询。

    # 数据库结构

    假设我们有两个表:

    1. users 表(分表后的结构为users_0, users_1, ..., users_9)
    2. orders 表(订单表)
    CREATE TABLE users_0 (
        id INT PRIMARY KEY,
        name VARCHAR(100),
        age INT
    );
    
    CREATE TABLE orders (
        id INT PRIMARY KEY,
        user_id INT,
        product VARCHAR(100),
        FOREIGN KEY (user_id) REFERENCES users_0(id)
    );
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    # PHP代码示例

    <?php
    $host = 'localhost';
    $user = 'root';
    $password = 'password';
    $dbname = 'test';
    $num_tables = 10; // 分表数量
    
    // 创建数据库连接
    $mysqli = new mysqli($host, $user, $password, $dbname);
    
    if ($mysqli->connect_error) {
        die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
    }
    
    // 获取分页和筛选参数
    $page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
    $limit = 10;
    $offset = ($page - 1) * $limit;
    $age_filter = isset($_GET['age']) ? (int)$_GET['age'] : null;
    $sort_by = isset($_GET['sort_by']) ? $_GET['sort_by'] : 'id';
    $sort_order = isset($_GET['sort_order']) ? $_GET['sort_order'] : 'ASC';
    
    // 分表查询
    $users = [];
    
    for ($i = 0; $i < $num_tables; $i++) {
        $table = "users_$i";
        $query = "SELECT * FROM $table";
    
        // 添加筛选条件
        if ($age_filter !== null) {
            $query .= " WHERE age = $age_filter";
        }
    
        // 添加排序条件
        $query .= " ORDER BY $sort_by $sort_order";
    
        // 添加分页条件
        $query .= " LIMIT $offset, $limit";
    
        $result = $mysqli->query($query);
    
        if ($result) {
            while ($row = $result->fetch_assoc()) {
                $users[] = $row;
            }
        }
    }
    
    // 获取用户ID列表
    $user_ids = array_column($users, 'id');
    $user_ids_str = implode(',', $user_ids);
    
    // JOIN查询
    if (!empty($user_ids)) {
        $query = "SELECT o.*, u.name FROM orders o JOIN (";
        for ($i = 0; $i < $num_tables; $i++) {
            $table = "users_$i";
            $query .= "SELECT * FROM $table UNION ALL ";
        }
        $query = rtrim($query, ' UNION ALL ');
        $query .= ") u ON o.user_id = u.id WHERE o.user_id IN ($user_ids_str)";
    
        $result = $mysqli->query($query);
    
        if ($result) {
            while ($row = $result->fetch_assoc()) {
                print_r($row);
            }
        }
    } else {
        echo "No users found.";
    }
    
    $mysqli->close();
    ?>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76

    # 说明

    1. 筛选条件:我们在查询中添加了一个可选的筛选条件age。
    2. 排序条件:我们在查询中添加了排序条件ORDER BY,可以根据sort_by和sort_order参数进行排序。
    3. 分页条件:我们在查询中添加了分页条件LIMIT和OFFSET。
    4. JOIN查询:我们首先获取所有用户ID,然后使用这些ID进行JOIN查询。为了简化,我们将所有分表的查询结果通过UNION ALL合并在一起。

    # 注意事项

    • 性能:这种方法适用于数据量较小的场景。如果数据量非常大,可能需要更复杂的分片和查询策略。
    • 数据均衡:哈希取模的方法可以较好地均衡数据,但在某些情况下可能仍会出现数据倾斜。
    • 扩展性:增加或减少分表数量时,需要重新分配数据,这可能会比较复杂。

    通过这个示例,你可以了解如何在PHP中使用哈希取模的方法实现分表后的筛选、分页和排序查询。根据实际需求,你可能需要进一步优化和调整代码。

    在线编辑 (opens new window)
    上次更新: 2025/02/25, 18:30:54
    Mysql
    严格模式

    ← Mysql 严格模式→

    最近更新
    01
    showprocess用法
    04-29
    02
    vue3中尖括号和冒号的使用细则
    04-29
    03
    sd使用
    02-22
    更多文章>
    🖥️

    © 2025窝窝侠 💌 豫ICP备20005263号-2 🛀 Theme by 💝 Vdoing && 小胖墩er

    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式
    ×