How to create table B like A with foreign key definitions? - mysql

I am able to create table sales_order in database archived_db with the same schema as sales_order table from main database prod_db using below query:
CREATE TABLE archived_db.sales_order LIKE prod_db.sales_order
It is working fine and creating sales_order table in archived_db with same table structure as in prod_db. One thing that is not copied/created is the foreign key.
so, my question is, is it possible to create table B using schema of table A with the same foreign_keys?

You can use this:
SHOW CREATE TABLE prod_db.sales_order
This shows the table definition in the syntax of a CREATE TABLE statement.
Capture the result of this into a string, and then run that string as an SQL statement.
I would suppose that CREATE TABLE <B> LIKE <A> doesn't support foreign keys because foreign keys are a feature that depends on the storage engine. The engine-independent metadata does not store foreign key definitions. This is one of the unexpected consequences of MySQL's strange history and architecture of pluggable storage engines.
Re your comment:
ERROR 1215 (HY000): Cannot add foreign key constraint
Does the parent table exist in the archived db schema in which you are creating the copy table? I imagine the foreign key definition does not qualify the table name, and assumes that the parent table is in the same schema as the sales_order table.
If you need to specify which schema the foreign key references, it's probably best to create the table using CREATE TABLE LIKE as you were before, and then add foreign key(s) using ALTER TABLE.

Related

PHP MyAdmin Altering an existing table to create foreign keys

first post so very sorry if this seems like an obvious answer. Here's the premise of my problem. I have a database I am managing using PhpMyAdmin. I have a table called "Schedules" and want the id of the drivers on the schedule to be a foreign key that references a larger table "Users" where the ID column in this table is a primary key. Here is what i tried:
ALTER TABLE `Schedules`
ADD CONSTRAINT `FK_DriverID`
FOREIGN KEY (`Driver_ID`)
REFERENCES `users`(`ID`);
However, i get this error:
1005 - Can't create table 'Scheduler.#sql-3b7_3b9d' (errno: 150)
(Details…)
I am really at a loss with this error because im not trying to create any tables just alter an existing one. Thanks again and sorry if I butchered the formatting.
This mainly is due to a wrong primary key reference in your table.
Usually this means the key you are referencing does not exist / there might be difference in datatype between the FOREIGN KEY and the REFERENCED column / or there might be difference in column name.
Make sure that
you have a column named ID in users table
Driver_ID column have the same data type as ID column in Users table. Make sure both are exactly of the same data type.
Refer this for more information

Am not able to see foreign keys for any table in my mysql database

New to mysql and have been told by many, that creating foreign keys in mysql is not necessary? how will table relationships be consistent and cascading would be done then? Where can i find info about what foreign key has been created on my mysql tables? desc table_name or show create table_name is not giving any info....
Foreign keys in MySQL work only with InnoDB tables. They do appear in SHOW CREATE TABLE. You might not actually have foreign keys defined, because MySQL silently ignores the column type REFERENCES othertable(column) syntax; only separate FOREIGN KEY (column) REFERENCES othertable(column) foreign key definitions have effect in CREATE TABLE.
Related reading: CREATE TABLE in MySQL docs (search for "inline references specifications")

can't add foreign key in mysql?

I used MySQL workbench to add a foreign key in a table, but some strange error happened, this is the SQL statement:
ALTER TABLE `tansung`.`Declaration` ADD COLUMN `goodsId` INT(11) NOT NULL AFTER `declarationId` ,
ADD CONSTRAINT `goodsId`
FOREIGN KEY (`goodsId` )
REFERENCES `tansung`.`Goods` (`goodsId` )
ON DELETE NO ACTION
ON UPDATE NO ACTION
, ADD INDEX `goodsId` (`goodsId` ASC) ;
When i click apply, the surprise comes out!
ERROR 1005: Can't create table 'tansung.#sql-1b10_1' (errno: 150)
SQL Statement:
ALTER TABLE `tansung`.`Declaration` ADD COLUMN `goodsId` INT(11) NOT NULL AFTER `declarationId` ,
ADD CONSTRAINT `goodsId`
FOREIGN KEY (`goodsId` )
REFERENCES `tansung`.`Goods` (`goodsId` )
ON DELETE NO ACTION
ON UPDATE NO ACTION
, ADD INDEX `goodsId` (`goodsId` ASC)
ERROR: Error when running failback script. Details follow.
ERROR 1050: Table 'Declaration' already exists
SQL Statement:
CREATE TABLE `Declaration` (
`declarationId` int(11) NOT NULL,
PRIMARY KEY (`declarationId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
I can't find out any mistake in logic, even can't understand the error, please give me a help.
All foreign key names throughout the database must be unique. If you already have a foreign key named 'goodsId', even on another table, you will receive this error.
If the related columns do not have exactly the same type (e.g. INT) and constraints (UNIQUE and such), you will receive that error.
It can happen because of many reasons. Following are some of the common reasons. You can also say syntactical errors, because of which these kinds of error are thrown.
If the FK (Foreign Key) table Engine is using MyISAM and PK (Primary Key) table Engine is using InnoDB. MyISAM does not support foreign key constraints. So, you might want to converting your linking table to InnoDB.
All foreign key names throughout the database must be unique. If you already have a foreign key constraint with the same name, even on another table, you will receive this error.
If the related columns do not have exactly the same data typetype (e.g. INT) and constraints (UNIQUE and such), you will receive that error.
I'm getting this error when the table being linked to (in your case, Goods) is stored using MyISAM, and the table you're adding the index to (in your case, Declarations) is stored using InnoDB.
You can tell this from the files in the database directory. MyISAM tables will have files like:
table_name.frm
table_name.MYD
table_name.MYI
The InnoDB table will just have:
table_name.frm
MyISAM does not support foreign key constraints. I would suggest converting your Goods table to InnoDB (though, have a look at the documentation first and do some basic research):
ALTER TABLE Goods ENGINE=INNODB;
After making this change, my ADD INDEX operation completed successfully.
Like the others have said, first make sure the types of the two columns are the same and the database supports it. After that, make sure that the columns that hold the keys to the other tables are valid.
I had a problem where I was adding the constraint to an existing column with data in it, and that data didn't match any of the primary keys in the other table so the attempt to create the relationship would fail. Fixing it involved updating all the columns to make sure my column data matched up with the constraint I was trying to make.
I discovered that when trying to do this in phpMyAdmin that tables that had a hyphen in the name would only allow one FK and then give errors. I have no idea why but it was easy enough to work around I simply remade the
CREATE TABLE `something_new` LIKE `something-old`;
DROP TABLE `something-old`;
YMMV.
The type definitions of Goods.goodsId and Declarations.goodsId must be identical, or you will get the errno: 150.
Make sure they are both the same data type, which looks to be goodsId INT(11) NOT NULL in the Declarations table. What is the CREATE TABLE statement for Goods?
I had the same problem. It seems that there was some data in the child table that was not present in the parent table. You can do an outer join to see the differences and you can assign a valid id for non-matching rows or delete them:
DELETE FROM books
WHERE NOT EXISTS (
SELECT * FROM users
WHERE books.user_id = users.id
)
Errno 150 has a lot of causes. If you have SUPER privileges, you should try using
SHOW ENGINE INNODB STATUS
and that will tell you what the cause was. If you don't have SUPER privileges, you need to just go through all the possible causes. You can find how to use the SHOW INNODB STATUS and a list of all the causes here:
MySQL Foreign Key Errors and Errno 150
When I got that error it was becuase I was trying to update a table that already had data int it and the data didn't meet the FK restrictions.
A fourth possible problem (to the three proposed by abhijitcaps) is that you didn't make the column you are referencing to a primary key.

MySQL FK syntax: insert column called practice into table cred_insurances that is FK to table practices

I need to insert a column called "practice" into table "cred_insurances" that is a FK referencing table "practices" PK "id"
You will need to ensure that your MySQL table is using the InnoDB engine, by running the following from the mysql prompt.
show create table cred_insurances
the output will include (towards the bottom) the text ENGINE=.... If it is not InnodDB, then you will first need to convert it using the following SQL. You may need to do this to the parent table as well.
ALTER TABLE cred_insurances ENGINE=InnoDB
Then you can add a column and a foreign key constraint with the following command:
ALTER TABLE cred_insurances
ADD practice INT,
ADD CONSTRAINT fk_practice
FOREIGN KEY (practice) REFERENCES practices (ID)
If you are having difficulties with errors whilst adding a foreign key, try the following command to get more detailed information on the error.
SHOW ENGINE INNODB STATUS

Setting up foreign keys in phpMyAdmin?

I'm setting up a database using phpMyAdmin. I have two tables (foo and bar), indexed on their primary keys. I am trying to create a relational table (foo_bar) between them, using their primary keys as foreign keys.
I created these tables as MyISAM, but have since changed all three to InnoDB, because I read that MyISAM doesn't support foreign keys. All id fields are INT(11).
When I choose the foo_bar table, click the "relation view" link, and try to set the FK columns to be database.foo.id and database.bar.id, it says "No index defined!" beside each column.
What am I missing?
Clarification/Update
For the sake of simplicity, I want to keep using phpMyAdmin. I am currently using XAMPP, which is easy enough to let me focus on the PHP/CSS/Javascript, and it comes with phpMyAdmin.
Also, although I haven't been able to set up explicit foreign keys yet, I do have a relational table and can perform joins like this:
SELECT *
FROM foo
INNER JOIN foo_bar
ON foo.id = foo_bar.foo_id
INNER JOIN bar
ON foo_bar.bar_id = bar.id;
It just makes me uncomfortable not to have the FKs explicitly defined in the database.
If you want to use phpMyAdmin to set up relations, you have to do 2 things. First of all, you have to define an index on the foreign key column in the referring table (so foo_bar.foo_id, in your case). Then, go to relation view (in the referring table) and select the referred column (so in your case foo.id) and the on update and on delete actions.
I think foreign keys are useful if you have multiple tables linked to one another, in particular, your delete scripts will become very short if you set the referencing options correctly.
EDIT: Make sure both of the tables have the InnoDB engine selected.
phpMyAdmin lets you define foreign keys using their "relations" view. But since, MySQL only supports foreign constraints on "INNO DB" tables, the first step is to make sure the tables you are using are of that type.
To setup a foreign key so that the PID column in a table named CHILD references the ID column in a table named PARENT, you can do the following:
For both tables, go to the operations tab and change their type to "INNO DB"
Make sure ID is the primary key (or at least an indexed column) of the PARENT table.
In the CHILD table, define an index for the PID column.
While viewing the structure tab of the CHILD table, click the "relation view" link just above the "add fields" section.
You will be given a table where each row corresponds to an indexed column in your CLIENT table. The first dropdown in each row lets you choose which TABLE->COLUMN the indexed column references. In the row for PID, choose PARENT->ID from the dropdown and click GO.
By doing an export on the CHILD table, you should see a foreign key constraint has been created for the PID column.
This is a summary of a Wikipedia article. It specifies the different types of relationships you can stipulate in PHPmyadmin. I am putting it here because it is relevant to #Nathan's comment on setting the foreign keys options for "on update/delete" but is too large for a comment.
CASCADE
Whenever rows in the master (referenced) table are deleted (resp. updated), the respective rows of the child (referencing) table with a matching foreign key column will get deleted (resp. updated) as well. This is called a cascade delete (resp. update[2]).
RESTRICT
A value cannot be updated or deleted when a row exists in a foreign key table that references the value in the referenced table. Similarly, a row cannot be deleted as long as there is a reference to it from a foreign key table.
NO ACTION
NO ACTION and RESTRICT are very much alike. The main difference between NO ACTION and RESTRICT is that with NO ACTION the referential integrity check is done after trying to alter the table. RESTRICT does the check before trying to execute the UPDATE or DELETE statement. Both referential actions act the same if the referential integrity check fails: the UPDATE or DELETE statement will result in an error.
SET NULL
The foreign key values in the referencing row are set to NULL when the referenced row is updated or deleted. This is only possible if the respective columns in the referencing table are nullable. Due to the semantics of NULL, a referencing row with NULLs in the foreign key columns does not require a referenced row.
SET DEFAULT
Similar to SET NULL, the foreign key values in the referencing row are set to the column default when the referenced row is updated or deleted.
In phpmyadmin, you can assign Foreign key simply by its GUI. Click on the table and go to Structure tab. find the Relation View on just bellow of table (shown in below image).
You can assign the forging key from the list box near by the primary key.(See image below). and save
corresponding SQL query automatically generated and executed.
For those new to database .... and need to ALTER an existing table. A lot things seem to be pretty straightforward, but there is always something ... between A and B.
Before anything else, take a look at this.
Make sure you have P_ID (parent ID on both parent and child table).
Of course it will be already filled in the parent. Not necessarily in the child in a true and final way. So for instance P_ID #3 (maybe many times in the child table will be pointing to original P_ID at parent table).
Go to SQL tab (I am using phpMyAdmin, should be similar in other ones) and do this command:
ALTER TABLE child_table_name
ADD FOREIGN KEY (P_ID)
REFERENCES parent_table_name (P_ID)
Click on child table, than structure, finally on relational view. Finish your DB planning there. There was a nice answer before this one about cascade, restrict, etc.
Of course it could be done by commands...
Foreign key means a non prime attribute of a table referes the prime attribute of another
*in phpMyAdmin* first set the column you want to set foreign key as an index
then click on RELATION VIEW
there u can find the options to set foreign key
InnoDB allows you to add a new foreign key constraint to a table by using ALTER TABLE:
ALTER TABLE tbl_name
ADD [CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (index_col_name, ...)
REFERENCES tbl_name (index_col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]
On the other hand, if MyISAM has advantages over InnoDB in your context, why would you want to create foreign key constraints at all. You can handle this on the model level of your application. Just make sure the columns which you want to use as foreign keys are indexed!
Don't forget that the two columns should have the same data type.
for example if one column is of type INT and the other is of type tinyint you'll get the following error:
Error creating foreign key on [PID column] (check data types)
This is old thread but answer because if useful to anyone.
Step 1. Your Db Storage Engine set to InnoDB
Step 2. Create Primary Table
here customer is primary table and customer_id is primary key
Step 3. create foreign key table and give index
here we have customer_addresses as related table and store customer addresses, so here customer_id relation with customer table
we can select index directly when create table as below
If you forgot to give index when create a table, then you can give index from the structure tab of table as below.
Step 4. Once index give to the field, Go to structure tab and click on Relation View as shown in below pic
Step 5. Now select the ON DELETE and ON UPDATE what you want to do, Select column from current table, select DB (SAME DB), select relation table and primary key from that table as shown in below pic and Save it
Now check if relation are give successfully, go to foreign table data list and click on foreign key value, you will redirect to primary table record, then relation made successfully.
Make sure you have selected your mysql storage engine as Innodb and not MYISAM as Innodb storage engine supports foreign keys in Mysql.
Steps to create foreign keys in phpmyadmin:
Tap on structure for the table which will have the foreign key.
Create INDEX for the column you want to use as foreign key.
Tap on Relation view, placed below the table structure
In the Relation view page, you can see select options in front of the field (which was made an INDEX).
UPDATE CASCADE specifies that the column will be updated when the referenced column is updated,
DELETE CASCADE specified rows will be deleted when the referenced rows are deleted.
Alternatively, you can also trigger sql query for the same
ALTER TABLE table_name
ADD CONSTRAINT fk_foreign_key_name
FOREIGN KEY (foreign_key_name)
REFERENCES target_table(target_key_name);
Step 1:
You have to add the line:
default-storage-engine = InnoDB
under the [mysqld] section of your mysql config file (my.cnf or my.ini depending on your OS) and restart the mysqld service.
Step 2:
Now when you create the table you will see the type of table is: InnoDB
Step 3:
Create both Parent and Child table. Now open the Child table and select the column U like to have the Foreign Key:
Select the Index Key from Action Label as shown below.
Step 4:
Now open the Relation View in the same child table from bottom near the Print View as shown below.
Step 5:
Select the column U like to have the Foreign key as Select the Parent column from the drop down.
dbName.TableName.ColumnName
Select appropriate Values for ON DELETE and ON UPDATE
First set Storage Engine as InnoDB
then the relation view option enable in structure menu
You can also do it with a SQL command, like so.
ALTER TABLE employees
ADD CONSTRAINT fk_companyid FOREIGN KEY (companyid)
REFERENCES companies (id)
ON DELETE CASCADE;
In this example, if a row from companies is deleted, all employees with that companyid are also deleted.
From the official MySQL documentation at https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html:
MySQL requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan.