How does MySQL foreign key work?(Innodb) - mysql

I am using MySQL foreign key in Innodb, I wonder how Mysql enforce foreign key constraint when we insert into the child table. Innodb seems to build index on the foreign key column automatically, How is this feature useful in enforcing the foreign key constraint?
In sum, for normal index, we can create index file, which use the B+ tree structure. What structure is used for a foreign key?

It's an ordinary INDEX. And, in particular, a BTree.
SHOW CREATE TABLE will demonstrate that it is such (and has a fabricated name for the index).

Q: How is this feature [the index on the foreign key column(s) in the child table] useful in enforcing the foreign key constraint?
A: It's useful when an attempt is made to delete a row in the parent table. Or when an attempt is made to update a value in a column that is referenced by a foreign key.
For example, consider an attempt to delete a row in the parent table. The foreign key is a constraint that says: if there are any rows in child table that reference the row in parent table, the delete operation will not succeed and will return an error. (We're assuming for the sake of this example that the foreign key constraint is declared as ON DELETE RESTRICT.)
When a row is deleted from the parent, the child table needs to be checked. Think of performing that check in terms of running a query on the child table, to find out: are there any rows in the child table that reference the row in the parent table. (That is, are they are any rows that have a particular value in the foreign key column?)
If the database wasn't enforcing the constraint, and we were doing the check in the application instead, we would need to run a query something like this:
SELECT 1
FROM child_table
WHERE foreign_key_col = :referenced_key_value
LIMIT 1
And that query would benefit from a suitable index, and index with foreign_key_col as the leading column. Using an index, MySQL can quickly eliminate vast swaths of rows that it knows can't have that value, narrowing in very quickly to the block(s) that would contain a matching row.
For non-trivial sets, using an appropriate index to locate a row is much more efficient than performing a full scan operation, examining every row in the table, to verify there are no rows that match.
In this case, the ideal index ... ON child_table (foreign_key_column), ...)`
In addition to that performance benefit, the database can also use the index to prevent other sessions from inserting a row into child_table (rows that would violate the foreign key constraint), using a lock mechanism. Without an index, the database would need to lock the entire child_table. And that would kill concurrency.
(This is an overly simplified explanation. The actual mechanics are more involved. But this should explain why an index on foreign key columns is "useful". To define a foreign key constraint, InnoDB requires that a suitable index be defined. And if one doesn't exist, InnoDB will create one.
Q: What structure is used for a foreign key?
The same structure used for any other column in the table, or any other index on the table.
A FOREIGN KEY is a constraint. There's nothing "special" about a column used in a foreign key constraint. There is a requirement that the column(s) used in a foreign key constraint must be the leading columns in an index. As explained in the answer to your first question.

Related

If I apply the "UNIQUE" constraint to a column, will the database engine traverse the whole table for an occurrence thus affecting performance?

If I apply the "UNIQUE" constraint to a column, will the database engine traverse the whole table for an occurrence thus affecting performance?
If I have a table with millions of entries, will the engine have to check every field in the column to see if the input matches one of the fields?
How does this work?
No. A unique constraint creates a unique index. The index is used for validating the constraint. The index can also be used for other purposes as well.
As far as I know, all databases, including MySQL, implement such an index using a B-tree. A lookup is O(log(n)) where n is the number of records in the table.
The difference between a unique index and unique constraint is cosmetic. A violation of a unique constraint returns the constraint name; a violation of a unique index returns the index name.

Why InnoDB adds index for foreign key column

MySQL auto adding index when adding foreign key to a column In MySQL with innoDB engine. Primary key is enough for search the rows, how affect the performance by adding index for foreign key column.
Thanks in Advance.
MySQL docs state the reasoning clearly behind this here
MySQL requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist.
There are many queries typically joins which require rows to match on the basis of foreign keys and database has to find those rows. The index typically helps this to do faster.
If you are creating an foreign key means this column will be used to join data with any other tables referenced column, so it is understood that index will be required on this column for better join.
Due to this reason this feature is in build in mysql foreign key concept.

Disable auto indexing of mysql

I understand MySQL is automatically placing an index on every table's primary and foreign keys.
However, I would like to personally create my own indices on the foreign keys as I want to execute a query with hibernate showing the difference in time when I execute it with and without indices.
Is there any option in MySQL Workbench to disable it's auto indexing feature?
No you cannot disable the auto index creation of index on tables. This is a inbuilt feature which is added in MySql.
However if you want you can drop the index like this:
DROP INDEX index_name ON tbl_name
and then create it again.
From InnoDB and FOREIGN KEY Constraints
"InnoDB requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist. (This is in contrast to some older versions, in which indexes
had to be created explicitly or the creation of foreign key
constraints would fail.) index_name, if given, is used as described
previously."
No, these indexes are always created. Otherwise, every UPDATE or INSERT that modifies these columns would have to perform a full table scan, to ensure that the primary key is unique and the foreign key has a valid reference.
Regarding foreign keys, the documentation says:
MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan. In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order. Such an index is created on the referencing table automatically if it does not exist.

What are keys used for in MySQL? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
mySQL's KEY keyword?
Like
PRIMARY KEY (ID),
KEY name (name),
KEY desc (desc),
etc.
what are they useful for?
Keys are used to enforce referential integrity in your database.
A primary key is, as its name suggests, the primary identification of a given row in your table. That is, each row's primary key will uniquely identify that row.
A unique key is a key that enforces uniqueness on that set of columns. It is similar to a primary key in that it will also uniquely identify a row in a table. However, there is the added benefit of allowing NULL in some of those combinations. There can only be 1 primary key, but you can have many unique keys.
A foreign key is used to enforce a relationship between 2 tables (think parent/child table). That way, a child table can not have a value of X in its parent column unless X actually appears in the parent table. This prevents orphaned records from appearing.
The primary key constraint ensures that the column(s) are:
not null
unique (unique sets if more than one column)
KEY is MySQL's terminology in CREATE TABLE statements for an index. Indexes are not ANSI currently, but all databases use indexes to speed up data retrieval (at the cost of insertion/update/deletion, because of maintenance to keep the index relevant).
There are other key constraints:
unique
foreign key (for referential integrity)
...but your question doesn't include examples of them.
keys are also called indexes. They are used for speeding up queries. Additionally keys can be constrains (unique key and foreign key). The primary key is also unique key and it identifies the records. The record can have other unique keys as well, that do not allow to duplicate a value in a given column. Foreign key enforces referential integrity (#Derek Kromm already wrote excellent description). The ordinary key is used only for speeding up queries. You need to index the columns used in the WHERE clause of the queries. If you have no index on the column, MySQL will need to read the whole table to find the records you need. When index is used, MySQL reads only the index (which is usually a B+ tree) and then read only those record from the table it found in the index.
Primary KEY is for creating unique/not null constraint for each row in the table. Also searching by this key is the fastest. You can create only one PK in the table.
Ordinary key/index is key for speeding your searching by this column, sorting, grouping and joining with other table by this key.
Indexes drawback:
Adding new indexes to table will influence on speed or running insert/update/delete statements. So you should select columns for indexing in your table very carefully.
Key are used for relation purposes between tables and you are able to create joins in order to select data from multiple tables
What, you didn't fine the wikipedia entry comprehensive? ;-)
So, a key, in a relational database (such as MySQL, PostgreSQL, Oracle, etc) is a data constraint on a column or set of columns. The most common keys are the Primary key and foreign keys and unique keys.
A foreign key specifically relates the data of one table to data in another table. You might see that a table blog_posts has a foreign key to users based on a user_id column. This means that every user_id in blog_posts will have a corresponding entry in the users column (this is a one-to-many relationship -- a topic for another time).
If a column (or group of columns) has a unique key, that means that there can only be one such incidence of the key in the table. Often you'll see things like email addresses be unique keys -- you only want one email address per user. I've also seen a combination of columns match to a unique key -- the five columns, first_name, last_name, address, city, and state, will often be a unique key -- realistically, there can only be one William Gates at 1835 73rd Ave NE, Medina, Washington. (I do realize that it is possible for a William Gates Jr. to be born, but the designers of that database didn't really care).
The primary key is the primary, unique identifier of a given table. By definition it is a unique key. It is something which cannot be null and must be unique. It holds a special place of prominence among the indexes of a given table.

Does MySQL index foreign key columns automatically?

Does MySQL index foreign key columns automatically?
Yes, but only on innodb. Innodb is currently the only shipped table format that has foreign keys implemented.
Apparently an index is created automatically as specified in the link robert has posted.
InnoDB requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan. In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order. Such an index is created on the referencing table automatically if it does not exist. (This is in contrast to some older versions, in which indexes had to be created explicitly or the creation of foreign key constraints would fail.) index_name, if given, is used as described previously.
InnoDB and FOREIGN KEY Constraints
For those who are looking for quote from 5.7 docs:
MySQL requires indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist. This index might be silently dropped later, if you create
another index that can be used to enforce the foreign key constraint.
index_name, if given, is used as described previously.
You don't get the index automatically if you do an ALTER TABLE (instead of CREATE TABLE), at least according to the docs (the link is for 5.1 but it's the same for 5.5):
[...] When you add a foreign key constraint to a table using ALTER TABLE, remember to create the required indexes first.
As stated it does for InnoDB. At first I thought it was strange that many other (in particular MS SQL and DB2) doesn't. TableSpace scans are only better than index scans when there are very few table rows - so for the vast majority of cases a foreign key would want to be indexed. Then it kind of hit me - this doesn't necessarily mean it has to be a stand alone (one column) index - where it is in MySQL's automatic FK Index. So, may be that is the reason MS SQL, DB2 (Oracle I'm not sure on) etc leave it up to the DBA; after all multiple indexes on large tables can cause issues with performance and space.
Yes, Innodb provide this. You can put a foreign key name after FOREIGN KEY clause or leave it to let MySQL to create a name for you. MySQL automatically creates an index with the foreign_key_name name.
CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name (columns)
REFERENCES parent_table(columns)
ON DELETE action
ON UPDATE action
It's not possible to get index key automatically use
ALTER TABLE (NAME OF THE TABLE) ADD INDEX (FOREIGN KEY)
Name of the table which you have created for example photographs and FOREIGN KEY for example photograph_id. The code should be like this
ALTER TABLE photographs ADD INDEX (photograph_id);