MYSQL Update all foreign key values
You can apply ON UPDATE CASCADE
to each table with foreign keys related to TableB.id
in second database temporary:
ALTER TABLE db2.other_tables_with_fk DROP FOREIGN KEY fk_to_TableB;
ALTER TABLE db2.other_tables_with_fk
ADD CONSTRAINT fk_to_TableB FOREIGN KEY (TableB_id)
REFERENCES TableB(id) ON UPDATE CASCADE;
and afterwards use the trick in Sami's Answer and then remove temporary changes like this:
ALTER TABLE db2.other_tables_with_fk DROP FOREIGN KEY fk_to_TableB;
ALTER TABLE db2.other_tables_with_fk
ADD CONSTRAINT fk_to_TableB FOREIGN KEY (TableB_id)
REFERENCES TableB(id);
Then your second database will be ready to merge with the first one.
For MyISM or situations that CASCADE
is not supported by engine you can simulate it manually by defining Triggers:
CREATE TRIGGER trigger1
AFTER UPDATE
ON TableB
FOR EACH ROW
BEGIN
UPDATE other_tables_with_fk1 SET TableB_id = NEW.id WHERE TableB_id = OLD.id
UPDATE other_tables_with_fk2 SET TableB_id = NEW.id WHERE TableB_id = OLD.id
...
END
Even if triggers are not available you can simply increase id number of rows in second database by some custom amount(any amount greater than max row id which used in first database) in all tables including foreign key parent table at a same time:
UPDATE TableB t SET t.id = (t.id + 10000);
UPDATE related_table_1 t SET t.TableB_id = (t.TableB_id + 10000);
UPDATE related_table_2 t SET t.TableB_id = (t.TableB_id + 10000);
...
And then you can merge those databases.
my suggestion were:
- you drop the foreign key constraint of LinkA in database1
- increase the foreign key of the TableA:id AND LinkA:tableA_ID (the best way were with a join) by lets say 1000 (or how much rows you have in database2)
- add the constraint again (optional)
- import TableA and then LinkA to database2 from database1.
If you need more help, just ask.
Best Regards
====================================
Update. Example for the update of the ids:
UPDATE
Table_A, Link_A
SET
Table_A.id = Table_A.id + 1000,
Link_A.id = Link_A.tableA_ID + 1000,
FROM
Table_A JOIN Link_A
ON
Table_A.id = Link_A.tableA_ID
If both db are identical, I believe you should name it db_B.Table_A
not db_B.Table_B
to avoid confusion..but for now I go along with it
--get delta id, use biggest id from db_A and db_B
--to avoid failure because of updating to existing primary key
SELECT @dbBMax := MAX(id) FROM db_B.`Table_B`;
SELECT @dbAMin := MIN(id), @dbAMax := MAX(id) FROM db_A.`Table_A`;
SET @DeltaID := IF(@dbBMax > @dbAMax, @dbBMax, @dbAMax) - @dbAMin + 1;
--drop constraint
ALTER TABLE db_A.`Link_A` DROP FOREIGN KEY `constraint_name_A`;
ALTER TABLE db_A.`Link_B` DROP FOREIGN KEY `constraint_name_B`;
--update ids
UPDATE db_A.`Table_A` SET id = id + @DeltaID;
UPDATE db_A.`Link_A` SET tableA_ID = tableA_ID + @DeltaID;
UPDATE db_A.`Link_B` SET tableA_ID = Link_A.tableA_ID + @DeltaID;
--merge tables
--assume id is auto-increment, don't use auto-increment value,
--so id manually inserted
INSERT INTO db_A.`Table_A`(`id`, `column1`, `column2`,`column3`)
SELECT `id`, `column1`, `column2`,`column3` FROM db_B.`Table_B`;
--assume id is auto-increment, use it, don't insert manually
INSERT INTO db_A.`Link_A`(`column1`, `tableA_ID`)
SELECT `column1`, `tableA_ID` FROM db_B.`Link_A`;
--assume id is auto-increment, use it, don't insert manually
INSERT INTO db_A.`Link_B`(`column1`, `tableA_ID`)
SELECT `column1`, `tableA_ID` FROM db_B.`Link_B`;
This code may add big leap on id
at db_B.Table_B
if db_A.Table_A
have much more data that db_B.Table_B
..that can be fixed easily before/after merge table..but I think its optional..