精华内容
下载资源
问答
  • Oracle数据库主键自动增长

    万次阅读 2018-08-30 15:32:25
    1:首先创建一张普通的表 ... id int primary key NOT NULL , //必须要有主键 mydate varchar(45) NOT NULL, height varchar(45) NOT NULL, weight varchar(45) NOT NULL, bmi varchar(45) NOT NULL,...

    1:首先创建一张普通的表

    CREATE TABLE bmi (
      id int primary key NOT NULL , //必须要有主键
      mydate varchar(45) NOT NULL,
      height varchar(45) NOT NULL,
      weight varchar(45) NOT NULL,
      bmi varchar(45) NOT NULL,
      sign varchar(45) NOT NULL,
      userName varchar(45) NOT NULL
     ); 

    2:序列(Sequence),又叫序列生成器,用于提供一系列的数字,开发人员使用序列生成唯一键。每次访问序列,序列按照一定的规律增加或者减少。
    序列的定义存储在SYSTEM表空间中,序列不像表,它不会占用磁盘空间。
    序列独立于事务,每次事务的提交和回滚都不会影响序列。

    创建的方法及参数说明如下,想了解更多,可以具体查一下oracle database sequence的说明:

    CREATE SEQUENCE SEQNAME    //序列名字         
    INCREMENT BY 1                    //每次自增1, 也可写非0的任何整数,表示自增,或自减  
    START WITH 1                       //以该值开始自增或自减  
    MAXVALUE 1.0E20                   //最大值;设置NOMAXVALUE表示无最大值  
    MINVALUE 1                           //最小值;设置NOMINVALUE表示无最大值  
    CYCLE or NOCYCLE                  //设置到最大值后是否循环;  
    CACHE 20                              //指定可以缓存 20 个值在内存里;如果设置不缓存序列,则写NOCACHE  
    ORDER or NOORDER                  //设置是否按照请求的顺序产生序列  

    3:创建此表的序列

    create sequence bmi_tb_seq 
             minvalue 1 maxvalue 1000   
             increment by 1    
             start with 1;   /*步长为1*/ 

    4:创建触发器


    create or replace trigger bmi_tb_tri      
    before insert on bmi  /*触发条件:当向表bmi执行插入操作时触发此触发器*/    
     for each row     /*对每一行都检测是否触发*/    
    begin   /*触发器开始*/    
    select  bmi_tb_seq.nextval into :new.id from dual;   
    /*触发器主题内容,即触发后执行的动作,在此是取得序列bmi_tb_seq的下一个值插入到表
    bmi中的id字段中*/    
    end;    
    /  

    5: 提交: 现在就完成了主键的自动增长


    insert into bmi('id','mydate','height','weight','bmi','sign','username') values(null,'2018','男','180','70','..','jack')

    6:提示“已创建一行”,表示成功。

    展开全文
  • 我们先来通过mycat实现一个自增长主键,现在有两个数据库,mycat和mycat2,然后设定数据库增长的方式,按照自增长的方式实现。自增长实现步骤:1、创建数据库,2、创建mycat的自增长函数,3、插入需要自增长策略,4...

    我们先来通过mycat实现一个自增长的主键,现在有两个数据库,mycat和mycat2,然后设定数据库增长的方式,按照自增长的方式实现。自增长实现步骤:1、创建数据库,2、创建mycat的自增长函数,3、插入需要自增长策略,4、配置schemal.xml,添加自增长的表,5、配置server.xml,设置主键增长策略,6、配置sequence_db_conf.properties,添加需要自增长的表。 如果我们后期想添加自增长的表,只需要进行步骤3、4、6 三个步骤。

    数据准备

    1、创建数据库

    创建两个数据库,并都创建test表

    #创建数据库
    create database mycat;
    
    #添加表
    use mycat 
    #创建表test
    create table test3(id int auto_increment primary key,name varchar(32)) ;
    
    #创建数据库
    create database mycat3;
    
    #添加表
    use mycat 2
    #创建表test
    create table test3(id int auto_increment primary key,name varchar(32)) ;

    这里写图片描述

    添加后的表数据,看了一下,表示表建立好了
    这里写图片描述

    2、创建Mycat生成唯一主键所需要的函数

    我将自增长的函数都创建在了mycat这个db中

    DROP TABLE IF EXISTS MYCAT_SEQUENCE;
    CREATE TABLE MYCAT_SEQUENCE (
    NAME VARCHAR (50) NOT NULL,
    current_value INT NOT NULL,
    increment INT NOT NULL DEFAULT 100,
    PRIMARY KEY (NAME)
    ) ENGINE = INNODB ;
    
    
    INSERT INTO MYCAT_SEQUENCE(NAME,current_value,increment) VALUES ('GLOBAL', 100000, 100);
    
    DROP FUNCTION IF EXISTS `mycat_seq_currval`;
    DELIMITER ;;
    CREATE FUNCTION `mycat_seq_currval`(seq_name VARCHAR(50)) 
    RETURNS VARCHAR(64) CHARSET utf8
        DETERMINISTIC
    BEGIN DECLARE retval VARCHAR(64);
            SET retval="-999999999,null";  
            SELECT CONCAT(CAST(current_value AS CHAR),",",CAST(increment AS CHAR) ) INTO retval 
              FROM MYCAT_SEQUENCE WHERE NAME = seq_name;  
            RETURN retval ; 
    END
    ;;
    DELIMITER ;
    
    DROP FUNCTION IF EXISTS `mycat_seq_nextval`;
    DELIMITER ;;
    CREATE FUNCTION `mycat_seq_nextval`(seq_name VARCHAR(50)) RETURNS VARCHAR(64)
     CHARSET utf8
        DETERMINISTIC
    BEGIN UPDATE MYCAT_SEQUENCE  
                     SET current_value = current_value + increment 
                      WHERE NAME = seq_name;  
             RETURN mycat_seq_currval(seq_name);  
    END
    ;;
    DELIMITER ;
    
    
    DROP FUNCTION IF EXISTS `mycat_seq_setval`;
    DELIMITER ;;
    CREATE FUNCTION `mycat_seq_setval`(seq_name VARCHAR(50), VALUE INTEGER) 
    RETURNS VARCHAR(64) CHARSET utf8
        DETERMINISTIC
    BEGIN UPDATE MYCAT_SEQUENCE  
                       SET current_value = VALUE  
                       WHERE NAME = seq_name;  
             RETURN mycat_seq_currval(seq_name);  
    END
    ;;
    DELIMITER ;
    

    3、测试添加结果

    #查询当前所在db ,这个语句只是想给大家证明,我是在mycat 这个数据库里面添加的函数
    select database();
    
    #查询doubi这张表里面的数据
    select mycat_seq_nextval('doubi');

    这里写图片描述

    4、插入要自增的表名称到MYCAT_SEQUENC表

    插入数据的时候,一定要注意,自己需要插入的表,一定要是大写的

    #设定TEST3表的增长方式为 步进为1 ,
    insert into MYCAT_SEQUENCE (name,current_value,increment) values ('TEST3',0,1);
    
    #查询结果
     select * from MYCAT_SEQUENCE;

    这里写图片描述

    配置maycat

    1、配置schemal.xml

    vim conf/schemal.xml, 数据库的表名称为test2,设定表的主键,这样mycat好给我们生成主键,而且我们是自增长,所以需要配置autoIncrement="true",这个里面 type="global" 表示是全局的表, 每个子节点,都会存在

    <?xml version="1.0"?>
    <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
    <mycat:schema xmlns:mycat="http://io.mycat/">
    
            <schema name="yellowcong" checkSQLschema="true" sqlMaxLimit="1000">
                    <table name="test3" dataNode="jdbc_node1,jdbc_node2" primaryKey="id" autoIncrement="true"  type="global"/>
            </schema>
    
            <dataNode name="jdbc_node1" dataHost="localhost" database="mycat" />
            <dataNode name="jdbc_node2" dataHost="localhost" database="mycat2" />
    
            <dataHost name="localhost" maxCon="1000" minCon="10" balance="0"
                              writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                    <heartbeat>select user()</heartbeat>
    
                    <writeHost host="hostM1" url="127.0.0.1:3306" user="root" password="root" />
    
            </dataHost>
    
    
    </mycat:schema>
    
    

    2、配置server.xml

    需要修改sequnceHandlerType 为1,<property name="sequnceHandlerType">1</property>

    vim conf/server.xml
    
    0 表示是表示使用本地文件方式。
    1 表示的是根据数据库来生成,就是我们自己配置的自增长
    2 表示时间戳的方式 ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加)
    <property name="sequnceHandlerType">1</property>

    下面是全部配置

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- - - Licensed under the Apache License, Version 2.0 (the "License");
            - you may not use this file except in compliance with the License. - You
            may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
            - - Unless required by applicable law or agreed to in writing, software -
            distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
            WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
            License for the specific language governing permissions and - limitations
            under the License. -->
    <!DOCTYPE mycat:server SYSTEM "server.dtd">
    <mycat:server xmlns:mycat="http://io.mycat/">
            <system>
            <property name="serverPort">8066</property>
            <property name="useSqlStat">0</property>  <!-- 1为开启实时统计、0为关闭 -->
            <property name="useGlobleTableCheck">0</property>  <!-- 1为开启全加班一致性检测、0为关闭 -->
    
                    <property name="sequnceHandlerType">1</property>
    
                    <!--默认为type 0: DirectByteBufferPool | type 1 ByteBufferArena-->
                    <property name="processorBufferPoolType">0</property>
    
                    <!--分布式事务开关,0为不过滤分布式事务,1为过滤分布式事务(如果分布式事务内只涉及全局表,则不过滤),2为不过滤分布式事务,但是记录分布式事务日志-->
                    <property name="handleDistributedTransactions">0</property>
    
                            <!--
                            off heap for merge/order/group/limit      1开启   0关闭
                    -->
                    <property name="useOffHeapForMerge">1</property>
    
                    <!-- 单位为m-->
                    <property name="memoryPageSize">1m</property>
    
                    <!--单位为k -->
                    <property name="spillsFileBufferSize">1k</property>
    
                    <property name="useStreamOutput">0</property>
    
                    <!--单位为m-->
                    <property name="systemReserveMemorySize">384m</property>
    
    
                    <!--是否采用zookeeper协调切换  -->
                    <property name="useZKSwitch">true</property>
            </system>
    
            <user name="root">
                    <property name="password">root</property>
                    <property name="schemas">yellowcong</property>
            </user>
    
            <user name="user">
                    <property name="password">user</property>
                    <property name="schemas">yellowcong</property>
                    <property name="readOnly">true</property>
            </user>
    
    </mycat:server>
    

    3、配置sequence_db_conf.properties

    #配置默认的表自增长设置
    vim ./conf/sequence_db_conf.properties
    
    #添加需要自增长的表名称
    TEST3=jdbc_node1

    这里写图片描述

    测试插入数据

    重启mycat服务后,连接数据库,测试插入数据到TEST3表

    #连接mycat
    mysql -h 127.0.0.1 -P 8066 -u root -proot
    
    #使用yellowocng 数据库
    use yellowcong ;
    
    #查看表信息
    show tables ;
    
    #插入数据
    #插入多条数据
    insert into test3 (name) values ('doubi1'),('doubi2'),('doubi3'),('yellowcong');
    
    #查询数据
    select * from test3;

    这里写图片描述

    查询数据,结果可以看到,角标的增长很完美。是增长的步进是1.
    这里写图片描述

    查看子节点,可以看到对mycat操作后,由于是全局表,所以每个子节点数据中,都存在表信息。
    这里写图片描述

    错误集合

    ERROR 1064 (HY000): bad insert sql (sharding column:ID not provided,INSERT INTO test2 (NULL, ‘doubi1’)

    包这个问题的原因很明显,就是我们没有设置mycat中虚拟表的id自增,所以导致没有获取到id,所以导致了这个问题。

    这里写图片描述

    #修改后的语句
    insert into test2(name) values('doubi1'),('doubi2'),('doubi3'),('yellowcong');

    ERROR 1064 (HY000): insert must provide ColumnList

    必须提供添加的列,直接插入,导致了问题,所以我们需要修该插入语句
    这里写图片描述

    #原来语句
    insert into test2 (null,'doubi1'),(null,'doubi2'),(null,'doubi3'),(null,'yellowcong');
    
    #修改后的语句
    insert into test2(name) values('doubi1'),('doubi2'),('doubi3'),('yellowcong');

    Out of range value for column ‘id’ at row 1

    导致这个问题的大致原因可能是由于mycat生成的id和数据库的字符长度对不上,超过了数据库配置的默认长度所导致的。解决办法,就是修改数server.xml,设定id生成策略是根据数据库生成的。
    这里写图片描述

    vim conf/server.xml
    
    0 表示是表示使用本地文件方式。
    1 表示的是根据数据库来生成
    2 表示时间戳的方式 ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加)
    <property name="sequnceHandlerType">1</property>

    这里写图片描述

    mycat sequnce err.io.mycat.config.util.ConfigException: can’t find definition for sequence :TEST2

    mycat对应sequence_db_conf.properties增加相应设置
    这里写图片描述

    #配置默认的表自增长设置
    vim ./conf/sequence_db_conf.properties
    
    #添加需要自增长的表名称
    TEST3=jdbc_node1

    这里写图片描述

    mycat sequnce err.java.lang.RuntimeException: can’t fetch sequnce in db,sequnce :TEST2

    报错,说没办法获取到 id,从数据库中,这个说明我们sequence_db_conf.properties 的配置文件有问题
    这里写图片描述

    mycat sequnce err.java.lang.RuntimeException: can’t fetch sequnce in db,sequnce :TEST2 detail:FUNCTION mycat.mycat_seq_nextval does not exist

    说没有mycat.mycat_seq_nextval 这个函数,说明在rule.xml中还需要添加这个配置
    这里写图片描述

    #添加表
    DROP TABLE IF EXISTS MYCAT_SEQUENCE;
    CREATE TABLE MYCAT_SEQUENCE (
    NAME VARCHAR (50) NOT NULL,
    current_value INT NOT NULL,
    increment INT NOT NULL DEFAULT 100,
    PRIMARY KEY (NAME)
    ) ENGINE = INNODB ;
    
    
    INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES ('GLOBAL', 100000, 100);
    
    DROP FUNCTION IF EXISTS `mycat_seq_currval`;
    DELIMITER ;;
    CREATE FUNCTION `mycat_seq_currval`(seq_name VARCHAR(50)) 
    RETURNS varchar(64) CHARSET utf8
        DETERMINISTIC
    BEGIN DECLARE retval VARCHAR(64);
            SET retval="-999999999,null";  
            SELECT concat(CAST(current_value AS CHAR),",",CAST(increment AS CHAR) ) INTO retval 
              FROM MYCAT_SEQUENCE WHERE name = seq_name;  
            RETURN retval ; 
    END
    ;;
    DELIMITER ;
    
    DROP FUNCTION IF EXISTS `mycat_seq_nextval`;
    DELIMITER ;;
    CREATE FUNCTION `mycat_seq_nextval`(seq_name VARCHAR(50)) RETURNS varchar(64)
     CHARSET utf8
        DETERMINISTIC
    BEGIN UPDATE MYCAT_SEQUENCE  
                     SET current_value = current_value + increment 
                      WHERE name = seq_name;  
             RETURN mycat_seq_currval(seq_name);  
    END
    ;;
    DELIMITER ;
    
    
    DROP FUNCTION IF EXISTS `mycat_seq_setval`;
    DELIMITER ;;
    CREATE FUNCTION `mycat_seq_setval`(seq_name VARCHAR(50), value INTEGER) 
    RETURNS varchar(64) CHARSET utf8
        DETERMINISTIC
    BEGIN UPDATE MYCAT_SEQUENCE  
                       SET current_value = value  
                       WHERE name = seq_name;  
             RETURN mycat_seq_currval(seq_name);  
    END
    ;;
    DELIMITER ;
    
    
    
    
    #插入一条数据,这条数据是我们这个表所需要的。
    #必须是大写的字符,不然就会报错
    #插入需要自增张的表的策略
    insert into  MYCAT_SEQUENCE (name,current_value,increment) values ('TEST3',0,1);
    

    参考文章

    http://www.linuxidc.com/Linux/2016-01/127829.htm

    展开全文
  • oracle主键自增
    我们都知道,在MySQL中,要实现主键的自动递增非常简单.只需要在主键定义的后面加上auto_increment即可,
    但是在Oracle中就不是这样,需要分几步来完成
    1.建立一个表
    create table 户口本  (
       户号                   INTEGER                         not null,
       户别                   CHAR(20)                        not null,
       户主姓名                 CHAR(20)                        not null,
       住址                   CHAR(200)                       not null,
       承办人                  CHAR(20)                        not null,
       日期                   DATE                            not null,
       constraint PK_户口本 primary key (户号)
    );
     
    2.建立一个sequence序列:
    CREATE SEQUENCE book_Sequence
     INCREMENT BY 1   -- 每次加几个  
         START WITH 1     -- 从1开始计数  
         NOMAXVALUE       -- 不设置最大值  
         NOCYCLE ;         -- 一直累加,不循环
     
    3.建立一个触发器:
    CREATE TRIGGER book_increase BEFORE
    insert ON 户口本 FOR EACH ROW
    begin
    select BOOK_SEQUENCE.nextval into:New.户号 from dual;
    end;
     
    这样就可以了,以后在插入户口本表的时候主键输入null,就可以实现自动递增.
    有一个地方需要强调,就是可以有些初学者喜欢用中文命名这样非常的麻烦..而且也不符合国际化的思想,不过sequence必须用英文..
    展开全文
  • oracle 数据库没有像 MYSQL一样有 自动ID增值 的功能,如要实现可以用触发器。 首先就是建立一个序列,序列有有自动增值的功能,再建立一个触发器。 如: 建立一个序列 CREATE SEQUENCE auto_seq minvalue 1 -- ...

    oracle 数据库没有像 MYSQL一样有 自动ID增值 的功能,如要实现可以用触发器。

    首先就是建立一个序列,序列有有自动增值的功能,再建立一个触发器。

    如:

    建立一个序列

    CREATE SEQUENCE auto_seq
    minvalue 1 -- 最小值
    increment by 1 -- 每次增加值数
    nocache -- 不启用缓存
    nocycle -- 不循环;

    建立一个触发器

    CREATE OR REPLACE trigger auto_id_tri
    before insert on pjsh_person -- before 表示插入新数据时执行
    for each row -- 每次插入数据到pjsh_person表时执行下面的oracle 语句
    begin
    select auto_seq.nextval into :NEW.ID from dual;
    end;

    auto_id_tri 触发器名

    auto_seq.nextval 提取auto_seq 序列的值

    :NEW.ID  ID为要添加的主键列名

    pjsh_person 要添加自动ID值的表名。

    展开全文
  • 1、创建数据库 创建两个数据库,并都创建test表 #创建数据库 create database mycat; #添加表 use mycat #创建表test create table test3(id int auto_increment primary key,name varchar(32)) ; #创建数据库 ...
  • 将表的主键进行序列增加之后可以在数据库层面自动主键id增长 方法如下:先建序列,然后建表关联id主键,然后添加语句,不用考虑id主键 DROP SEQUENCE IF EXISTS "public"."sp_warehouse_id_seq"; CREATE ...
  • 通过本地文件的方式,mycat将配置classpath目录下面的sequence_conf.properties文件中,自动进行增长,但是...2、配置schema.xml文件,设定主键自增长,3、配置server.xml,配置为本地文件方式,4、配置equence_conf.p
  • 首先创建基础表 接着配置MyCat中相差配置文件 一、server.xml 保存了所有mycat需要的... 1 表示的是根据数据库来生成 2 表示时间戳的方式 ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加)
  • 本地时间的方式,id自动生成的策略ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+...实现本地时间戳注意点,就是自动生成的id是18位的,所以大家在创建表的时候,需要注意下主键的大小。 创建数据库#创建数据库 cr

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,052
精华内容 1,220
关键字:

数据库主键自增长