浏览 3133 次
锁定老帖子 主题:mysql里的序列应用详解
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-09-02
(1)首先mysql的自增长“序列”和序列是两回事,mysql本身不提供序列机制。 (2)mysql的AUTO_INCREMENT可以设置起始值,但是不能设置步长,其步长默认就是1. (3)mysql一个表只能有一个自增长字段。自增长只能被分配给固定表的固定的某一字段,不能被多个表共用。并且只能是数字型。 (4)在历史表和数据迁移时,经常会遇到自增主键重复的问题。 (5)自增主键往往是没意义的。 在下列情况下可能你需要使用序列: (1)业务复杂,你需要高度定制和控制主键(自增主键只能是按数字递增的,但是序列可以随心所欲的变化,比如按照年月日生成主键。。。) (2)你希望手工维护自增长,方便数据迁移; (3)当事务跨多表时,期望事务可靠性; (4)当你需要一个业务上有意义的主键时,比如单据号等(若你需要的只是一个流水号,那么用自增更方便); (5)当你的主键很明确地需要和其他表关联时(若你的表不与其他表关联时,如日志表,自增更方便) (6)你期望这个主键是唯一的,不需要重复利用的。 当然,序列也有缺点,主要就是程序处理麻烦,不如自增方便。oracle的自增有缓存,不用担心效率问题,而mysql只能通过触发器模拟,可能会有性能损失。 下面,我们就来实现一下mysql中的序列。 先建一个序列表,如下: 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是每次增长的步长。 再来写几个函数(取当前值): 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 ; 取下一个值: 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的这些高级特性?对不起,我从不考虑虚拟主机,也请你不要把目光局限在针对虚拟主机的开发。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-10-25
当我们需要插入时,只用加一句select nextval("s_blog_account"),然后用这个返回值作为主键,插入到对应的表中?举个例子
|
|
返回顶楼 | |