弃用数据库自增ID,曝光一下我自己用到的解决方法 (转发)

在平时的项目开发中,我相信有很大一批人都在用这个数据库自增ID,用数据库自增ID有利也有弊。

    优点:节省时间,根本不用考虑怎么来标识唯一记录,写程序也简单了,数据库帮我们维护着这一批ID号。

    缺点:for example, 在做分布式数据库时,要求数据同步时,这种自增ID就会出现严重的问题,因为你无法用该ID来唯一标识记录。同时在数据库做移植时,也会出现各种问题,总之,对此自增ID有依赖的情况,都有可能出现问题。我绝对相信园子里有很一部分人都被这个“好用的东西” 曾经害惨过!

  

  我平时在开发项目的时候,一般都没有用到数据库的自增ID, 所以我想分享一下自己的解决方法。

  解决思路:

    

1:定义一张表,专门用来存放存所有需要唯一ID的表名称以及该表当前所使用到的ID值。
2: 写一个存储过程,专门用来在上一步的表中取ID值。

  这个思路非常简单,我不作解释了,直接来看看我的实现方法:

 

 

代码

第一步:创建表
create table table_key
(
       table_name   varchar(50) not null primary key,
       key_value    int         not null
)

第二步:创建存储过程来取自增ID
create procedure up_get_table_key
(
   @table_name     varchar(50),
   @key_value      int output
)
as
begin
     begin tran
         declare @key  int
         
         --initialize the key with 1
         set @key=1
         --whether the specified table is exist
         if not exists(select table_name from table_key where table_name=@table_name)
            begin
              insert into table_key values(@table_name,@key)        --default key vlaue:1
            end
         -- step increase
         else    
            begin
                select @key=key_value from table_key with (nolock) where table_name=@table_name
                set @key=@key+1
                --update the key value by table name
                update table_key set key_value=@key where table_name=@table_name
            end
        --set ouput value
    set @key_value=@key

    --commit tran
    commit tran
        if @@error>0
      rollback tran
end

 

 

对于在表中不存在记录,直接返回一个默认值为1的键值,同时插入该条记录到table_key表中。而对于已存在的记录,key值直接在原来的key基础上加1.

    

 

    总结一下,这种方法非常简单,我说一下它的优缺点。

    优点:

       1:ID值是可控的。用户可以从指定段开始分配ID值,这对于在分布式数据要求同数据同步时,非常方便,很好地解决了ID重复的问题。

       2:在编写程序中,ID值是可见的,比如在再插入关联的记录时,相比使用数据库自增ID的情况下,这种方法不需要在插入一条数据库记录之后,再去得到自增ID值,然再再使用该ID的值来插入关联的记录。我们可以一次性使用事务来插入关联记录。

      3:对于需要批量插入数据时,我们可以改写一下上面的存储过程,返回一个段的开始ID,然后更新表时需要注意,不是原来的简单的递增1,而是递增你想要的插入多少条记录的总数。

    缺点:

      1:效率问题,每次取ID值都需要调用存储过程从数据库中检索一次。对于这种情况,我觉得效率不是很大问题,因为SQL server 会对我们经常调用的存储过程有缓存,再一点,这个表的数据应该不会很大,最多上千条(一个项目中上千个表的情况应该不是很多吧)。所以检索不是什么问题,何况是根据表名来检索(表名列已是主键)。

    2:并发问题。

    很多人有提到!不过凡事都是一把双刃剑,这就好比做优化,要么以时间换空间,要么以空间换时间,这个世界上根本不存十全十美的事物!

      个人拙见!仅此而已!

    

 

转发自:http://www.cnblogs.com/repository/archive/2011/01/17/1937265.html

时间: 2024-08-07 17:42:08

弃用数据库自增ID,曝光一下我自己用到的解决方法 (转发)的相关文章

spring mvc-Springmvc框架下的,关于数据库自增ID获取的问题

问题描述 Springmvc框架下的,关于数据库自增ID获取的问题 向数据库中插入新的数据.并且ID是设置为自增的,我该如何做到插入的同时还能够获取到这个数据的id呢 解决方案 http://blog.csdn.net/yaerfeng/article/details/7231093 解决方案二: 有一个selectkey的属性,加上就好了 解决方案三: 首先,先在数据库中设置其ID为自增 然后,往数据库中插入数据 再然后,根据所插入的一些信息查找出刚刚插入数据的ID 解决方案四: spring

android 数据库 自增 id的问题

问题描述 android 数据库 自增 id的问题 Android sqlite数据库,一个表有一个自增id(主键),插入数据的时候没有手动指定(我觉得id应该会自动赋值),查询的时候id都是0,这是为什么,我用sqlite studio打开db文件,发现id是有值的,而且是从1开始自动增长的. 解决方案 关于数据库自增ID数据写入问题的解决Android sqlite数据删除解决自增id问题android 中应用SQLite 常用自增ID,ID归零方法 解决方案二: 不一定id 都是自增长的,

mysql数据库自增id重新从1排序的两种方法

使用mysql时,通常表中会有一个自增的id字段,但当我们想将表中的数据清空重新添加数据时,希望id重新从1开始计数,用以下两种方法均可: 通常的设置自增字段的方法: 创建表格时添加: create table table1(id int auto_increment primary key,...) 创建表格后添加: alter table table1 add id int auto_increment primary key 自增字段,一定要设置为primary key. 例子 alter

Access数据库中“所有记录中均未找到搜索关键字”的解决方法

先使用 Ms Access 压缩修复,然后再去相关的表把备注类型的字段里的"索引"去掉 备注型字段为什么不能超过1950字节?是由于备注型字段是有"索引".用Access对数据库的表进行设计时,点试设计视图->索引, 可以看到这个字段有索引.就是这个原因,删掉这个索引就什么事都没有了. 奇怪的是:在ACCESS设计表时,在备注型的字段里,根本就没有选项对备注型字段加上索引功能. 本文来源于 KinJAVA日志 (http://jorkin.reallydo.c

MSSQL数据库占用内存过大造成服务器死机问题的解决方法

使用MSSQL的站长朋友都会被MSSQL数据库吃内存的能力佩服得五体投地,一个小小的网站,运行若干天之后,MSSQL就会把服务器上所有的内存都吃光,此时你不得不重新启动一下服务器或MSSQL来释放内存,有人认为是MSSQL有内存泄露问题,其实不然,微软给我们了明确说明: 在您启动 SQL Server 之后,SQL Server 内存使用量将会持续稳定上升,即使当服务器上活动很少时也不会下降.另外,任务管理器和性能监视器将显示计算机上可用的物理内存稳定下降,直到可用内存降到 4 至 10 MB

js获取指定id innerHTML时出现未知的运行时错误的解决方法

<script> document.getelementbyid("trone").innerhtml = "<td>haha</td>"; </script> </head> <body> <div id="trone"></div> </body> </html> <!-- 问题现在在js与htm位置区别,因为程序是从

数据库自增主键可能产生的问题

在MySQL中经常会配置自增长属性的字段作为主键,特别是使用InnoDB存储引擎, 因为InnoDB的聚集索引的特性,使用自增长属性的字段当主键性能更好,但是使用自增主键也可能会带来一些问题. 举个例子,使用自增主键对数据库做分库分表,可能出现一些诸如主键重复等的问题,或者在数据库导入的时候,可能会因为主键出现一些问题. 主要业务表的主键应该配置一个合理的策略,尽量避免自增AUTO_INCREMENT. 针对主键自增可能产生的问题,下面这两篇文章有相关的讨论: INNODB自增主键的一些问题my

spring-mybatis 批量新增时,怎么批量返回自增ID,数据库是mysql

问题描述 mybatis 批量新增时,怎么批量返回自增ID,数据库是mysql 各位大侠你们好..如题..求解,下面是DAO和SQL: spring Dao的方法定义: public List saveCatalogList(@Param("catalist") List catalist);? mybatis的批量插入SQL: insert into CATALOG (Marc_Type,Catalog_State,Doc_Type,LANG_CODE,Country_Code,Ca

在oracle数据库里创建自增ID字段的步骤_oracle

在oracle里使用自增ID字段的步骤比较繁琐,总结如下: -- 创建表 CREATE TABLE ADVICE ( ID INT NOT NULL, ACTIVE INT DEFAULT 1 NOT NULL, TYPE INT NOT NULL, MSG VARCHAR2(512) NOT NULL, ADVICE VARCHAR2(4000) NOT NULL, PRIMARY KEY(ID), CONSTRAINT ADVICE_UNI UNIQUE(TYPE,MSG) )TABLESP