I have a little problem making some foreign keys...
When I try to define the foreign key in MySQL Workbench, I get the following message:
Selected column 'playerName' must be indexed and be of a compatible type for a Foreign Key to be created.
There my problem starts: I'm pretty sure, that the column (towns.playerName) is indexed and it's definitively of the same type ( VARCHAR(255) )...
Indexes of 'towns'
I want to add a Foreign Key from players.name (primary key, not null, unique) to towns.playersName(not null).
So what can I do to get the foreign key created?
It seems i am doing something wrong...
PS: I'm sorry, if there is already a question for this...
EDIT: I just tried again (exactly as I did before several times) and now it works... really strange
Perhaps a bug in MySQL Workbench??
I got the same problem a number of times, but finally found a interesting and useful concept which I missed while learning mysql.
If a column is not a 'key' in the table 1, you cannot add it as foreign key unless it should have an index.
So I make the column a indexed column.
e.g.
CREATE INDEX any_name ON table1 (column1);
finally, I was able to solve my problem.
I believe that the key you are trying to access through the foreign key needs to be a primary key in the other table.
I was getting similar error message. I checked the type of the column in both the tables. It was int in one table whereas varchar in the other table. It should be the same type in both. On using the same type in both the tables, it worked fine.
Related
If I create two tables and I want to set one column as foreign key to another table column why the hell am I allowed to set foreign key column datatype?
It just doesn't make any sense or am I missing something? Is there any scenario where column with foreign keys has different datatype on purpose?
Little more deeper about my concerns, I tried to use pgadmin to build some simple Postgres DB. I made first table with primary key serial datatype. Then I tried to make foreign key but what datatype? I have seen somewhere serial is bigint unsigned. But this option doesn't even exists in pgadmin. Of course I could use sql but then why am I using gui? So I tried Navicat instead, same problem. I feel like with every choice I do another mistake in my DB design...
EDIT:
Perhaps I asked the question wrong way.
I was allowed to do build structure:
CREATE TABLE user
(
id bigint NOT NULL,
CONSTRAINT user_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
CREATE TABLE book
(
user integer,
CONSTRAINT dependent_user_fkey FOREIGN KEY (user)
REFERENCES user (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
I insert some data to table user:
INSERT INTO user(id)
VALUES (5000000000);
But I can't cast following insert:
INSERT INTO book(user)
VALUES (5000000000);
with ERROR: integer out of range which is understandable, but obvious design error.
And my question is: Why when we set CONSTRAINT, data types are not being validated. If I'm wrong, answer should contain scenario where it is useful to have different data types.
Actually it does make sense here is why:
In a table, you can in fact set any column as its primary key. So it could be integer, double, string, etc. Even though nowadays, we mostly use either integers or, more recently, strings as primary key in a table.
Since the foreign key is pointing to another table's primary key, this is why you need to specify the foreign key's datatype. And it obviously needs to be the same datatype.
EDIT:
SQL implementations are lax on this case as we can see: they do allow compatible types (INT and BIG INT, Float or DECIMAL and DOUBLE) but at your own risk. Just as we can see in your example, below.
However, SQL norms do specify that both datatypes must be the same.
If datatype is character, they must have the same length, otherwise, if it is integer, they must have the same size and must both be signed or both unsigned.
You can see by yourself over here, a chapter from a MySQL book published in 2003.
Hope this answers your question.
To answer your question of why you'd ever want different type for a foreign vs. primary key...here is one scenario:
I'm in a situation where an extremely large postgres table is running out of integer values for its id sequence. Lots of other, equally large tables have a foreign key to that parent table.
We are upsizing the ID from integer to bigint, both in the parent table and all the child tables. This requires a full table rewrite. Due to the size of the tables and our uptime commitments and maintenance window size, we cannot rewrite all these tables in one window. We have about three months before it blows up.
So between maintenance windows, we will have primary keys and foreign keys with the same numeric value, but different size columns. This works just fine in our experience.
Even outside an active migration strategy like this, I could see creating a new child table with a bigint foreign key, with the anticipation that "someday" the parent table will get its primary key upsized from integer to bigint.
I don't know if there is any performance penalty with mismatched column sizes. That question is actually what brought me to this page, as I've been unable to find guidance on it online.
(Tangent: Never create any table with an integer id. Go with bigint, no matter what you think your data will look like in ten years. You're welcome.)
So im trying to add an primary key and a foreign key to my table, but i just can't seem to get it to work. i've checked the forums already and other places but it didn't answer my problem. So here is my table:
http://puu.sh/mVW7D/5986e08daa.png
im trying to get VeiederID as my foreing key and keep studentnr as primary
but ive tryied to "alter table" and add the foreing key as constraint, but i might be doing it wrong, im very new to mysql. any help is appirciated
Steffen
Two points:
You do not identify the second table. A foreign key works between two tables and you are only showing one.
You do not specify which mysql version you are using.
Regardless: You should read the manual, reference: v 5.7 Foreign Keys
Update
I see from your updated example you are creating 3 tables and you want the rows in Veileder to reference studentinfo. So, the statement in the Veiled table should be
FOREIGN KEY (VeilederID)
REFERENCES studentinfo(VeiederID)
ON DELETE CASCADE
Apologies if the spelling is wrong. One other note, it appears you are trying to make the primary key (VeilederID) map to the foreign key. If I am wrong please comment but I don't know if that would be allow. Typically a table HAS it's own primary and a reference constrain (a.k.a. FOREIGN KEY) as a different column.
think i found it now i dont get an error while im running it this way, but if its right im not sure..
http://puu.sh/mW1Ze/ae333a40d6.png
A friend of mine just sent me an image of his new api database design.
When I saw it, I noticed that his user table had three primary ids.
I actually thought this wouldn't be possible.
It got me thinking... Is it okay to do this? As long as each column is unique?
I can't seem to find a reason not to do this, except the id is not primary if there are more than one.
Is this a bad database design? And why?
There should be only one column(s) designated as the PRIMARY KEY per table and most DB's will disallow usage of multiple PRIMARY KEYS. Note that a PRIMARY KEY can span multiple columns. Use UNIQUE for other column(s) that require unique values. UNIQUE keys can also be used in foreign key relationships.
is it possible to create a primary key in a existing table on a column that have repeated value? I want is previous record not validate but new record will validate with this.Is it possible in mysql. I know it is possible in Oracle (here is an example) but don't have idea about mysql.
The link you posted as a comment to Nerd-Herd's answer uses deferred constraints. Those constraints are checked at the end of the transaction rather than at the time the statement is executed.
MySQL does not support deferred constraints
If you absolutely need deferred constraints and want to stick with an open source database you will need to migrate to PostgreSQL.
No it can not be. It violates what Primary Key means. But if you want to have a composite primary key, it may be possible
A primary key is always a unique identifier, if you make it non unique it stops being an identifier, why do you want to repeat it? If you have multiple entries that have a field that repeats, that field is not your primary key, however, you can combine it with another field that will give you a primary key (not very recommendable, but you can make this field plus a timestamp field your combined primary key).
In this case what I would recommend is make an autoincrement key and just use this field that repeats as a normal field, maybe ad an index to it to improve searches. You can still look for records on any field, just because it's not your primary key it doesn't mean you are not going to be able to search and get it. The idea of a primary key is that it will get you 1 and only 1 record, not 1 or more.
I have a table with a primary key which is built from three columns. In an other table I would like to reference to them as one single column foreign key. How can this be resolved? Maybe an id alias? Or how can this be resolved?
There is no good way to do this, just use all three as a foreign key. You could introduce an additional unique-values column on the original, and reference that, but it isn't a great approach.