Lets say I need to create two tables which both refer to each other (they need constraints). Is the only way to create the tables without the constraints, and then add them in a separate statement? I remember that some orms can solve this themselves, but is it possible to do this only using sql and in two statements?
You should must create the tables first without foreign keys and append them after both tables are created:
create table t1 (id int not null primary key, id2 int not null);
create table t2 (id int not null primary key, id1 int not null);
alter table t1 add foreign key (id2) references t2(id);
alter table t2 add foreign key (id1) references t1(id);
Good news: A schema dump works perfect (so is my database):
mysqldump -u root so t1 t2 | mysql -u root so
This gives no errors because mysqldump inserts DISABLE KEYS and ENABLE KEYS at the right places.
Related
Currently, I have two configuration tables that stores two different kinds of configurations, however, both have an ID column. I have one table called Deactivation. Any configuration I want to deactivate I can add ID of that configuration table into this table.
Structure of the database is as follow.
My question is Can I create two FK constraints that refer,
- ID (FK) to T1_ID (PK)
- ID (FK) to T2_ID (PK)
(single child to multiple parents)
So, deactivation table should not be allowed insertion of any id which is not in either T1 or T2. But If ID found in any of that table insertion should be done.
Thanks
I think you've got your answer already, from the comments, but here as a direct statement:
Relational databases Foreign/Primary key mechanism is not intended to maintain and enforce this kind of relationship between tables. You'll have to do something custom with a trigger on Deactivations, that checks the value being inserted into Deactivations is present in T1 or T2 and permits the insert if it is/rejects it if not.
You'll also have to consider coding up something in T1 and T2 to deal with updates/deleted (cascade them?) and collisions (what if T1 id = 1 and T2 id = 2, but then you change T2 ID to also be 1? What if an ID present in T1, representing one thing, is inserted into T2 representing a different thing? Does the new thing in T2 automatically become deactivated? Does my phone stop working because someone stopped paying their contract on their tablet?)
I think your relationship is backwards. Basically, you want deactivations (or some other table) to have the primary key. Then, this can be shared among the other tables:
create table deactivations (
deactivationId int auto_increment primary key,
. . .
);
create table config1 (
config1Id int primary key,
. . .
constraint fk_config1_config1Id foreign key (config1Id) references deactivations(deactivationId)
);
create table config2 (
config2Id int primary key,
. . .
constraint fk_config2_config2Id foreign key (config2Id) references deactivations(deactivationId)
);
This is not 100% what you need, because a deactivationId could be shared between the two tables. There are ways around this, but alas in MySQL, such a check requires triggers.
If you still want to go with your solution, you can use a generated column:
create table deactivations (
config1Id int,
config2Id int,
id int generated always as (coalesce(config1Id, config2Id)),
constraint fk_deactivations_config1Id as foreign key (config1Id) references config1(config1Id),
constraint fk_deactivations_config2Id as foreign key (config2Id) references config2(config2Id)
);
Unfortunately, MySQL does not support check constraints, so you require a trigger to guarantee that exactly one but not both of the ids are not null.
I am trying to set up a bunch of foreign key's in MySQL Workbench. It all seems to be working fine except that when I reverse engineer the EER diagram the relationship is always coming up as one to many rather than one to one. For my purposes I need to establish both types in different tables and I was wandering what I can do to control the type of relationship when I set up the foreign key.
Sorry if I am completely missing something obvious / basic but I am a beginner at this. Below I have included a screen shot of my current set-up of a foreign key that I want to result in a one to one relationship but is currently giving me a one to many. All help is greatly appreciated.
A 1:1 relationhip can be defined as follows
CREATE TABLE Table1
(
ID INT PRIMARY KEY,
Name VARCHAR(255)
);
CREATE TABLE Table2
(
ID INT PRIMARY KEY,
OtherDetails VARCHAR(255),
FOREIGN KEY (ID) REFERENCES Table1(ID)
);
To insert a record into Table2, the ID value must be present in Table1 (the Table2 foreign key constraint enforces this) and can only be added to Table2 once (Primary key constraint enforces this)
I am in the process of designing the databases for my system. There are a lot of foreign key constraints.
I was wondering whether I could get some advice, whether I should do which of the following:
1) Specify the constraints during table creation itself ie,
CREATE TABLE IF NOT EXISTS abc
(
keyword VARCHAR(20) NOT NULL,
id INT UNSIGNED NOT NULL,
FOREIGN KEY (id) REFERENCES xyz(id) ON DELETE CASCADE ON UPDATE CASCADE
)ENGINE=InnoDB;
2)create the table without FK constraints and 'alter' the table later on ie,
CREATE TABLE IF NOT EXISTS abc
(
keyword VARCHAR(20) NOT NULL,
id INT UNSIGNED NOT NULL,
)ENGINE=InnoDB;
ALTER TABLE abc ADD CONSTRAINT fk_constraint FOREIGN KEY (id) REFERENCES xyz(id)
ON DELETE CASCADE ON UPDATE CASCADE;
Table xyz is simply another table with 'id' as a primary key.
You may create the FK at once. But this is not always possible because they can refer to each other in a circular fashion. Also, you may want to add columns later, with a FK.
It may be slightly faster to add it at once, because MySQL has to validate and rebuild the table structure for some changes (although I'm not sure adding FKs is one of those). But this process will be reasonably fast on empty tables, so it doesn't matter much when you add the FK.
The result will be the same. So, there is no differences.
If I create new database, I'd create table and its foreign key in one statement. The script will look better. But in this case parent tables must be created before the child tables.
If you don't want to take into account dependencies when creating tables, you can create tables in random order in the beginning of the script and then add foreign keys using ALTER TABLE.
I am setting up a table in mysql of engine type merge in mysql and was wondering if i have to have all my tables created previously that i want to merge. For example:
CREATE TABLE t1 (
a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
message CHAR(20)) ENGINE=MyISAM;
CREATE TABLE t2 (
a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
message CHAR(20)) ENGINE=MyISAM;
INSERT INTO t1 (message) VALUES ('Testing'),('table'),('t1');
INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2');
CREATE TABLE total (
a INT NOT NULL AUTO_INCREMENT,
message CHAR(20), INDEX(a))
ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
Now if i have code that automatically created a t3 table i would have to modify the merge table to add this to the union? Would i use an ALTER query for that?
note: i am not using MySQL partitions because i have a mysql version 5.0.
Now if i have code that automatically created a t3 table i would have to modify the merge table to add this to the union? Would i use an ALTER query for that?
From the documentation:
To remap a MERGE table to a different collection of MyISAM tables, you can use one of the following methods:
DROP the MERGE table and re-create it.
Use ALTER TABLE tbl_name UNION=(...) to change the list of underlying tables.
Beginning with MySQL 5.0.60, it is also possible to use ALTER TABLE ... UNION=() (that is, with an empty UNION clause) to remove all of the underlying tables.
I have a script in MySQL that creates two tables, the second table references a field in the first table, now when I try to run this script in one batch it returns an error. My guess is that it checks the referenced table in the second table definition before creating the tables.
Any idea how I can create both tables at once?
Thanks
Edit:
Example:
CREATE TABLE table1
(
ID INT NOT NULL,
PRIMARY KEY (ID)
) ENGINE=InnoDB;
CREATE TABLE table2
(
ID INT NOT NULL,
FID INT NOT NULL ,
PRIMARY KEY (ID),
FOREIGN KEY (FID) REFERENCES table1 (ID)
) ENGINE=InnoDB;
If I create the first table, then create the second table everything works fine, but when I run this in one batch it returns an error
Update:
It seems that this problem has been solved with MySQL 5.5. It now works correctly in one batch even if you have foreign key constraints in some table definitions.
the simple thing , to create first the 2 tables,
after that do alter table and add the reference.