I am trying to create a foreign key.
The columns in both tables are VARCHAR(255) and neither is a PK, however I keep getting this error message:
I can’t figure out how to make a fk out of the topics title and the posts’s topic_title.
Thank you in advance for your help, much needed.
Have a very nice day,
Ana
Only define foreign keys to primary keys. That is simply a best practice.
In order to add a foreign key in MySQL, though, you need to declare the column in the referred table as a primary key, as unique, or using an index. I strongly discourage you from using just any key. At the very least it should be unique. But preferably a primary key.
Related
I'm learning mySQL, still on basic stuff.
My teacher has said that when writing, the best codes have first, all the tables; then, ALTER TABLE queries inserting keys to the tables. That way, we can properly name the keys. I know for sure he does that to foreign keys. He has taught this with primary keys examples as well; however, when providing files with answers for exercises he proposed, he typed the primary keys inside the tables, and later only altered the foreign keys.
How should I do it then? Always insert primary keys inside the tables, alter the foreign keys later? Or should I alter both primary and foreign keys? I'm currently trying to do he latter, and bumping into auto_increment issues for the primary keys.
Thank you for your insight!
You can't rename a primary key, so it makes no sense to do it later in an ALTER statement.
You're running into issues with auto_increment, because an auto_increment column also has to be (part of) the primary key. So you can not specify an auto_increment column but not make it primary key at the same time.
The thing is, this question is actually obsolete, as you can name your foreign keys also when creating the table. Which is for me the way that is prefered. Everything done in one statement. It would look like this:
CREATE TABLE foo (
id int auto_increment primary key,
bar int,
constraint my_fancy_fk_name foreign key (bar) references other_table(whatever_column)
);
I'm new to learning SQL syntax and came across this example in a book. I understand the need for foreign keys and using the constraint function in order to set the key to another table that is created (EMPLOYEE_TBL in this example).
My question is why it listed the line CONSTRAINT EMP_ID_FK FOREIGN KEY (EMP_ID). What exactly is the EMP_ID_FK portion? Since you just need to use the CONSTRAINT function to set a field on you child table to the parent table, couldn't you just write it as CONSTRAINT FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEE_TBL (EMP_ID)); instead?
Am I understanding this incorrectly? Any help would be appreciated. Thanks!
CREATE TABLE EMPLOYEE_PAY_TBL
(EMP_ID CHAR(9) NOT NULL,
DATE_HIRE DATE NULL,
DATE_LAST_RAISE DATE NULL,
CONSTRAINT EMP_ID_FK FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEE_TBL (EMP_ID));
The clause CONSTRAINT EMP_ID_FK simply gives a name to the constraint. This becomes necessary later if you want to disable or drop the constraint. You are correct that the name (EMP_ID_FK) is optional; if you omit it you can also omit the CONSTRAINT keyword, as the clause FOREIGN KEY is enough to tell the interpreter what it is you want.
Naming your constraints is entirely optional but is considered good practice for documentary purposes and in case, as I said, you later need to do something with the constraint. If you omit the name, the database will automagically name the constraint for you, but good luck finding out what that name is.
Put it like this.
Table 1 has to have a reference to Table 2. Table 2 has a Primary Key ID that is a unique value, that means it can be accessed with this ID, as it is unique in all the rows of this table. Now table Table 1 needs to reference to that ID. You need to store that ID in Table 1 so you can reference to it and you know to which Table 2, Table 1 points. You use the naming convention Table2_ID_FK to know that that Field in Table 1 is a reference to the ID of table 2. The constraint is to set the actual relation between these tables.
How many primary keys are possible in a table in MySQL database.
You can't have several of what is called "primary". The answer is: one. A primary key can contain several columns, though. Then it's what you called a "composite primary key"
For this kind of question, you will always find an answer in the manual:
http://dev.mysql.com/doc/refman/5.5/en/create-table.html
You can only have one primary key and it can be composed (or not). Also you can have many unique indexes which are logicaly identical to primary keys (but some functions are not aviable for them)
you should understand primary key as "the" first index of a table, on many RDBMS it is mandatory to have a primary key in order to have other indexes
You can only have one primary key. From the MySQL documentation:
A PRIMARY KEY is a unique index where all key columns must be defined
as NOT NULL. If they are not explicitly declared as NOT NULL, MySQL
declares them so implicitly (and silently). A table can have only one
PRIMARY KEY. If you do not have a PRIMARY KEY and an application asks
for the PRIMARY KEY in your tables, MySQL returns the first UNIQUE
index that has no NULL columns as the PRIMARY KEY.
You posted a comment about composite primary keys. I suggest doing some reading from the MySQL manual to learn about them http://dev.mysql.com/doc/refman/5.5/en/create-table.html. Plus there are question here on SO about composite primary keys you just have to look for them.
One, hence "primary". You can have other "unique" keys/indexes on a table that signify uniqueness in that column/columns (and would likely be referred to as a candidate key).
One.
You can however use several fields to construct the primary key, if that is what you are looking for.
Does a Join table (association table) have a primary key ? many to many relationship. I've seen some Join tables with a primary key and some without can someone please explain when you would have a primary key in a join table and why?
Thank you in advance;-)
In a pure 'join' or junction table all the fields will be part of the primary key. For example let's consider the following tables:
CREATE TABLE USERS
(ID_USER NUMBER PRIMARY KEY,
FIRST_NAME VARCHAR2(32),
LAST_NAME VARCHAR2(32));
CREATE TABLE ATTRIBUTES
(ID_ATTRIBUTE NUMBER PRIMARY KEY,
ATTRIBUTE_NAME VARCHAR2(64));
A junction table between these to allow many users to have many attributes would be
CREATE TABLE USER_ATTRIBUTES
(ID_USER NUMBER REFERENCES USERS(ID_USER),
ID_ATTRIBUTE NUMBER REFERENCES ATTRIBUTES(ID_ATTRIBUTE),
PRIMARY KEY(ID_USER, ID_ATTRIBUTE));
Sometimes you'll find the need to add a non-primary column to a junction table but I find this is relatively rare.
Share and enjoy.
All tables should have a primary key. :-)
You can either use a compound foreign key, or a blind integer key.
You would use the compound foreign key when there are no other elements in your association table.
You could use the blind integer key when the association table has elements of its own. The compound foreign key would be defined with two additional indexes.
It depends on the records you are associating. You can create a composite primary key on the id's of the associated records as long as you don't need multiple records per association.
However, its far more important that you make sure both these columns are indexed and have referential integrity defined.
Relationship tables frequently have three candidate keys, one of which need not be enforced with a constraint, and the choice of which key (if any) should be 'primary' is arbitrary.
Consider this example from Joe Celko:
CREATE TABLE Couples
(boy_name INTEGER NOT NULL UNIQUE -- nested key
REFERENCES Boys (boy_name),
girl_name INTEGER NOT NULL UNIQUE -- nested key,
REFERENCES Girls(girl_name),
PRIMARY KEY(boy_name, girl_name)); -- compound key
The "Couples" table lets you insert
these rows from the original set:
('Joe Celko', 'Brooke Shields')
('Alec Baldwin', 'Kim Bassinger')
Think about this table for a minute.
The PRIMARY KEY is now redundant. If
each boy appears only once in the
table and each girl appears only once
in the table, then each (boy_name,
girl_name) pair can appear only once.
From a theoretical viewpoint, I could
drop the compound key and make either
boy_name or girl_name the new primary
key, or I could just leave them as
candidate keys.
SQL products and theory do not always
match. Many products make the
assumption that the PRIMARY KEY is in
some way special in the data model and
will be the way to access the table
most of the time.
...HOWEVER I suspect you question is implying something more like, "Assuming I'm the kind of person who shuns natural keys in favour of artificial identifiers, should I add an artificial identifier to a table that is composed entirely of artificial identifiers referenced from other tables?"
does it make sense to create indexes for a table called user_movies with the following columns:
user_id
movie_id
There will be much more reading than inserting or updating on this table but I'm not sure what to do. Also: Is it adequate to omit a primary key in this situation?
The correct definition for this table is as follows:
CREATE TABLE user_movies (
user_id INT NOT NULL,
movie_id INT NOT NULL,
PRIMARY KEY (user_id, movie_id),
FOREIGN KEY (user_id) REFERENCES users(user_id),
FOREIGN KEY (movie_id) REFERENCES movies(movie_id)
) ENGINE=InnoDb;
Notice "primary key" is a constraint, not a column. It's best practice to have a primary key constraint in every table. Do not confuse primary key constraint with an auto-generated pseudokey column.
In MySQL, declaring a foreign key or a primary key implicitly creates an index. Yes, these are beneficial.
I would index both columns separately and yes you can eliminate the primary key.
I have always heard that you should create a unique index on BOTH columns, first one way (user_id + movie_id) then the other way (movie_id + user_id). It DOES work slightly faster (not much, about 10-20%) in my application with some quick and dirty testing.
It also makes sure you can't have two rows that tie the same movie_id to the same user_id (which could be good, but perhaps not always).
If you are using such a "join-table", you'll probably use some joins in your queries -- and those will probably benefit from an index on each one of those two columns (which means two separate indexes).