As far as I know, foreign keys can reference candidate keys of tables. Can a compound foreign key also reference a superkey of a table (in case overdefinition is required)? If possible I am interested in how it could be done in mysql workbench.
Related
I'm trying to understand something about the foreign key of a database.
I couldn't find a clear answer for this.
The definition of a foreign key goes something like this,
"Foreign key is a field or a group of fields in a table that refers to the primary key of another table"
OK I get that.
Then we learn about types of relationships we can have among tables using foreign keys.
In one-to-many(1:M) and many-to-many(M:N) relationships, there are duplicates in the foreign key.
But how can this be?
If a foreign key refers to a primary key and a primary key can't have duplicates, how can a foreign key can?
I'm confused.
Can someone please explain this to me?
Note - I'm expecting a common answer, not a DBMS specific one.
For example:
There is an employee table with a primary key column called EmployeeID. There is also a foreign key called SupervisorID, which references a different row in the same table.
Two employees work for the same supervisor. They will have different values in the EmployeeID field, but the same value in the SupervisorID field.
This example uses a reference back to the same table, but the concept is the same when the foreign key references a different table.
What is the difference between Primary and Unique key (in MySQL)? How these can be considered as a foreign key? please explain.
I tried creating a database table and don't know how to make a primary key as a foreign key. Does it take Joins concept where the separating attribute automatically create a foreign key?
A table in MySQL can only have one Primary Key at most, while you can create as many unique Keys or indexes as you want.
Also a primary key is not nullable while a unique key can have NULL as value.
But the biggest difference is the purpose:
You want to have a primary key because you need an identifier
The unique Key/Index on the other hand is usefull to controll values that are automatically getting inserted into your table (e.g. to avoid duplicates where none are allowed)
If you want to use a column as a forgein key, you need to define it as a primary key first. Unique Constraint can not be related with other tables as a foreign key.
Is there any database engine out there that supports multiple primary keys?
And no, I am not asking about multiple fields in a single primary key.
I understand that the engine will have to duplicate the data for each of additional primary keys. That is fine with me.
Has anyone out there implemented that feature?
A set of columns that is unique is a superkey. A superkey that contains no smaller/proper superkey is a CK (candidate key). One CK can be called "the" PK (primary key).
It does not make sense to talk about multiple PKs. Maybe when you say PK you mean CK or superkey (or maybe even some kind of SQL index) but you don't clarify what you mean.
SQL only allows one primary key declaration per table. But it means unique not null. So in relational terms primary key declares a superkey, but not necessarily a CK or PK. (Although a DBMS might treat PKs differently in some other way.) An SQL foreign key must reference columns that are unique not null (maybe via primary key) but in relaational terms that makes it a foreign superkey, not a FK (foreign key).
(When NULLs are involved in SQL other relational terms also don't apply because there is no NULL in relational theory.)
I am having two conflicting definitions of foreign key.
From Wikipedia
the foreign key is defined in a second table, but it refers to the primary key in the first table.
From my lecture notes:
Foreign key does not have to match a primary key but must match a candidate key in some relation
Which is which? Does a foreign key need to reference a primary key or candidate key?
In the relational model of data, a foreign key must reference a candidate key.
In almost all SQL dbms, a foreign key must reference a candidate key.
In MySQL, a foreign key can reference just about anything.
Additionally, MySQL requires that the referenced columns be indexed for performance reasons. However, the system does not enforce a requirement that the referenced columns be UNIQUE or be declared NOT NULL.
Emphasis added.
This is a Bad Thing, IMHO.
The rule that a FK must reference a "primary" key was imposed by the older versions of the SQL standard. That rule has been relaxed by now (and it is now permitted for a FK to reference any candidate key), but it may be the case that some products still go by the old rule, just as it may be the case that some textbooks or other sources have not yet been updated to reflect the new state of affairs.
I don't know precisely when the rule was relaxed in the standard, but imo it must certainly have been no later than 2003.
A foreign key must refer to an unique key (a primary key is unique), because if it doesn't, it cans be the reference of 2 lines, and it's just impossible for a foreign key. Then you can have your primary key, but an unique key who is not a primary key and do a foreign key on it. And your unique key must be NOT NULL
Foreign keys have to be linked to candidate keys because, if join between tables was made using foreign key, the FK linked to an attribute that was not a candidate key could result in multiple values being retrieved where only one value should be retrieved.
Practically, the foreign key has nothing to do with the primary key tag of another table, if it points to a unique column (not necessarily a primary key) of another table then too, it would be a foreign key. So, a correct definition of the foreign key would be:
Foreign keys are the columns of a table that points to the candidate key of another table.
I've been told that if I foreign key two tables, that SQL Server will create something akin to an index in the child table. I have a hard time believing this to be true, but can't find much out there related specifically to this.
My real reason for asking this is because we're experiencing some very slow response time in a delete statement against a table that has probably 15 related tables. I've asked our database guy and he says that if there is a foreign key on the fields, then it acts like an index. What is your experience with this? Should I add indexes on all foreign key fields or are they just unnecessary overhead?
A foreign key is a constraint, a relationship between two tables - that has nothing to do with an index per se.
However, it makes a lot of sense to index all the columns that are part of any foreign key relationship. An FK-relationship will often need to look up a relating table and extract certain rows based on a single value or a range of values.
So it makes good sense to index any columns involved in an FK, but an FK per se is not an index.
Check out Kimberly Tripp's excellent article "When did SQL Server stop putting indexes on Foreign Key columns?".
Wow, the answers are all over the map. So the Documentation says:
A FOREIGN KEY constraint is a candidate for an index because:
Changes to PRIMARY KEY constraints are checked with FOREIGN KEY constraints in related tables.
Foreign key columns are often used in join criteria when the data from related tables is combined in queries by matching the column(s) in the FOREIGN KEY constraint of one table with the primary or unique key column(s) in the other table. An index allows Microsoft® SQL Server™ 2000 to find related data in the foreign key table quickly. However, creating this index is not a requirement. Data from two related tables can be combined even if no PRIMARY KEY or FOREIGN KEY constraints are defined between the tables, but a foreign key relationship between two tables indicates that the two tables have been optimized to be combined in a query that uses the keys as its criteria.
So it seems pretty clear (although the documentation is a bit muddled) that it does not in fact create an index.
No, there is no implicit index on foreign key fields, otherwise why would Microsoft say "Creating an index on a foreign key is often useful". Your colleague may be confusing the foreign key field in the referring table with the primary key in the referred-to table - primary keys do create an implicit index.
Foreign keys do not create indexes. Only alternate key constraints(UNIQUE) and primary key constraints create indexes. This is true in Oracle and SQL Server.
In PostgeSql you can check for indexes yourself if you hit \d tablename
You will see that btree indexes have been automatically created on columns with primary key and unique constraints, but not on columns with foreign keys.
I think that answers your question at least for postgres.
Say you have a big table called orders, and a small table called customers. There is a foreign key from an order to a customer. Now if you delete a customer, Sql Server must check that there are no orphan orders; if there are, it raises an error.
To check if there are any orders, Sql Server has to search the big orders table. Now if there is an index, the search will be fast; if there is not, the search will be slow.
So in this case, the slow delete could be explained by the absence of an index. Especially if Sql Server would have to search 15 big tables without an index.
P.S. If the foreign key has ON DELETE CASCADE, Sql Server still has to search the order table, but then to remove any orders that reference the deleted customer.
SQL Server autocreates indices for Primary Keys, but not for Foreign Keys. Create the index for the Foreign Keys. It's probably worth the overhead.
It depends. On MySQL an index is created if you don't create it on your own:
MySQL requires that foreign key columns be indexed; if you create a table with a foreign key constraint but no index on a given column, an index is created.
Source: https://dev.mysql.com/doc/refman/8.0/en/constraint-foreign-key.html
The same for MySQL 5.6 eh.
Strictly speaking, foreign keys have absolutely nothing to do with indexes, yes. But, as the speakers above me pointed out, it makes sense to create one to speed up the FK-lookups. In fact, in MySQL, if you don't specify an index in your FK declaration, the engine (InnoDB) creates it for you automatically.
Not to my knowledge. A foreign key only adds a constraint that the value in the child key also be represented somewhere in the parent column. It's not telling the database that the child key also needs to be indexed, only constrained.
I notice that Entity Framework 6.1 pointed at MSSQL does automatically add indexes on foreign keys.