当我们对MySQL进行分表操作后,将不能依赖MySQL的自动增量来产生唯一ID了,因为数据已经分散到多个表中。

应尽量避免使用自增IP来做为主键,为数据库分表操作带来极大的不便。

在postgreSQL、oracle、db2数据库中有一个特殊的特性---sequence。 任何时候数据库可以根据当前表中的记录数大小和步长来获取到该表下一条记录数。然而,MySQL是没有这种序列对象的。

可以通过下面的方法来实现sequence特性产生唯一ID:

1. 通过MySQL表生成ID 对于插入也就是insert操作,首先就是获取唯一的id了,就需要一个表来专门创建id,插入一条记录,并获取最后插入的ID。代码如下:

?123CREATE TABLE `ttlsa_com`.`create_id` (`id`BIGINT( 20 )NOT NULL AUTO_INCREMENTPRIMARY KEY) ENGINE = MYISAM

也就是说,当我们需要插入数据的时候,必须由这个表来产生id值,我的php代码的方法如下:

?1234567<?phpfunction get_AI_ID() {$sql ="insert into create_id (id) values('')";$this->db->query($sql);return $this->db->insertID();}?>

这种方法效果很好,但是在高并发情况下,MySQL的AUTO_INCREMENT将导致整个数据库慢。如果存在自增字段,MySQL会维护一个自增 锁,innodb会在内存里保存一个计数器来记录auto_increment值,当插入一个新行数据时,就会用一个表锁来锁住这个计数器,直到插入结 束。如果是一行一行的插入是没有问题的,但是在高并发情况下,那就悲催了,表锁会引起SQL阻塞,极大的影响性能,还可能会达到 max_connections值。

innodb_autoinc_lock_mode:可以设定3个值:0、1、2

0:traditonal (每次都会产生表锁)

1:consecutive (默认,可预判行数时使用新方式,不可时使用表锁,对于simple insert会获得批量的锁,保证连续插入)

2:interleaved (不会锁表,来一个处理一个,并发最高)

对于myisam表引擎是traditional,每次都会进行表锁的。

2. 通过redis生成ID

?function get_next_autoincrement_waitlock($timeout = 60){$count = $timeout > 0 ? $timeout : 60; while($r->get("serial:lock")){$count++;sleep(1);if ($count > 10)return false;} return true;} function get_next_autoincrement($timeout = 60){// first check if we are locked...if (get_next_autoincrement_waitlock($timeout) ==false)return 0; $id = $r->incr("serial"); if ( $id > 1 )return $id; // if ID == 1, we assume we do not have "serial" key... // first we need to get lock.if ($r->setnx("serial:lock"), 1){$r->expire("serial:lock", 60 * 5); // get max(id) from database.$id = select_db_query("select max(id) from user_posts");// or alternatively:// select id from user_posts order by id desc limit 1 // increase it$id++; // update Redis key$r->set("serial", $id); // release the lock$r->del("serial:lock"); return $id;} // can not get lock.return 0;} $r =new Redis();$r->connect("127.0.0.1","6379"); $id = get_next_autoincrement();if ($id){$sql ="insert into user_posts(id,user,message)values($id,'$user','$message')"$data = exec_db_query($sql);}

3. 队列方式 其实这也算是上面的一个解说

使用队列服务,如redis、memcacheq等等,将一定量的ID预分配在一个队列里,每次插入操作,先从队列中获取一个ID,若插入失败的话,将该ID再次添加到队列中,同时监控队列数量,当小于阀值时,自动向队列中添加元素。

这种方式可以有规划的对ID进行分配,还会带来经济效应,比如QQ号码,各种靓号,明码标价。如网站的userid, 允许uid登陆,推出各种靓号,明码标价,对于普通的ID打乱后再随机分配。

?<?php  class common { private $r; function construct() {$this->__construct();} public function __construct(){$this->r=new Redis();$this->r->connect('127.0.0.1', 6379);} function set_queue_id($ids){if(is_array($ids) && isset($ids)){foreach ($ids as $id){$this->r->LPUSH('next_autoincrement',$id);}}} function get_next_autoincrement(){return $this->r->LPOP('next_autoincrement');} } $createid=array();while(count($createid)<20){$num=rand(1000,4000);if(!in_array($num,$createid))$createid[]=$num;} $id=new common();$id->set_queue_id($createid); var_dump($id->get_next_autoincrement());

监控队列数量,并自动补充队列和取到id但并没有使用

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

mysql id问题_MySQL分表自增ID问题的解决方法相关推荐

  1. mysql分表id维护_MySQL分表自增ID解决方案

    当我们对MySQL进行分表操作后,将不能依赖MySQL的自动增量来产生唯一ID了,因为数据已经分散到多个表中. 应尽量避免使用自增IP来做为主键,为数据库分表操作带来极大的不便. 在postgreSQ ...

  2. mysql 分表 id_MySQL分表自增ID解决方案

    当我们对MySQL进行分表操作后,将不能依赖MySQL的自动增量来产生唯一ID了,因为数据已经分散到多个表中. 应尽量避免使用自增ID来做为主键,为数据库分表操作带来极大的不便. 在postgreSQ ...

  3. think php自增,thinkphp5分表自增ID解决方案

    生成自增ID的方式有很多种,这里采用的是mysql单独建一张表来获取自增ID 创建表的sql语句CREATE TABLE `wx_article_auto_increment` ( `id` bigi ...

  4. MySQL占用系统进程_MySQL的Sleep进程占用大量连接解决方法

    第一部分为产生大量sleep进程的原理及对应解决方法 第二部分为设置wait_timeout值,有效减少sleep进程 ======================================== ...

  5. mysql 1118错误_Mysql 出现Error 1118的一种解决方法 | 学步园

    首先声明,对mysql不懂,很多都不知道原因 设计了一个表,里面很多text字段,然后填进去的东西太多(用的是python的MySQLdb),报错: _mysql_exceptions.Operati ...

  6. 没有修改出现mysql密码错误_MySql 修改密码后的错误快速解决方法

    设置好密码后,使用数据库时出现如下错误: ERROR 1820 (HY000): You must reset your password using ALTER USER statement bef ...

  7. mysql自动增长id 溢出_MySQL表自增id溢出的故障复盘怎么解决 MySQL表自增id溢出的故障复盘解决方法...

    MySQL表自增id溢出的故障复盘如何解决?本篇文章小编给大家分享一下MySQL表自增id溢出的故障复盘解决方法,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 问题:MyS ...

  8. mysql c接口返回自增id_详解mysql插入数据后返回自增ID的七种方法

    引言 mysql 和 oracle 插入的时候有一个很大的区别是: oracle 支持序列做 id: mysql 本身有一个列可以做自增长字段. mysql 在插入一条数据后,如何能获得到这个自增 i ...

  9. mysql 新增返回主键自增id_详解mysql插入数据后返回自增ID的七种方法

    引言 mysql 和 oracle 插入的时候有一个很大的区别是: oracle 支持序列做 id: mysql 本身有一个列可以做自增长字段. mysql 在插入一条数据后,如何能获得到这个自增 i ...

最新文章

  1. 什么是 JVM方法区
  2. Oracle9在Windows7下的安装
  3. 【论文解读】通过知识蒸馏促进轻量级深度估计
  4. TCP往返时延的估计和超时
  5. 淘宝网商品管理?技术 ?
  6. php get教程,PHP $_GET 变量
  7. API3价格流将与Omen预测市场进行集成
  8. C# pictureBox桌面大小自适应 大小自适应 窗体居中
  9. ITextSharp 使用
  10. 连接局域网打印机显示无法连接服务器,网络打印机拒绝访问无法连接处理方法汇总...
  11. 【算法笔记题解】《算法笔记知识点记录》第二章——快速入门4[结构体、输入输出、复杂度和黑盒测试]
  12. 计算机重装后如何连接无线网络,电脑重装系统后怎么连接无线网络连接
  13. 魔方还原算法(一) 概述
  14. python外文文献翻译_英文学术文献翻译软件有哪些推荐?
  15. 骨灰级的魔兽伤害计算(包括物理和…
  16. 人才外包公司成本大揭露——一个外包人员的分析
  17. 鸿蒙系统运行内存为啥只有8g,明明8G内存,系统却显示只有4G!为啥会这样?
  18. 二十四节气-小寒。文案、海报分享,小寒料峭 年味渐浓。
  19. [IAR] 编译报错:Variable expansion failed for Pre-Build command line
  20. 笔记本电脑计算机无法启动怎么办,联想笔记本开不了机怎么办 电脑开机进不了系统怎么办...

热门文章

  1. Linux下数据库的安装配置、数据库C程序连接
  2. java工程师待遇杭州招聘_【华为杭州研究所工资】java开发工程师待遇-看准网
  3. 实体list 查找一个符合条件的实体并返回其中一个字段_小米知识图谱团队斩获CCKS 2020实体链指比赛冠军...
  4. 基于阿克曼转向的车辆运动学模型 在simulink中建立车辆运动学模型
  5. 不穷:阿里企业大脑最佳实践
  6. 无线网技术期末考试复习
  7. 用H5和CSS如何实现鼠标触碰一个盒子后显示下面隐藏的盒子
  8. 中国车载激光雷达市场洞察报告-220425
  9. 2017找工作总结——不打无准备的仗
  10. 航空科普VR大型体验馆设备VR航天主题乐园星际飞碟vr游乐设备