Can a foreign key reference a non-unique index?
From MySQL documentation:
InnoDB allows a foreign key constraint to reference a non-unique key. This is an InnoDB extension to standard SQL.
However, there is a pratical reason to avoid foreign keys on non-unique columns of referenced table. That is, what should be the semantic of "ON DELETE CASCADE" in that case?
The documentation further advises:
The handling of foreign key references to nonunique keys or keys that contain NULL values is not well defined (...) You are advised to use foreign keys that reference only UNIQUE (including PRIMARY) and NOT NULL keys.
Your analysis is correct; the keys don't have to be unique, and constraints will act on the set of matching rows. Not usually a useful behavior, but situations can come up where it's what you want.
Yes, you can create foreign keys to basically any column(s) in any table. Most times you'll create them to the primary key, though.
If you do use foreign keys that don't point to a primary key, you might also want to create a (non-unique) index to the column(s) being referenced for the sake of performance.
Depends on the RDBMS you're using. I think some do this for you implicitly, or use some other tricks. RTM.
When this happens, it usually means that two foreign keys are being linked to each other. Often the table that would contain the key as a primary key isn't even in the schema.
Example: Two tables, COLLEGES and STUDENTS, both contain a column called ZIPCODE.
If we do a quick check on
SELECT * FROM COLLEGES JOIN STUDENTS ON COLLEGES.ZIPCODE = STUDENTS.ZIPCODE
We might discover that the relationship is many to many. If our schema had a table called ZIPCODES, with primary key ZIPCODE, it would be obvious what's really going on.
But our schema has no such table. Just because our schema has no such table doesn't mean that such data doesn't exist, however. somewhere, out in USPO land, there is just such a table. And both COLLEGES.ZIPCODE and STUDENTS.ZIPCODE are references to that table, even if we don't acknowledge it.
This has more to do with the philosophy of data than the practice of building databases, but it neatly illustrates something fundamental: the data has characteristics that we discover, and not only characteristics that we invent. Of course, what we discover could be what somebody else invented. That's certainly the case with ZIPCODE.