I have a table which has a "foreign key" referencing itself. This would be very useful, except I am uncertain how to add the first record to such a table. No matter what I add, I cannot provide a valid "foreign" key to the table itself, having no entries yet. Maybe I'm not going about this correctly, but I want this table to represent something that is always a member of itself. Is there a way to "bootstrap" such a table, or another way to go about self-reference?
+2
A:
One option is to make your field NULL
-able, and set the root record's parent key to NULL
:
CREATE TABLE tb_1 (
id int NOT NULL PRIMARY KEY,
value int NOT NULL,
parent int NULL,
FOREIGN KEY (parent) REFERENCES tb_1(id)
) ENGINE=INNODB;
Query OK, 0 rows affected (0.43 sec)
-- This fails:
INSERT INTO tb_1 VALUES (1, 1, 0);
ERROR 1452 (23000): A foreign key constraint fails.
-- This succeeds:
INSERT INTO tb_1 VALUES (1, 1, NULL);
Query OK, 1 row affected (0.08 sec)
Otherwise you could still use a NOT NULL
parent key and point it to the root record itself:
CREATE TABLE tb_2 (
id int NOT NULL PRIMARY KEY,
value int NOT NULL,
parent int NOT NULL,
FOREIGN KEY (parent) REFERENCES tb_2(id)
) ENGINE=INNODB;
Query OK, 0 rows affected (0.43 sec)
-- This fails:
INSERT INTO tb_2 VALUES (1, 1, 0);
ERROR 1452 (23000): A foreign key constraint fails.
-- This succeeds:
INSERT INTO tb_2 VALUES (1, 1, 1);
Query OK, 1 row affected (0.08 sec)
Daniel Vassallo
2010-06-04 04:56:31
If I were to use the second approach, (tb_2), how could I know for sure what number to use for the third parameter?
Joshua
2010-06-04 18:50:35
@Joshua: The third parameter is the same as the first parameter (for the root record). That is, the `parent_id` of the root record is the same as its `id`. Then for other rows, simply reference the appropriate `parent_id` normally.
Daniel Vassallo
2010-06-05 04:35:44