foreword
Recently, in the process of migrating the product database from MySql to PostgreSQL, in the migration and adaptation of MySql auto-incrementing primary key to PostgreSQL auto-incrementing primary key, after going through a bit of twists and turns, the problem was finally solved through the process of jumping in and out of the pit. I hereby record and summarize the experience of students who have encountered similar situations.
What is an auto-incrementing primary key?
When set 自增主键
, the generation of the primary key is completely dependent on the database without human intervention. When new data is added, developers do not need to manually set the value of the primary key field, and the database will automatically generate a primary key value.
Why do you need an auto-increment primary key?
- The auto-increment primary key allows the primary key index to be inserted in increasing order, thus avoiding page splitting;
- Compared with other types (such as varchar), using auto-increment primary keys saves storage overhead to a certain extent;
- The maintenance of the application program is relatively simple, only unified configuration is required in the code, and there is no need to manually set the primary key value;
1. The use of auto-increment primary key in MySql
1. Create a table with an auto-increment primary key
create table t_user(
`id` INT NOT NULL AUTO_INCREMENT COMMENT '主键id',
`age` INT(11) NOT NULL DEFAULT 10 COMMENT '年龄',
PRIMARY KEY (`id`)
)
2. How to write SQL when inserting data
insert into t_user(age) values(18)
insert into t_user(age) values(20)
Query the above inserted data
3. Modify the initial value of the auto-increment primary key
In some cases, the application needs the ID primary key to start from a specified position, or greater than this value (for example: to reserve a certain ID range in the middle), you can use the following sql statement on the basis of a known table Adjustment
alter table t_user auto_increment=10;
Then, insert two pieces of data into the above table
insert into t_user(age) values(24)
insert into t_user(age) values(26)
Observe the effect again, and you can find that the initial value of id becomes 11 at this time
4. Usage of auto-increment primary key in mybatis
The following methods can be used in the processing of mybatis on the auto-increment primary key
<insert id="addUser" parameterType="com.congge.entity.TUser">
INSERT INTO t_user
(age)
VALUES (
#{age}
)
<selectKey keyProperty="id" resultType="java.lang.Integer" order="AFTER">
SELECT LAST_INSERT_ID();
</selectKey>
</insert>
Supplementary Note
When the above table is built, the primary key auto-increment is limited directly by building the table, or you can not specify it before building the table, but use the alert statement to modify:
alter table t_user modify id integer auto_increment ;
2. Use of auto-increment primary key in PostgreSQL
In PostgreSQL, the use of the auto-increment primary key is slightly different. When creating a table, specify the field type as serial to identify the current field as an auto-increment primary key;
In PostgreSQL, the following two methods can be used to set a sequence of increasing primary key values (mysql can also be used)
Pre-preparation, create an ordinary PG table
create table t_user(
id INT NOT NULL ,
age INT NOT NULL DEFAULT 10,
PRIMARY KEY (id)
)
Method 1: By manually creating a sequence to achieve an incremental effect
Create an auto-increment sequence (similar to the function in mysql), and call this sequence every time you need to obtain the auto-increment primary key.
1. Create an auto-increment primary key sequence
CREATE SEQUENCE
t_user_id_seq
INCREMENT 1 -- step size
MINVALUE 1 -- minimum value
MAXVALUE 9999 -- maximum value
START WITH 1 -- initial value
CACHE 1;
After executing the above creation sequence method, you can query all sequences in the database through the following sql
select * from information_schema.sequences where sequence_schema = 'public';
The circled in the figure is the sequence value we just created above
2. Call the auto-increment sequence method to insert data
The next step is to call the related methods of the sequence, and then use it in the sql of the insert statement. If you want to insert data into the above t_user table, you can use the following sq operation,
insert into t_user values(
nextval('t_user_id_seq') , 18
)
insert into t_user values(
nextval('t_user_id_seq') , 22
)
3. Summary of common methods of auto-increment sequence
It can be seen that the data is inserted in the way of primary key auto-increment as we expected. In the above insert statement, the nextval method is used, which is one of the methods provided by default in the auto-increment sequence. The auto-increment sequence provides common The following methods provide reference
function | return type | Description |
loadselect() | bigint | Returns the most recent value of any sequence obtained with nextval |
nextval( regclass ) | bigint | Increments a sequence and returns the new value |
currval( regclass ) | bigint | Get the value of the specified sequence after the last use of netxval. If you use currval directly instead of nextval, an error will occur. |
setval( regclass,bigint ,boolean ) | bigint | Set the current value of the sequence and the is_called flag. If it is true, it will take effect immediately. If it is false, it will take effect after calling nextval once |
setval( regclass,bigint ) | bigint | Sets the current value of the sequence |
4. Set the default value of the auto-increment primary key
The method provided above found that when writing the insert statement, it is necessary to add a function, which is somewhat cumbersome. Therefore, the following method can be considered to adjust the default value of the ID field;
Set the default value of the id field to nextval('t_user_id_seq') , and add this sentence directly on the basis of the sequence created above
alter table
t_user
alter column
id
set default nextval(
't_user_id_seq'
);
When inserting data again, just write it directly as follows
insert into t_user values(
23
)
insert into t_user values(
24
)
Query the data and find that it can still be successfully written in
Method 2: By specifying the field as serial type to achieve the incremental effect
1. Use the following table creation statement
create table t_user(
id serial NOT NULL ,
age INT NOT NULL DEFAULT 10,
PRIMARY KEY (id)
)
2. View the created sequence
select * from information_schema.sequences where sequence_schema = 'public';
Note that the sequence created before will not be cleaned up unless the statement to clean up the sequence is called manually. By default, the name of the sequence is +id_seq. Since it was created before, a seq1 is automatically spliced here, that is, id Using serial, PG will attach a sequence to the current table by default;
3. Insert data
When inserting data again, just write as follows
insert into t_user(age) values(
23
);
insert into t_user(age) values(
24
);
The data can still be found, and the id is incremented;
4. The use of PG sequence in mybatis
<insert id="addUser" parameterType="com.congge.entity.TUser">
INSERT INTO t_user
(age)
VALUES (
#{age}
)
<selectKey keyProperty="id" resultType="java.lang.Integer" order="AFTER">
SELECT nextval('t_user_id_seq'::regclass) as id
</selectKey>
</insert>
3. MySql data migration to PostgreSQL Some suggestions on auto-increment primary key
In actual business, the migration at the data level may be done first. After the migration is completed, the business can be used normally. However, after migrating the data, the editor found that the interface reported an error. The main reason for the error was the primary key conflict. Why? how about this?
For example, the maximum value of the data id of the t_user table in mysql is 99. After migrating to pg, the maximum value of the data is still 99. There is nothing wrong with this, but after cutting the database, when using the PG auto-increment sequence to create data, but from 1, after the migration, the data with ID 1 already exists, and of course an error will be reported;
At this time, it is necessary to make simple settings for the migrated sequence. The core idea is as follows for reference:
- Use the max function to find the maximum value of the current ID: select max(id) from t_user;
- Manually adjust the starting value of the sequence: alter sequence t_user_id_seq restart with [the maximum value in the first step or add a little];