Search code examples
phpmysqldatabaseduplicationdatabase-relations

Duplicate tables having N:M relationship (including relationship)


Working on an existing webapp (PHP/MySQL) I came to this point: I have 2 tables storing names and types id. The relation between them being N<---->N I have another table in between. (see picture)

Tables names and columns have been simplified, but it's pretty much it

I have a last table called "category" which is unpictured. What I have to do is: duplicate contracts and customers having id_category=1 to contracts and customers with same values, having id_category=3. As well as duplicating the relations between them.

So far I've managed to duplicate all contracts and customers apart, using:

INSERT INTO contract (t_name, id_category) SELECT t_name,'3' WHERE id_category=2
INSERT INTO customer (t_name, id_category) SELECT t_name,'3' WHERE id_category=2

(The "id" field being Auto-Incremented, it goes fine).

But about copying the relations, I can't figure out HOW to take the problem.

Additional info:

  • Using temporary tables is fine, but I can't modify the existing structure of tables.
  • Contracts may have from 0 to N customers. Customers may have from 0 to N contracts.
  • I can use either strict MySQL, or with PHP.

Solution

  • You say you can't change the table structure. If you could, I would likely recommend against the denormalization (duplication of rows) of these tables depending upon what you are doing.

    I'm also a bit confused because you say you have to duplicate the rows and relations with id_category = 1 to id_category = 3, but then your sample queries have id_category = 2.

    This answer should apply regardless, though. I would use PHP and PDO.

    $pdo = new PDO('mysql:host=?', $user, $passwd);
    $stmtCustomers = $pdo->prepare("INSERT INTO customer (t_name, id_category)
       VALUES (t_name, ?) WHERE id_category = ?");
    $stmtContracts = $pdo->prepare("INSERT INTO contract (t_name, id_category)
       VALUES (t_name, ?) WHERE id_category = ?");
    $stmtRelation = $pdo->prepare("INSERT INTO customer_has_contract VALUES (?, ?)");
    
    //Perform in a loop if needed
    $pdo->beginTransaction();
    $stmtCustomers->execute($target_cat_id, $origin_cat_id);
    $cus_id = $pdo->lastInsertId();
    $stmtContracts->execute($target_cat_id, $origin_cat_id);
    $con_id = $pdo->lastInsertId();
    $stmtRelation->execute($con_id, $cus_id);
    $pdo->commit();