zoukankan      html  css  js  c++  java
  • Mysql、Oracle插表关于主键的处理

    1.情景展示

    在实际开发过程中,在新增表数据时,对于表字段主键,Mysql和Oracle的处理方式是不一样的。

    2.Oracle

    Oracle的主键通过序列来实现;

    要想使用序列,需要先给主键创建序列,通常以"seq_"+表名的格式进行命名,方便识别;

    获取主键的方式:需要提前获取,也就是在插入表记录之前,就可以提前知晓该行记录的主键ID;

    即:通过查询获取主键ID;

    SELECT SEQ_TABLE_NAME.NEXTVAL FROM DUAL

     在IBATIS或MYBATIS中的用法为:(ibatis+oracle)

    <!-- 接入授权表 插入sql -->
    <insert id="insertACCESS_GRANT" parameterClass="map">
     <selectKey keyProperty="ID" resultClass="java.lang.String">
           SELECT SEQ_ACCESS_GRANT.NEXTVAL FROM DUAL
       </selectKey>
        INSERT INTO ACCESS_GRANT(ID,GRANTJK,SECRETKEY,ACCESSID)
        VALUES(#ID#,#GRANTJK#,#SECRETKEY#,#ACCESSID#)
    </insert>

    这样,查询出来的ID将会和行数据一同插入到表中。

    Oracle使用序列的方式的好处在于:

    序列的数据具有唯一性,每次查询都会+1,不用考虑并发问题,只要是使用序列值当做主键,基本不会出现序列值(ID)重复导致插入失败的问题;

    另外,基于这个特性,当我们需要提前获取ID而进行一些基于当前行ID做些处理时,将会非常简单。

    缺点在于:序列一直增加,因为其它字段导致插入失败时,难免会造成序列号不连续。

    3.Mysql

    Mysql的主键可以设置自增属性;

    在插入表数据的时候,不需要获取主键,不需要给主键填充数值,Mysql会自动给该字段赋值;

     在IBATIS或MYBATIS中的用法为:(ibatis+mysql)

    <insert id="insertMETA_THEME" parameterClass="map">
        INSERT INTO META_THEME(THEMENAME,THEMECODE,THEMELEVEL,PARENTTHEMEID,STATUS,ZJM,CREATETIME,REMARK1,REMARK2,REMARK3)
        VALUES(#THEMENAME#,#THEMECODE#,#THEMELEVEL#,#PARENTTHEMEID#,#STATUS#,#ZJM#,DATE_FORMAT(sysdate(),'%Y-%m-%d %H:%i:%s'),#REMARK1#,#REMARK2#,#REMARK3#)
    </insert>

     或者,携带主键,不赋值:

    Mysql自增主键的好处在于:

    可以只管填数据,不需考虑主键的问题;

    插入数据失败,不会触发自增,确保ID的连续性(刨除删除表数据造成的主键ID缺失)。

    坏处在于:在插入数据之前无法提前获得主键ID。

    4.拓展

    Mysql,如何在插入数据之前获取(确定)主键?

    首先,这种需求肯定是普遍存在的,举个例子:

    某表结构有字段:主键ID和编码,编码根据主键等固定规则生成,这就需要我们在插入数据之前提前获取并确定该行记录的主键ID;

    这里提供两种解决办法:

    办法一:

    在插入数据的时候编码字段先不管,也就是该字段值插入的是null,待插入成功将主键返回后,在生成编码并更新字段编码的值。

    缺点是:繁琐,需要对表操作两次,才能完成一条记录;

    好处是:提高成功率,不需要考虑因主键ID重复造成插入失败问题。

    办法二:

    查询当前最大的ID,MAX_ID+1当做即将插入字段的ID。

    考虑到并发问题,在查询的时候增加了排他锁,但预计并不能解决并发造成主键ID重复的问题。

    好处在于:可以在插入数据之前就能确定ID;

    坏处在于:不支持并发,一旦并发,就会造成因主键ID重复造成数据插入失败。

    办法三:该方法行不通

    使用函数LAST_INSERT_ID()

    网上百度出来,可以使用这种方法,经测试无效;

    LAST_INSERT_ID()返回的是上一次插入的ID值,不能在插入数据前,只能用在插入数据后,那这样,对于我们来说,该函数就失去了使用意义。

    第1次执行插入,虽然last_insert_id()函数返回的是0,控制台显示的也是插入的是0,但实际上,插入的数据库的主键确实48;

    第2次执行插入,last_insert_id()函数返回的是48,因为主键ID=48的数据记录已经存在,所以,就会造成主键重复,导致插入失败;

    那是不是last_insert_id()+1就可以解决这个问题了呢?

    重启tomcat,再次尝试,主键ID计数将从0重新开始:

    更多关于last_insert_id()使用弊端的问题见文末推荐。

    写在最后

      哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

     相关推荐:

    本文来自博客园,作者:Marydon,转载请注明原文链接:https://www.cnblogs.com/Marydon20170307/p/15592462.html

  • 相关阅读:
    geoserver发布地图服务WMTS
    geoserver发布地图服务WMS
    geoserver安装部署步骤
    arcgis api 3.x for js 入门开发系列十四最近设施点路径分析(附源码下载)
    arcgis api 3.x for js 入门开发系列十三地图最短路径分析(附源码下载)
    cesium 之自定义气泡窗口 infoWindow 后续优化篇(附源码下载)
    arcgis api 3.x for js 入门开发系列十二地图打印GP服务(附源码下载)
    arcgis api 3.x for js 入门开发系列十一地图统计图(附源码下载)
    arcgis api 3.x for js 入门开发系列十叠加 SHP 图层(附源码下载)
    arcgis api 3.x for js入门开发系列九热力图效果(附源码下载)
  • 原文地址:https://www.cnblogs.com/Marydon20170307/p/15592462.html
Copyright © 2011-2022 走看看