This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
MySQL Relationships
I am trying to create a one to many relationship in MySQL with foreign keys.
Two tables, user and location. Each user can have many locations, but each location can have only one user.
How do I configure this? I am using HeidiSQL if that helps, though I can input code as well.
MySQL does not know, nor does it need to know if a relationship is 1-1, or 1-many.
No SQL supports many-many relationships, all require a intermediate table which splits a many-many relationship into 2 separate 1-many.
The difference is in the logic that controls the relationships, which is in the code that you write.
A 1-1 relationship is maintained by having the tables share the same primary key (PK).
With the secondary table declaring that PK as a foreign key pointing to the other tables PK.
Table chinese_mother (
id integer primary key,
name....
Table chinese_child (
id integer primary key,
name ....
....,
foreign key (id) references chinese_mother.id
The direction of the relationship 1 -> many vs many <- 1 is determined by the location of the link field.
Usually every table has a unique id and the link field is called tablename_id.
The table that has the link field in it is the many side of the relationship, the other table is on the 1 side.
Each user can have many locations, but each location can have only one user.
Table user
id: primary key
name......
.....
Table location
id: primary key
user_id foreign key references (user.id)
x
y
.......
By placing the link field in the location table, you force things so that a location can only have 1 user. However a user can have many locations.
There is an example here that is almost exactly what you need foreign keys in innodb
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child (
id INT,
parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE
) ENGINE=INNODB;
In your example user is the same as parent (a user has many locations, a parent has many childs) and location is the same as child (a location has one user, a child has one parent)
Related
Lets say I have table A with two junction tables B and C, how would I go about creating primary keys for table A? I have two of these types of table in a diagram I drew, the circle keys are foreign keys btw.
Image with junction tables
Your games table needs only one primary key: this identifies each specific game. In the junction tables, the primary keys are composed of the game primary key and the directors (or types) primary key.
Taken from the reference in the tutorial MySQL Primary Key:
CREATE TABLE roles(
role_id INT AUTO_INCREMENT,
role_name VARCHAR(50),
PRIMARY KEY(role_id)
);
It is difficult to provide information about your specific question because there is too little details in it.
From your comment "if a table has two junction tables attached to it, would it need to have two primary keys?". No.
A primary key is actually a logical concept (a design mechanism) used to define a logical model. A primary key is a set of attributes (columns) that together uniquely identify each end every Tuple (row) in a relation (table). One of the rules of a primary key is that there is only one per relation.
The logical model is used, as mentioned, as the design to create the physical model, relations become tables, attributes become columns, Primary keys may become unique indexes. Foreign Keys may become indexes in the related table and so on.
Many RDBMS's allow the specification of a PRIMARY KEY in a physical table definition. Most also allow definition of FOREIGN KEYs on a physical table also. What they do with them may vary from one implementation to another. Many use the definition of a PRIMARY KEY to define a UNIQUE INDEX of some sort to enforce the "must uniquely identify" each and every record in the table.
So, No, your games_directors table does not need, nor can it have, two primary keys. if you did choose to specify a PRIMARY KEY, you would need to specify all the columns that uniquely identify records in the games_directors table - most likely PRIMARY KEY (game_id, director_id).
Similarly, the PRIMARY KEY for the games table would likely be PRIMARY KEY (game_id), for the directors would likely be PRIMARY KEY (director_id) and for game types it would likely be PRIMARY KEY (game_type_id).
You might use a foreign key from your games_directors table to ensure that when records are added to it that the corresponding director exists in the games table and the directors table. In this case, your games_directors table will have two foreign key relationships (one to games and another to directors). But only one PRIMARY KEY.
So you might end up with something like this:
create table games (
game_id integer,
PRIMARY KEY (game_id)
);
create table directors (
director_id integer,
PRIMARY KEY (director_id)
);
CREATE TABLE games_directors (
game_id INTEGER NOT NULL,
director_id INTEGER NOT NULL,
commission_paid DECIMAL(10,2),
PRIMARY KEY (game_id, director_id),
FOREIGN KEY (game_id) REFERENCES games(game_id),
FOREIGN KEY (director_id) REFERENCES directors(director_id)
);
NB: I didn't tested the above using PostgreSql. The syntax should work for most RDBMS's, but some may require tweaking slightly.
Indexes can be used to speed up access to individual records within table. For example, you might want to create an index on director name or director id (depending upon how you most frequenytly access that table). If you mostly access the director table with an equality condition like this : where director_name = 'fred' then an index on director_name might make sense.
Indexes become more useful as the number of records in the tables grows.
I hope this answers your question. :-)
I am trying to set up a bunch of foreign key's in MySQL Workbench. It all seems to be working fine except that when I reverse engineer the EER diagram the relationship is always coming up as one to many rather than one to one. For my purposes I need to establish both types in different tables and I was wandering what I can do to control the type of relationship when I set up the foreign key.
Sorry if I am completely missing something obvious / basic but I am a beginner at this. Below I have included a screen shot of my current set-up of a foreign key that I want to result in a one to one relationship but is currently giving me a one to many. All help is greatly appreciated.
A 1:1 relationhip can be defined as follows
CREATE TABLE Table1
(
ID INT PRIMARY KEY,
Name VARCHAR(255)
);
CREATE TABLE Table2
(
ID INT PRIMARY KEY,
OtherDetails VARCHAR(255),
FOREIGN KEY (ID) REFERENCES Table1(ID)
);
To insert a record into Table2, the ID value must be present in Table1 (the Table2 foreign key constraint enforces this) and can only be added to Table2 once (Primary key constraint enforces this)
I have an access database which contains 23 tables.
There is one Main table which houses all test equipment and contains
columns headers 4-26. The other 22 tables are used to house the equipment related to a section (4-26).
What I've been trying to do is setup relationships between each section table to the Main table's section column header. If there is an "X" within column 4 of the main table then add that column automatically to the section 4 table as well.
This is an overkill since the data is already in the main table. However, I wanted to reframe from having to read through the main table and separate equipment to its section in my applications run time.
Problems:
I've already tried setting up the relationships, however, my "relationship" type is "indeterminate" which I believe is because the tables are not referencing each others primary key column.
I created a section column in each of the section tables to denote a value 4-26. I then set that as my primary key, but primary keys (as far as i know) must be unique so that will not work.
Any suggestions?
Any list of columns of a table can form a foreign key in it. The referencing table and list of colums just has to reference a list of columns that forms a candidate key in the refereced table.
In SQL a PRIMARY KEY declares a UNIQUE NOT NULL column list. This is called a superkey. A superkey that contains no smaller superkey is a candidate key. Primary keys don't matter to integrity & normalization, candidate keys do. You can call some candidate key the primary key. (So an SQL PRIMARY KEY actually declares a superkey, what you might call a primary superkey, which might be a candidate key.)
A foreign key says that if you replace the column names in the referencing column list by their values in a row of the referencing table then you have to be able to make the same list of values by replacing the column names in the the referenced column list by their values in a row of the referenced table. If that's the case and there isn't already a chain of foreign keys from referencing table to the referenced tables that says the same thing then declare a foreign key. (The DBMS will use that fact for integrity and optimization.)
PS Tables (whether the values of base tables or query results) represent application relationships/associations. Certain tools, methods and presentations call foreign keys "relationships".
Establish the primary key in the main table which will include the section values and use this in the section tables as both the primary key of that table and a foreign key back to the main table.
create table TestEquipment(
ID AutoNumber primary key,
Section int not null,
..., -- other fields common to test equipment
constraint CK_TestEquipmentSection( Section between 4 and 26 ),
constraint UQ_TestEquipmentLink unique( ID, Section )
);
As ID will be unique all by itself, why create a unique constraint with ID and the section value? So we can refer to the combination with FKs in the section tables:
create table Section4(
ID int not null primary key,
Section int not null,
..., -- other fields for section 4 entries
constraint CK_Section4 check( Section = 4 ),
constraint FK_Section4TE foreign key( ID, Section )
references TestEquipment( ID, Section )
};
create table Section5(
ID int not null primary key,
Section int not null,
..., -- other fields for section 5 entries
constraint CK_Section5 check( Section = 5 ),
constraint FK_Section5TE foreign key( ID, Section )
references TestEquipment( ID, Section )
};
The other section tables will be similarly defined. When a piece of test equipment is entered, the key value is generated and the section number established by creating an entry in TestEquipment. A entry can then only be made in the section table with the matching section value. That is, if any entry is made in TestEquipment with an ID value of 1001 and Section value of 4, the only section table that can contain an entry with an ID value of 1001 will be the Section4 table. Any attempt to enter it into any of the other section tables will be rejected.
This is about the simplest way to do what it would appear you are trying to do.
I have a problom about my ERD...
I have 3 user table with different attributes. Each user connected to house table.
Then house table has many logs. My question is, how to know the logs are related to users depends on user type
Add a USER table bridging the USER_x tables to HOUSE:
-- [id] is a type x user and ...
USER_x(id,...) PK (id) FK (id) REFERENCES USER (id)
-- [id] is a user
USER(id) PK (id)
-- house [id] is used by [USER_id] and ...
HOUSE(id,USER_id,...) PK (id) FK (USER_id) REFERENCES USER (id)
There are various ways to constrain this kind of design so that USER has exactly the disjoint union of USER_x ids. Eg a USER type discriminator column whose values are the various values for x. (Also other kinds of design. Eg a nullable USER foreign key per USER_x. With their own constraints. Eg checking that only one such FK IS NOT NULL.)
Search for Stackoverflow SQL articles re subtables, subtypes, inheritance and foreign keys. Eg this or this.
Here's how to constraint this kind of situation without triggers.
Here's an example: Originally I have 3 tables. Table B references Table A. So now Table B has two primary keys. One used as the original primary key and the other one to enforce its relationship with Tabe A. Then I want Table B to have a many-to-many relationship with Table X. As I'm adding the relationship, MySQL Workbench added Table Y with both of Table B primary keys and one primary key in Table X. So Table Y now has three primary keys.
It seems like the second primary key from Table B in the junction table is unnecessary since I can identify Table B with the original primary key. So do I still need the extra primary key? Or perhaps I should not have an identifying relationship between Table A and B?
Table A and B have a relationship something like User has many Post. Post must belong to a User. But Post already has a primary key of its own, so does the foreign key to User need to be a primary key?
EDIT
Here's the scenario (diagram link below). The tables I'm focusing on are snippet, snippet_topic and tag. From what I know, since every snippet must belong to a snippet_topic, it has an identifying relationship. So I used the identifying relationship in MySQL Workbench and they added snippet_topic ID as a primary key. Afterwhich I added a m:n relationship for tag and snippet. MySQL Workbench added snippet_topic ID to the junction table (but I removed it). Is there anything wrong with my design? Or is there a more correct way to this?
Legend:
Yellow icon - primary key
Red icon - not null
each table should only have one primary key which is only about this table. If you then want a second column in Table A containing the values of the table B primary key thats find. Just set up a second index to get performance if requires
Originally I have 3 tables.
Ok.
Table B references Table A. So now
Table B has two primary keys. One used
as the original primary key and the
other one to enforce its relationship
with Tabe A.
No. Table B has one primary key and one foreign key. The foreign key might be part of the primary key, and it might not.
Then I want Table B to have a
many-to-many relationship with Table
X.
Ok.
As I'm adding the relationship, MySQL
Workbench added Table Y with both of
Table B primary keys and one primary
key in Table X. So Table Y now has
three primary keys.
A many-to-many relationship is typically implemented as a table that contains two foreign keys as its primary key. In your case, one foreign key is the primary key of Table B, and the other foreign key is the primary key of Table X. The primary key of Table B seems to contain two columns. The tables might look like this.
Table A: {a1, a2}
Table B: {b1, a1, b2, b3}, a1 references Table A
Table X: {x1, x2}
Table Y, which implements the m:n relationship, contains the keys from B and from X.
Table Y: {b1, a1, x1}, the two columns b1, a1 reference Table B; the column x1 references Table X
If you want better answers, edit your question and include the SQL DDL for your tables. Get the DDL by using SHOW CREATE TABLE.
You can not have more than one primary key. What you have there might be indexes. If the user_id column from table posts is included in your primary key, you can take it out and leave the primary key composed of just the id column.
I hope this helps
From your edited post - the only way to do this correctly is to have another table to hold the many to many relationship. Sniipit & snippit_topic have single primary keys and this new table has two columns with each of the primary keys