ci+数据库多表分页/删除/插入

未做并发测试,但考虑了一下.可能有bug;

思路:n个数据表,一个数据关系表,关系表中得到数据表间关系;

 

显示

1表示表1,2表示表2

数据表名使用xx_下标

关系表只二列,id(即下标), 本表行数(可以考虑每次使用都查询而不是自己维护)

 

ci+数据库多表分页/删除/插入 - qidizi - qidizi 的博客

----

获取数据

 

/**
     * 整站地址库
     */
    public function index()
    {    
        
        if (! $this->logined ){//未登录
            return;
        }
        
        $this->load->library('pagination');
        $tables = $this->db->query('SELECT * FROM email_tables ORDER BY id ASC');
        
        if ($tables->num_rows()){           
            $tables = $tables->result_array();            
            $offset = (int)$this->uri->segment(4, 0);       
            $config['per_page'] = $pagePer = 5;
                        
            $count = 0;
            $noEnd = 1;
            $lists = array();
            
            foreach ($tables as $table){
                $rows = (int)$table['rows'];
                
                if ($noEnd && (
                              ( ($pagePer > 0) && ($offset < 1) ) //补足limit
                              || ($offset < $rows) //首次
                              )
                    ){//补足limit
                          $row = $this->db->select('*')
                                   ->from('email_'.$table['id'])
                                   ->where('id > ', 0)
                                   ->order_by('id ASC')
                                   ->limit($pagePer, $offset)
                                   ->get();
                          $getRows = $row->num_rows();       
                          $lists[$table['id']] = $row->result_array();
                          
                          if ($getRows < $pagePer){
                              $pagePer = $pagePer - $getRows;
                          }else{
                              $noEnd = 0;
                          }
                }else if ($offset > 0){
                    $offset -= $rows;
                }
                
                $count += $rows;
            }
            
            $config['total_rows'] = $count;
            $config['base_url'] = site_url("home/email/index/");
            $this->pagination->initialize($config);
            $data['pageCode'] = $this->pagination->create_links();
            $data['lists'] = $lists;
        }else{
            $data['lists'] = null;
        }
        
        $this->load->view('home/email', $data);
    }

显示模板

<table class="listTable" >
    <tr>
      <th>Id</th>
      <th>收件人地址</th>
      <th>检测次数</th>
      <th>入库时间</th>
    </tr>
    
    <?php
    
    foreach( $lists  as $key => $tbl){
        foreach ($tbl as $list){
            echo "
            <tr>
              <td>{$key}:{$list['id']}</td>
              <td>{$list['email']}</td>
              <td>{$list['unexist']}</td>
              <td>" .date('Y-m-d H:i:s', $list['time']). "</td>
            </tr>
            ";
        }
    }
    ?>
    
      <?php echo empty($pageCode)?"":'<tr><td colspan=4>'.$pageCode. '</td></tr>';?>

--------

删除

思路是,前台把各个表的列表(<input value="表下标.id" />)处理成:表下标.id_id,表下标.id_id格式后,php中再处理.

 

放在查询前就可以了


        $del = $this->uri->segment(5, '');
        
        if (FALSE !== strpos($del, 'del')){//删除
            $del = str_replace('del', '', $del);
            $del = explode(',', $del);//分解成表组
            
            if ( empty($del)){
                $data['tip'] = '错误id';
            }else{
                            
                foreach ($del as $delTbl){
                    $delTbl = explode('.', $delTbl);//分离表,id
                    $delTbl[1] = explode('_', $delTbl[1]);//分离id
                    if (empty($delTbl[1])) continue;
                    $this->db->where_in('id', $delTbl[1]);
                    $this->db->delete('email_'.(int)$delTbl[0]);
                    $this->db->query('UPDATE email_tables SET rows = (SELECT COUNT(id) FROM email_' .(int)$delTbl[0]. ') WHERE id = ' .(int)$delTbl[0]);//更新记录条数,还是让数据库处理好点会比自己先查询再删除好.
                    $data['tip'] = "删除完成:{$delTbl[0]}:" .implode(',', $delTbl[1]) ."<br />";
                }
            }
        }

---

插入

 

$tbls = $this->db->query('SELECT * FROM email_tables ORDER BY id ASC ' )->result_array();//取得所有表 ,主要 用于查询分表的 总 记录数,是否还可以插入
          
          foreach ($tbls as $tbl){
              $eid =  $this->db->query('SELECT id FROM email_' .$tbl['id']. ' WHERE email=? limit 1', array($email) );//检测是否 存在时很 麻烦。需要  对 所有分表进行查询

              if ($eid->num_rows()){//全站库存在      
                  $eid = $eid->row()->id;
                  $existCount++;
                  break;
              }else{
                  $eid = 0;
                  if ( empty($tblId) && ( (int)$tbl['rows'] < $maxRows) ) $tblId = $tbl['id'];//取得可插入记录表                      
              }
          }
          
          if (empty($eid)){//插入全站库   
              if (empty($tblId)){//所有表已满,建立新表
                  $this->db->insert('email_tables', array('rows'=>0));
                  $tblId = $this->db->insert_id();
                  $this->db->query('DROP TABLE IF EXISTS email_' .$tblId);
                  $this->db->query("CREATE TABLE `email_{$tblId}` (
                                  `id` int(11) NOT NULL AUTO_INCREMENT,
                                  `email` varchar(256) NOT NULL,
                                  `unexist` int(2) NOT NULL DEFAULT '0',
                                  `time` int(11) NOT NULL DEFAULT '0',
                                  PRIMARY KEY (`id`)
                                ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;");//新表
              }
              
              $this->db->insert('email_' .$tblId, array('email'=>$email, 'time'=>time()) );
              $this->db->query('UPDATE email_tables SET rows = rows + 1 WHERE id = ' .$tblId);
              $eid = $this->db->insert_id();
              $insertCount++;
              $tblId  = 0;//reset
          }

 

-----------------

初设计,未 优化,有 bug,应该还可以进行 优化 ,像信箱地址索引,对于检测存在会节约时间;

还有,在 分页查询时,进行分表编号指定,相当于 limit于 某个分表,而不是分表 整体,虽然这样实现分页会导致前面数据 删除 后,分页从前算起和后算起 会不一至情况,但是要求不高时可以这 样,更加轻便点 ;

 

分表将导致表关系表非常的复杂,如有一 分组 表,使用到这个分表里面的数据做引用时,删除 /分页都会 非常的 麻烦.性能可能也会 下降 ,也就是说,如果需要执行整体处理的 时候,如整体的count,分表会带来麻烦,而 速度并不一定能 提高多少 ;

 

这只 是不打算 升级硬件而做的分表 处理 ,

并不是分表+分 区+集群的并发处理.

前者只是 尽量防止因为硬件性能过 差 载入过多 的 数据的处理而已.而它不是 并发处理;这只是相当数据库设计优化;

不是为了 引入更多的硬件提高服务性能;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值