Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autoincrement separately for each foreign key

I have two tables:

 CREATE TABLE "user"
    (
      username character varying(35) NOT NULL,
      CONSTRAINT user_pk PRIMARY KEY (username)
    )
    CREATE TABLE item
    (
      id serial NOT NULL,
      username character varying(35),
      user_item_number integer,
      item_value character varying(35),
      CONSTRAINT item_pk PRIMARY KEY (id),
      CONSTRAINT item_fk FOREIGN KEY (username)
          REFERENCES "user" (username) MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE NO ACTION,
      CONSTRAINT unique_item_username UNIQUE (username, user_item_number)
    )

enter image description here

I would like to auto increment user_item_number separately for each username. Following image shows example. For each username: (user1, user2) user_item_number starts form 1 and is incremented by 1. enter image description here

I suppose that I should use some trigger before insert which get max value of user_item_number for username which is inserted and increment it. But I don't know how to write that trigger.

I also don't know how to consider a concurency access (concurency insert more than one row with the same value of username). I don't want to get constraint violation error when two rows with the same username and user_item_number are inserted, I would like that trigger catch that error and one again increment user_item_number value.

Any idea?

like image 375
Mariusz Avatar asked Aug 06 '13 12:08

Mariusz


People also ask

Can a foreign key Autoincrement?

A foreign key is a link to a specific record in another table (or another record in the same table). Creating a foreign key field that is auto-incrementing would create a link to an arbitrary (and possibly non-existent) record, which would defeat the whole purpose of having a foreign key in the first place.

Can you create an auto increment on a unique key?

Auto-increment allows a unique number to be generated automatically when a new record is inserted into a table. Often this is the primary key field that we would like to be created automatically every time a new record is inserted.

Is primary key should always be auto increment?

The above statement is true. Primary key should always be auto increment.

How do I set Autoincrement value?

In MySQL, the syntax to change the starting value for an AUTO_INCREMENT column using the ALTER TABLE statement is: ALTER TABLE table_name AUTO_INCREMENT = start_value; table_name. The name of the table whose AUTO_INCREMENT value you wish to change.


2 Answers

It is really hard to generate and maintain such gapless sequence.

the better way to obtain same results is to use window functions to generate such sequences on the fly. Something like:

SELECT id, username, row_number() OVER (PARTITION BY username ORDER BY id) as user_item_number, item_value
from item_table;

It will give you desired results and wont cause any problems with concurrency. Also it will always maintain sequences gapless.

like image 73
Ihor Romanchenko Avatar answered Sep 20 '22 23:09

Ihor Romanchenko


Auto inc should be unique and only one per table.

So based on what you seem to want

User(User_ID PK, ...)
UserItem(User_Item_ID PK, User_ID FK, ...)
UserItemValue(User_Item_Value_ID PK, User_Item_ID FK, ...)

is where you should be heading from a normalisation point of view

like image 40
Tony Hopkinson Avatar answered Sep 21 '22 23:09

Tony Hopkinson