Hi!

Use SELECT INTO OUTFILE + READ DATA INFILE

Do not rename tables.

Regards,

Heikki

-----Original Message-----
From: Philip Molter <[EMAIL PROTECTED]>
To: Heikki Tuuri <[EMAIL PROTECTED]>
Cc: [EMAIL PROTECTED] <[EMAIL PROTECTED]>
Date: Thursday, January 03, 2002 5:54 PM
Subject: Re: FOREIGN KEYs and ALTER TABLE


>On Thu, Jan 03, 2002 at 05:21:49PM +0200, Heikki Tuuri wrote:
>: mysql> CREATE TABLE parent(id INT NOT NULL, PRIMARY KEY (id))
TYPE=INNODB;
>: Query OK, 0 rows affected (0.11 sec)
>:
>: mysql> CREATE TABLE child(id INT, parent_id INT, INDEX par_ind
(parent_id),
>:     ->                   FOREIGN KEY (parent_id) REFERENCES parent(id))
>: TYPE=INN
>: ODB;
>: Query OK, 0 rows affected (0.03 sec)
>:
>: mysql> insert into parent values (10);
>: Query OK, 1 row affected (0.00 sec)
>:
>: mysql> insert into child values (5, 10);
>: Query OK, 1 row affected (0.00 sec)
>:
>: mysql> drop table parent;
>: Query OK, 0 rows affected (0.01 sec)
>:
>: mysql> CREATE TABLE parent(id INT NOT NULL, PRIMARY KEY (id))
TYPE=INNODB;
>: Query OK, 0 rows affected (0.01 sec)
>:
>: mysql> insert into parent values (10);
>: Query OK, 1 row affected (0.00 sec)
>:
>: mysql> insert into parent values (20);
>: Query OK, 1 row affected (0.01 sec)
>:
>: mysql> insert into child values (6, 20);
>: Query OK, 1 row affected (0.00 sec)
>
>Well, the problem right here with this methodology is that if parent
>is a large table, you have to reinsert all the data back into that
>table.  That may be fine for small tables, but for 100,000 to
>1,000,000+ row tables, that's pretty annoying.
>
>So we make a copy of our data first, so that the reinsertion goes
>much easier.  I do this by simply renaming the table to get it out
>of the way.  Then I make my new table with the same name as my old
>one, insert into it out of my old (renamed) table and then drop
>the renamed.  Thus, I'm sure my data is correct.
>
>The problem appears to be that the child foreign key follows it's
>parent table around even after the rename, so when I create my new
>table with the same name as the old one, the child is no longer
>pointing there.  On first thought, I would expect the child not to
>follow on a rename (because of the explicit pointer to a table
>named 'parent').  On the flip-side, I can see how it might be
>beneficial, but foreign keys in the abstract sense are references
>to keys by table names, not references to keys by table object.
>
>Using this methodology (listed below) should be significantly faster
>if you want to preserve the data in your table.  Using the method
>you detailed, if you wanted to preserve the contents of the table
>being altered, you'd first have to dump your data into a file or
>another temporary table, then reinsert it.
>
>As an aside, the reverse method of this (create the new table,
>populate it with data from the old table, drop the old table, rename
>the new table) also fails on a foreign key constraint.
>
>mysql> create table parent( id INT NOT NULL, PRIMARY KEY (id)) TYPE=InnoDB;
>Query OK, 0 rows affected (0.02 sec)
>
>mysql> create table child( id INT, parent_id INT, INDEX par_ind
(parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id));
>Query OK, 0 rows affected (0.01 sec)
>
>mysql> insert into parent values (10);
>Query OK, 1 row affected (0.00 sec)
>
>mysql> insert into child values (5, 10);
>Query OK, 1 row affected (0.00 sec)
>
>mysql> alter table parent rename parent_temp;
>Query OK, 0 rows affected (0.02 sec)
>
>mysql> create table parent( id INT NOT NULL, id2 INT NOT NULL, PRIMARY KEY
(id)) TYPE=InnoDB;
>Query OK, 0 rows affected (0.01 sec)
>
>mysql> insert into parent select id, 0 FROM parent_temp;
>Query OK, 1 row affected (0.00 sec)
>Records: 1  Duplicates: 0  Warnings: 0
>
>mysql> drop table parent_temp;
>Query OK, 0 rows affected (0.00 sec)
>
>mysql> insert into parent values (20, 0);
>Query OK, 1 row affected (0.00 sec)
>
>mysql> insert into child values (6,20);
>ERROR 1216: Cannot add a child row: a foreign key constraint fails
>mysql> select * from parent;
>+----+-----+
>| id | id2 |
>+----+-----+
>| 10 |   0 |
>| 20 |   0 |
>+----+-----+
>2 rows in set (0.00 sec)
>
>mysql> select * from child;
>+------+-----------+
>| id   | parent_id |
>+------+-----------+
>|    5 |        10 |
>+------+-----------+
>1 row in set (0.00 sec)
>
>* Philip Molter
>* Texas.net Internet
>* http://www.texas.net/
>* [EMAIL PROTECTED]



---------------------------------------------------------------------
Before posting, please check:
   http://www.mysql.com/manual.php   (the manual)
   http://lists.mysql.com/           (the list archive)

To request this thread, e-mail <[EMAIL PROTECTED]>
To unsubscribe, e-mail <[EMAIL PROTECTED]>
Trouble unsubscribing? Try: http://lists.mysql.com/php/unsubscribe.php

Reply via email to