相关知识库:

MySQL知识库
                                        <div id="related_topics" style="position: relative;">相关文章: <span class="close"><a href="#" onclick="$('related_topics').hide();if($('hunter_recommended')){$('hunter_recommended').style.width='780px'};if($('topic_tags')){$('topic_tags').style.width='790px'};return false;" title="关闭">&nbsp;</a></span>
<ul>
<li><a href="http://www.iteye.com/topic/186233" title="ibatis中主键的返回" target="_blank">ibatis中主键的返回</a></li>
<li><a href="http://www.iteye.com/topic/1126814" title="oracle 实现自增auto_increament" target="_blank">oracle 实现自增auto_increament</a></li>
<li><a href="http://www.iteye.com/topic/267" title="用oracle的trigger生成主键的时候和hibernate冲突的讨论" target="_blank">用oracle的trigger生成主键的时候和hibernate冲突的讨论</a></li>
</ul>
<br><span>推荐群组: <a href="http://grails.group.iteye.com" target="_blank">Groovy on Grails </a></span>
<br><a href="/wiki/topic/1114280" target="_blank">更多相关推荐</a>
</div>
<script type="text/javascript">
document.observe("dom:loaded", function() {
if($('hunter_recommended')) {
$('hunter_recommended').setStyle({cssFloat: 'left', width: '557px'})
}
if($('topic_tags')) {
$('topic_tags').setStyle({width: '567px'})
}
new Draggable("related_topics");
});
</script> <div id="topic_tags" class="news_tag" style="width: 567px;">
<a href="/forums/tag/MySQL">MySQL</a>
<a href="/forums/tag/%E6%95%B0%E6%8D%AE%E5%BA%93">数据库</a>
</div> 提到mysql,我顺便讲讲序列。用过oracle的人都知道,orale没有类似mysql的AUTO_INCREMENT这样的自增长字段,实现插入一条记录,自动增加1.oracle是通过sequence(序列)来完成的。这样看起来,似乎mysql的自增长要比oracle序列的实现更好更方便。那我为什么还要提序列呢?有必要吗?

(1)首先mysql的自增长“序列”和序列是两回事,mysql本身不提供序列机制。




(2)mysql的AUTO_INCREMENT可以设置起始值,但是不能设置步长,其步长默认就是1.




(3)mysql一个表只能有一个自增长字段。自增长只能被分配给固定表的固定的某一字段,不能被多个表共用。并且只能是数字型。




(4)在历史表和数据迁移时,经常会遇到自增主键重复的问题。




(5)自增主键往往是没意义的。


在下列情况下可能你需要使用序列:


(1)业务复杂,你需要高度定制和控制主键(自增主键只能是按数字递增的,但是序列可以随心所欲的变化,比如按照年月日生成主键。。。)


(2)你希望手工维护自增长,方便数据迁移;


(3)当事务跨多表时,期望事务可靠性;




(4)当你需要一个业务上有意义的主键时,比如单据号等(若你需要的只是一个流水号,那么用自增更方便);




(5)当你的主键很明确地需要和其他表关联时(若你的表不与其他表关联时,如日志表,自增更方便)




(6)你期望这个主键是唯一的,不需要重复利用的。


    当然,序列也有缺点,主要就是程序处理麻烦,不如自增方便。oracle的自增有缓存,不用担心效率问题,而mysql只能通过触发器模拟,可能会有性能损失。




下面,我们就来实现一下mysql中的序列。




先建一个序列表,如下:




  1. DROP TABLE IF EXISTS sequence;  
  2.   
  3. CREATE TABLE IF NOT EXISTS sequence (  
  4.   
  5.   name varchar(50) NOT NULL,  
  6.   
  7.   current_value int(11) NOT NULL,  
  8.   
  9.   increment int(11) NOT NULL DEFAULT '1'  
  10.   
  11. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='序列表,命名s_[table_name]';  
  12.   
  13. INSERT INTO sequence (namecurrent_valueincrement) VALUES  
  14.   
  15. ('s_blog_account', 0, 1)  
DROP TABLE IF EXISTS sequence;

CREATE TABLE IF NOT EXISTS sequence (

name varchar(50) NOT NULL,

current_value int(11) NOT NULL,

increment int(11) NOT NULL DEFAULT '1'

) ENGINE=MyISAM DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='序列表,命名s_[table_name]';

INSERT INTO sequence (name, current_value, increment) VALUES

('s_blog_account', 0, 1)

name是序列的名字,current_value是序列当前值,increment是每次增长的步长。


再来写几个函数(取当前值):




  1. DROP FUNCTION IF EXISTS currval;  
  2.   
  3. DELIMITER //  
  4.   
  5. CREATE DEFINER=TEST@% FUNCTION currval(seq_name VARCHAR(50)) RETURNS int(11)  
  6.   
  7.     READS SQL DATA  
  8.   
  9.     DETERMINISTIC  
  10.   
  11. BEGIN  
  12.   
  13. DECLARE VALUE INTEGER;  
  14.   
  15. SET VALUE = 0;  
  16.   
  17. SELECT current_value INTO VALUE FROM sequence WHERE NAME = seq_name;  
  18.   
  19. RETURN VALUE;  
  20.   
  21. END//  
  22.   
  23. DELIMITER ;  
DROP FUNCTION IF EXISTS currval;

DELIMITER //

CREATE DEFINER=TEST@% FUNCTION currval(seq_name VARCHAR(50)) RETURNS int(11)
READS SQL DATA

DETERMINISTIC

BEGIN

DECLARE VALUE INTEGER;

SET VALUE = 0;

SELECT current_value INTO VALUE FROM sequence WHERE NAME = seq_name;

RETURN VALUE;

END//

DELIMITER ;

取下一个值:




  1. DROP FUNCTION IF EXISTS nextval;  
  2.   
  3. DELIMITER //  
  4.   
  5. CREATE DEFINER=TEST@% FUNCTION nextval(seq_name VARCHAR(50)) RETURNS int(11)  
  6.   
  7.     DETERMINISTIC  
  8.   
  9. BEGIN  
  10.   
  11. UPDATE sequence SET current_value = current_value + increment WHERE NAME = seq_name;  
  12.   
  13. RETURN currval(seq_name);  
  14.   
  15. END//  
  16.   
  17. DELIMITER ;  
DROP FUNCTION IF EXISTS nextval;

DELIMITER //

CREATE DEFINER=TEST@% FUNCTION nextval(seq_name VARCHAR(50)) RETURNS int(11)
DETERMINISTIC

BEGIN

UPDATE sequence SET current_value = current_value + increment WHERE NAME = seq_name;

RETURN currval(seq_name);

END//

DELIMITER ;

    当我们需要插入时,只用加一句select nextval("s_blog_account"),然后用这个返回值作为主键,插入到对应的表中。我提到了"插入时",那么是不是我们还可以用触发器来实现呢?这个就归你有兴趣时看看了。我估计绝大部分程序员都只在使用自增主键,如果你对这个问题思考的再深一点,那么你会发现,序列很不错。目前,在我的开发中,我只在LOG表和无意义的字段中使用自增,凡是有意义的主键,我都是用的序列维护。神马?你说虚拟主机不支持mysql的这些高级特性?对不起,我从不考虑虚拟主机,也请你不要把目光局限在针对虚拟主机的开发。

mysql里的序列应用详解的更多相关文章

  1. MySQL Cluster 配置文件(config.ini)详解

    MySQL Cluster 配置文件(config.ini)详解 ################################################################### ...

  2. mysql中event的用法详解

    一.基本概念mysql5.1版本开始引进event概念.event既“时间触发器”,与triggers的事件触发不同,event类似与linux crontab计划任务,用于时间触发.通过单独或调用存 ...

  3. MYSQL常用内置函数详解说明

    函数中可以将字段名当作变量来用,变量的值就是该列对应的所有值:在整理98在线字典数据时(http://zidian.98zw.com/),有这要一个需求,想从多音字duoyinzi字段值提取第一个拼音 ...

  4. Mysql数据库导入命令Source详解

    Mysql数据库导入命令Source详解 几个常用用例: 1.导出整个数据库 mysqldump -u 用户名 -p 数据库名 > 导出的文件名 mysqldump -u root -p dat ...

  5. Android Service生命周期 Service里面的onStartCommand()方法详解

    在Demo上,Start一个Service之后,执行顺序:onCreate - > onStartCommand 然后关闭应用,会重新执行上面两步. 但是把代码拷贝到游戏工程发现,关闭游戏后,只 ...

  6. mysql中SQL执行过程详解与用于预处理语句的SQL语法

    mysql中SQL执行过程详解 客户端发送一条查询给服务器: 服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果.否则进入下一阶段. 服务器段进行SQL解析.预处理,在优化器生成对应的 ...

  7. Python学习一:序列基础详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7858473.html 邮箱:moyi@moyib ...

  8. Mysql中limit的用法详解

    Mysql中limit的用法详解 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,为我们提供了limit这样一个功能. SELECT * FROM table LIMIT [offset ...

  9. vuex里mapState,mapGetters使用详解

    这次给大家带来vuex里mapState,mapGetters使用详解,vuex里mapState,mapGetters使用的注意事项有哪些,下面就是实战案例,一起来看一下. 一.介绍 vuex里面的 ...

随机推荐

  1. IDEA 下的 github 创建提交与修改

    本章假定你已经安装了 git 客户端,本文仅仅使用与 Mac 环境下,未在 Window下实验,但 IDEA 在 Window 和 Mac 下软件的使用方法是一致的. 1 配置账号 IDEA 需要配置 ...

  2. spring boot加载配置文件的顺序

    四个默认加载配置文件地方的优先级,四个文件相同配置有优先级概念  不同位置相互补充 外部配置文件不建议使用,不符合maven项目结构,打包会打不进去

  3. MAC系统 - 基础知识

    一.基础操作 设置:触控板设置 - >学习具体手势 手势:MacBook Pro手势大全必学手势触控板手势有哪些 左键,右键,滑屏,切换到应用... 一指操作: 一指敲击:鼠标左键: 一指按下: ...

  4. 转入软工后第一节java课的作业

    这个作业,鸽了好久.本来大家都在中秋前发了,我摸摸索索加上各种缓慢的学习,终于是将他做完了. 做完之后,java最基本的输入输出功能都基本学习到了.下面附上代码: import java.util.* ...

  5. 杭电 1059 Dividing

    Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  6. VS中编码格式的问题(待总结)

    今天又遇到这样的事情了,VS中代码明明是正确的,却报某个变量未定义.百思不得解,前面增加了一个换行之后,竟然又神奇般的复原了. 最后确认是编码格式的问题,后来把有问题的那部分代码粘贴到微软的" ...

  7. HDU 1372 Knight Moves(bfs)

    嗯... 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1372 这是一道很典型的bfs,跟马走日字一个道理,然后用dir数组确定骑士可以走的几个方向, ...

  8. leetCode练题——9. Palindrome Number

    1.题目 9. Palindrome Number   Determine whether an integer is a palindrome. An integer is a palindrome ...

  9. 某元素 fixed 后,从页面消失

    position: fixed; top: 0; left: 0; width: 100%; z-index: 1; 一开始是定位后,元素就从页面消失了,添加了 层级 之后就可以了.

  10. 面试问题之——给你图片的url,你能知道它所占的字节空间吗?

    从一个需求说起 这标题起得有点标题党,实际情况是我最近在做一个公司内部工具时,遇到了这么一个需求,给定一个静态资源站点上某张图片的url(比如https://a.xxxcdn.com/demo.jpg ...