MySQL autoincrement value range - mysql

Scenario is that I have 2 tables of the same structure, however I only want to allow php permissions to update table B, while table A can only be updated via DBMS.
These 2 tables are merged into a single php array, so I would like to set primary key ranges to seperate them at this point to avoid conflict of primary key (a simple autoincrement integer for best indexing).
As far as I know the simplest would be to constrain table A to have primary key auto increment values from 1000000 to 1999999 and then table B 2000000 upwards.
Is this possible to constrain min-max autoincrement values (I know I can start them at a given integer so asking if there is a simple 'max' to put on table A).
This simple configuration would ensure integrity.
Would an 'after_insert' type trigger work to remove the new row and throw an SQL error ?

You could create one table with id as mediumint (max 8 388 607 or twice as much for unsigned):
create table tableA( id mediumint(5) not null auto_increment, `test` varchar(5), primary key (id)) ;
and second with int and auto_increment value set over mediumint max:
create table tableB( id int(5) not null auto_increment, `test` varchar(5), primary key (id)) auto_increment=8388608 ;
https://dev.mysql.com/doc/refman/8.0/en/integer-types.html
But i think that much more elegant would be to utilize auto_increment_increment mechanism.
auto-increment-increment = 2 //global for all tables in mysql.ini
SET ##auto_increment_increment=2; //run-time just for one session
Set in tableA first auto_increment=1 and in tableB auto_increment=2 and You will never collide. One table will have odd ids and second will have even ids. This way You do not have to worry about reaching id limit.

Related

How to create sequence for a number that starts at 100 and increment by 5 in MySQL?

I need that the values for a ColumnID, which is a Primary Key, to start at 100 and increment by 5. This condition is asked to be included as a constraint before populating the tables. I already created the tables, I just need to add that constraint. I know I can't use AUTO_INCREMENT because the increase is only by 1. Is there a way to do it in MySQL?
MySQL does not provide any built-in function to create a sequence for a table's rows or columns. But we can generate it via SQL query.
Example:
Let us understand it with the help of the following example. First, we need to create a new table and make sure that there is one column with the AUTO_INCREMENT attribute and that too, as PRIMARY KEY.
Execute the below query to create a table:
CREATE TABLE Insects (
Id INT AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(30) NOT NULL,
Type VARCHAR(30) NOT NULL,
Origin VARCHAR(30) NOT NULL
);
Then you can alter your column to start from another value:
ALTER TABLE Insects AUTO_INCREMENT=100;
You can check it here.

MySQL auto assign foreign key ID

I have a main table called results. E.g.
CREATE TABLE results (
r_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
r_date DATE NOT NULL,
system_id INT NOT NULL,
FOREIGN KEY (system_id) REFERENCES systems(s_id) ON UPDATE CASCADE ON DELETE CASCADE
);
The systems table as:
CREATE TABLE systems (
s_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
system_name VARCHAR(50) NOT NULL UNIQUE
);
I'm writing a program in Python with MySQL connector. Is there a way to add data to the systems table and then auto assign the generated s_id to the results table?
I know I could INSERT into systems, then do another call to that table to see what the ID is for the s_name, to add to the results table but I thought there might be quirk in SQL that I'm not aware of to make life easier with less calls to the DB?
You could do what you describe in a trigger like this:
CREATE TRIGGER t AFTER INSERT ON systems
FOR EACH ROW
INSERT INTO results SET r_date = NOW(), system_id = NEW.s_id;
This is possible only because the columns of your results table are easy to fill in from the data the trigger has access to. The auto-increment fills itself in, and no additional columns need to be filled in. If you had more columns in the results table, this would be harder.
You should read more about triggers:
https://dev.mysql.com/doc/refman/8.0/en/create-trigger.html
https://dev.mysql.com/doc/refman/8.0/en/triggers.html

MySQL moving primary key from varchar to int

I have three tables in MySQL (innodb) (X, Y and Z). X is a table with more than 10 million rows, and has primary key of Y as foreign key. Similarly, Z is table with more than 30 million rows and has primary key of Y as foreign key.
Now the problem is that primary key of Y is VARCHAR (something like a md5 hash or GUID). I want to move this key to INT (AUTO_INCREMENT). What is a way to achieve this in mysql, without writing a script in any other language?
Additionally, primary key of table Z is also a VARCHAR (md5/GUID). I would like to change that to integer as well. (It's not a foreign key in any table).
(This may or may not be any better than Ritobroto's suggestion.)
Assuming X links to Y. (Adapt as needed for all the FKs.)
Do something like this for each table.
ALTER TABLE X
DROP FOREIGN KEY ..., -- We'll add it back later
ADD id INT UNSIGNED NOT NULL AUTO_INCREMENT, -- Replacement PK
DROP PRIMARY KEY, -- Assuming it was `guid`
ADD PRIMARY KEY(id),
ADD INDEX(X_guid), -- Lost the FK; still (for now) need an index
ADD COLUMN Y_id INT UNSIGNED NOT NULL -- future FK to Y
;
Get the new ids linked up (to replace the guids). For each link:
UPDATE X JOIN Y ON X.Y_guid = Y.guid
SET x.y_id = y.id;
(This will take a long time.
Re-establish the FKs. For each table:
ALTER TABLE ...
ADD FOREIGN KEY ..., -- to tie `id` instead of `guid`
DROP INDEX(X_guid); -- unless you need it for something else
Practice it on a test machine !!
Step 1
Create tables with same column names but the datatype of primary key of Y should be in INT AUTO INCREMENT,Same goes for table Z.
Step 2
Use this query:
INSERT INTO table_name (column_names of present table except the primary key column_name) SELECT all the columns except the primary key column FROM Y/Z(which ever table you want from the data to be inserted).
Then you can drop the original table.
It's a painful process for such amount of data,but will do what you have wanted.

Assign MySQL #rowid as value

I have an existing table with lot of rows (around 10k rows) with two columns as primary keys as it is acting as middle table of many-to-many relation between two other table.
For new requirements, I need to assign add new column (say id) which must be primary key with auto increment values. I ran following queries:
ALTER TABLE `momento_distribution` ADD `id` INT( 11 ) NOT NULL FIRST;
ALTER TABLE `momento_distribution` DROP PRIMARY KEY , ADD PRIMARY KEY ( `id` );
First query run successfully but second query generated following error:
1062 - Duplicate entry '0' for key 'PRIMARY'
Reason is obvious, new column id got 0 as default value and Primary key can't have duplicate values.
Now before I can run second query, I need to set incremental value for new column like 1,2,3...
In Oracle, I know, this can be done through rowid. MySQL also have its equivalent #rowid. Can someone please suggest a query to set #rowid as column value for column id?
Please Note: This had to be done through query as I can't change 10000 rows manually.
You need to set it to AUTO_INCREMENT at the same time, that will populate it;
ALTER TABLE momento_distribution
ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
Demo here.
EDIT: If you have an existing primary key, you'll need to drop that at the same time;
ALTER TABLE momento_distribution
DROP PRIMARY KEY,
ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
Same question asked by same user differently. Refer to that question.
MySQL 1062 - Duplicate entry '0' for key 'PRIMARY'
In short,
1. Remove existing FK
2. Remove existing PK
3. Run your first query as
ALTER TABLE `momento_distribution` ADD `id` INT( 11 ) PRIMARY KEY AUTO_INCREMENT NOT NULL FIRST;
which will also assign unique number without depending on #rowid
4. Add FK to earlier columns, if needed.

What could cause duplicate ids on a auto increment primary key field (mysql)?

RESOLVED
From the developer: the problem was that a previous version of the code was still writing to the table which used manual ids instead of the auto increment. Note to self: always check for other possible locations where the table is written to.
We are getting duplicate keys in a table. They are not inserted at the same time (6 hours apart).
Table structure:
CREATE TABLE `table_1` (
`sales_id` int(10) unsigned NOT NULL auto_increment,
`sales_revisions_id` int(10) unsigned NOT NULL default '0',
`sales_name` varchar(50) default NULL,
`recycle_id` int(10) unsigned default NULL,
PRIMARY KEY (`sales_id`),
KEY `sales_revisions_id` (`sales_revisions_id`),
KEY `sales_id` (`sales_id`),
KEY `recycle_id` (`recycle_id`)
) ENGINE= MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=26759 ;
The insert:
insert into `table_1` ( `sales_name` ) VALUES ( "Blah Blah" )
We are running MySQL 5.0.20 with PHP5 and using mysql_insert_id() to retrieve the insert id immediately after the insert query.
I have had a few duplicate key error suddenly appear in MySql databases in the past even though the primary key is defined and auto_increment. Each and every time it has been because the table has become corrupted.
If it is corrupt performing a check tables should expose the problem. You can do this by running:
CHECK TABLE tbl_name
If it comes back as corrupt in anyway (Will usually say the size is bigger than it actually should be) then just run the following to repair it:
REPAIR TABLE tbl_name
Does the sales_id field have a primary (or unique) key? If not, then something else is probably making inserts or updates that is re-using existing numbers. And by "something else" I don't just mean code; it could be a human with access to the database doing it accidentally.
As the other said; with your example it's not possible.
It's unrelated to your question, but you don't have to make a separate KEY for the primary key column -- it's just adding an extra not-unique index to the table when you already have the unique (primary) key.
We are getting duplicate keys in a table.
Do you mean you are getting errors as you try to insert, or do you mean you have some values stored in the column more than once?
Auto-increment only kicks in when you omit the column from your INSERT, or try to insert NULL or zero. Otherwise, you can specify a value in an INSERT statement, over-riding the auto-increment mechanism. For example:
INSERT INTO table_1 (sales_id) VALUES (26759);
If the value you specify already exists in the table, you'll get an error.
Please post the results of this query:
SELECT `sales_id`, COUNT(*) AS `num`
FROM `table_1`
GROUP BY `sales_id`
HAVING `num` > 1
ORDER BY `num` DESC
If you have a unique key on other fields, that could be the problem.
If you have reached the highest value for your auto_increment column MySQL will keep trying to re-insert it. For example, if sales_id was a tinyint column, you would get duplicate key errors after you reached id 127.