Does a join table or associated table need a primary key? - mysql

Sorry, I'm pretty new at this,
I have 3 tables, one is table1, table2, and table12.
table1 has a PK table1_id and table2 has table2_id as a PK.
table12 has 3 attributes, FK table1_id, FK table2_id, and table12_name.
Is it wrong that I don't have a table12_id?
Thanks and sorry for the dumb post...

You probably should have an explicit primary key on table12. The question is, which of these makes a better primary key:
An artificial auto-incremented primary key, say Table12Id.
The pair (table1_id, table2_id)
Note that the second of these imposes a uniqueness constraint on the pair, which you probably want (if you allow duplicates, then you should definitely have an explicit id).
I am someone who strongly advocates using numeric, auto-incremented primary keys on all tables. However, for a junction table either method is fine. There is logic to this reasoning. All tables that represent entities should have unique keys. This table is an implementation of a relationship, so the composite primary key makes sense.
Note that depending on how you use the table, you might still want indexes on either or both of the components of foreign key columns.

Not necessarily wrong.
You should use a primary key, if you want to reference a specific row in a table.
The primary key must be a unique value identifying the row.
Sometimes you do not need a primary key, as in your case,
where the table12 seems to be a table that connects the other two
and names that connection.
You might want to make the connection unique (the pair of ID values in table12).

Following the structures of your 3 tables, it is clear you had a ManyToMany relationship between table1 and table2, so that is why you created an associative third table table12.
Actually it is just great what you did: table12 will have a primary key which is combined of table2_id and table1_id whereas table12_name is optional and depends on your needs.
So to answer your question directly: you already have table12_id which is the combination of table1_id and table2_id that must be, in combination -optionally with table12_name- a primary key of table12.

Related

How do I make a field reference another field which is not a primary key in MySQL?

I know that foreign keys need not reference only primary keys but they can also reference a field that has a unique constraint on it. For my scenario, I am setting up a quiz where for each test, I have a set of questions. My table design is like this
The point is, in my 2nd table where I will put all the answer options, I want the question number field to link to the first table question number. How do I do this? Or is there an alternative to this design?
Thank you
Ideally there should be a question_id primary key column in the test_question table, and you would use this as the foreign key in the test_answer table.
With your composite primary key in the test_question table, you should make a corresponding composite foreign key:
CONSTRAINT FOREIGN KEY (test_id, question_no) REFERENCES test_question (test_id, question_no)
This is in addition to the foreign key just for the test_id column.
Add another table purely for answers, and link them via the question_no field.
A DB table should hold information on one sort of item. Questions and answers are separate sorts of information so should be in separate tables. Adding a separate table also allows changes to questions and answers independently. Additionally, if they are separate, you could add a language field to each table and have a multi-lingual quiz
Short answer:
You can JOIN on any columns or expressions. There is no "requirement" for a FOREIGN KEY, PRIMARY KEY, UNIQUE, or anything else.
Long answer:
However,... For performance (in large tables), some things make a difference.
If you are JOINing to a PK, Unique key, or even an indexed column, the query cold run faster.
Why have a FOREIGN KEY? An FK is two things:
A "constraint" that says that the value must exist in the other table. Also, with things like ON DELETE CASCADE, it can provide actions to take if the indicated row is removed. The constraint requires looking in the other table each time a write occurs (eg INSERT).
An Index. That is, specifying a FK automatically adds an INDEX (if not already present) to make the constraint faster.
Getting the id
Here is the "usual" way to do a pair of inserts, where you need the second to 'point' to the first:
INSERT INTO t1 ... -- with an AUTO_INCREMENT id
grab LAST_INSERT_ID() -- that id
INSERT INTO t2 ... -- and include the id from above
For AUTO_INCREMENT to work it must be the first column of some key. (Note: a PRIMARY KEY is a UNIQUE is a key (aka INDEX).)
Optionally you can specify a FK on the second table to point out the connection between the tables.
And, as spelled out in other answers, a FK could involve more than one column.
Entities and Relations
Sometimes, a set of tables like yours is best 'designed' this way:
Determine the "entities": users, tests, questions, answers
Relations and whether they are 1:1, 1:many, or many:many... Users:test is many-to-many; tests:questions is 1:many (unless you want questions to be shared between tests).
Answers is more complex since each 1 answer depends on the user and question.
1:1 -- rarely practical; may as well merge the tables together.
1:many -- a link (FK?) in one table to the other.
many:many -- need a bridge table with (usually) 2 columns, namely ids linking to the two tables.

multiple primary key defined [duplicate]

Here is a gross oversimplification of an intense setup I am working with. table_1 and table_2 both have auto-increment surrogate primary keys as the ID. info is a table that contains information about both table_1 and table_2.
table_1 (id, field)
table_2 (id, field, field)
info ( ???, field)
I am trying to decided if I should make the primary key of info a composite of the IDs from table_1 and table_2. If I were to do this, which of these makes most sense?
( in this example I am combining ID 11209 with ID 437 )
INT(9) 11209437 (i can imagine why this is bad)
VARCHAR (10) 11209-437
DECIMAL (10,4) 11209.437
Or something else?
Would this be fine to use this as the Primary Key on a MYSQL MYISAM DB?
I would use a composite (multi-column) key.
CREATE TABLE INFO (
t1ID INT,
t2ID INT,
PRIMARY KEY (t1ID, t2ID)
)
This way you can have t1ID and t2ID as foreign keys pointing to their respective tables as well.
I would not make the primary key of the "info" table a composite of the two values from other tables.
Others can articulate the reasons better, but it feels wrong to have a column that is really made up of two pieces of information. What if you want to sort on the ID from the second table for some reason? What if you want to count the number of times a value from either table is present?
I would always keep these as two distinct columns. You could use a two-column primay key in mysql ...PRIMARY KEY(id_a, id_b)... but I prefer using a two-column unique index, and having an auto-increment primary key field.
the syntax is CONSTRAINT constraint_name PRIMARY KEY(col1,col2,col3) for example ::
CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
the above example will work if you are writting it while you are creating the table for example ::
CREATE TABLE person (
P_Id int ,
............,
............,
CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
);
to add this constraint to an existing table you need to follow the following syntax
ALTER TABLE table_name ADD CONSTRAINT constraint_name PRIMARY KEY (P_Id,LastName)
Suppose you have already created a table now you can use this query to make composite primary key
alter table employee add primary key(emp_id,emp_name);
Aside from personal design preferences, there are cases where one wants to make use of composite primary keys. Tables may have two or more fields that provide a unique combination, and not necessarily by way of foreign keys.
As an example, each US state has a set of unique Congressional districts. While many states may individually have a CD-5, there will never be more than one CD-5 in any of the 50 states, and vice versa. Therefore, creating an autonumber field for Massachusetts CD-5 would be redundant.
If the database drives a dynamic web page, writing code to query on a two-field combination could be much simpler than extracting/resubmitting an autonumbered key.
So while I'm not answering the original question, I certainly appreciate Adam's direct answer.
Composite primary keys are what you want where you want to create a many to many relationship with a fact table. For example, you might have a holiday rental package that includes a number of properties in it. On the other hand, the property could also be available as a part of a number of rental packages, either on its own or with other properties. In this scenario, you establish the relationship between the property and the rental package with a property/package fact table. The association between a property and a package will be unique, you will only ever join using property_id with the property table and/or package_id with the package table. Each relationship is unique and an auto_increment key is redundant as it won't feature in any other table. Hence defining the composite key is the answer.
CREATE TABLE `mom`.`sec_subsection` (
`idsec_sub` INT(11) NOT NULL ,
`idSubSections` INT(11) NOT NULL ,
PRIMARY KEY (`idsec_sub`, `idSubSections`)
);
#AlexCuse I wanted to add this as comment to your answer but gave up after making multiple failed attempt to add newlines in comments.
That said, t1ID is unique in table_1 but that doesn't makes it unique in INFO table as well.
For example:
Table_1 has:
Id Field
1 A
2 B
Table_2 has:
Id Field
1 X
2 Y
INFO then can have:
t1ID t2ID field
1 1 some
1 2 data
2 1 in-each
2 2 row
So in INFO table to uniquely identify a row you need both t1ID and t2ID

Multiple column key or multiple column unique [duplicate]

Here's what's confusing me. I often have composite primary keys in database tables. The bad side of that approach is that I have pretty extra work when I delete or edit entries. However, I feel that this approach is in the spirit of database design.
On the other side, there are friends of mine, who never use composite keys, but rather introduce another 'id' column in a table, and all other keys are just FKs. They have much less work while coding delete and edit procedures. However, I do not know how they preserve uniqueness of data entries.
For example:
Way 1
create table ProxUsingDept (
fkProx int references Prox(ProxID) NOT NULL,
fkDept int references Department(DeptID) NOT NULL,
Value int,
PRIMARY KEY(fkProx,fkDept)
)
Way 2
create table ProxUsingDept (
ID int NOT NULL IDENTITY PRIMARY KEY
fkProx int references Prox(ProxID) NOT NULL,
fkDept int references Department(DeptID) NOT NULL,
Value int
)
Which way is better? What are the bad sides of using the 2nd approach? Any suggestions?
I personally prefer your 2nd approach (and would use it almost 100% of the time) - introduce a surrogate ID field.
Why?
makes life a lot easier for any tables referencing your table - the JOIN conditions are much simpler with just a single ID column (rather than 2, 3, or even more columns that you need to join on, all the time)
makes life a lot easier since any table referencing your table only needs to carry a single ID as foreign key field - not several columns from your compound key
makes life a lot easier since the database can handle the creation of unique ID column (using INT IDENTITY)
However, I do not know how they
preserve uniqueness of data entries.
Very simple: put a UNIQUE INDEX on the compound columns that you would otherwise use as your primary key!
CREATE UNIQUE INDEX UIX_WhateverNameYouWant
ON dbo.ProxUsingDept(fkProx, fkDept)
Now, your table guarantees there will never be a duplicate pair of (fkProx, fkDept) in your table - problem solved!
You ask the following questions:
However, I do not know how they
preserve uniqueness of data entries.
Uniqueness can be preserved by declaring a separate composite UNIQUE index on columns that would otherwise form the natural primary key.
Which way is better?
Different people have different opinions, sometimes strongly held. I think you will find that more people use surrogate integer keys (not that that makes it the "right" solution).
What are the bad sides of using the
2nd approach?
Here are some of the disadvantages to using a surrogate key:
You require an additional index to maintain the unique-ness of the natural primary key.
You sometimes require additional JOINs to when selecting data to get the results you want (this happens when you could satisfy the requirements of the query using only the columns in the composite natural key; in this case you can use the foreign key columns rather than JOINing back to the original table).
There are cases like M:N join tables where composite keys make most sense (and if the nature or the M:N link changes, you'll have to rework this table anyway).
I know it is a very long time since this post was made. But I had to come across a similar situation regarding the composite key so I am posting my thoughts.
Let's say we have two tables T1 and T2.
T1 has the columns C1 and C2.
T2 has the columns C1, C2 and C3
C1 and C2 are the composite primary keys for the table T1 and foreign keys for the table T2.
Let's assume we used a surrogate key for the Table T1 (T1_ID) and used that as a Foreign Key in table T2, if the values of C1 and C2 of the Table T1 changes, it is additional work to enforce the referential ingegrity constraint on the table T2 as we are looking only at the surrogate key from Table T1 whose value didn't change in Table T1. This could be one issue with second approach.

Two Primary Keys

here is the pictorial representation of my partial database. BrandNo is a primary key in Suppliar Table, that is being used as Foreign Key in others.
In LotDetails Table I need BrandName as Foreign Key. This sounds absurd as i can make either
a Single Primary Key OR
a Composite Key
that will be used as Foreign Key.
I know that I can use BrandNo as Foreign Key and Display BrandName, but for the sake of KNOWLEDGE (and yes EASE ofcourse) i want to know that
Is it possible to use two attributes of a table as Foreign Keys separately in different Tables?
EDITTED
BrandNo is just a Serial Number and Brand Name can be the Name of any Brand.
BrandNo is needed in 4 Tables as shown, whereas BrandName is needed in only one table.
Thanks!
Yes! A FK don't need to reference a PK, you even don't need to reference a indexed column but for the sake of relational integrity (and sanity) you must reference a unique valued column (thus is why we "like" to reference a PK or at least a unique non clustered indexed column).
It's sound a bit weird but you can build a relational tableAB holding IdA, IdB and tableA and tableB referencing tableAB respective columns.
btw: a table don't need to own a PK but cannot exist two PK. In general the table is physical ordered by the PK.
Yes that's quite possible. Assuming BrandName is a candidate key on its own then in principle you can reference it in just the same way as BrandNo. In that case BrandName and BrandNo would not be a composite key, they would both be separate candidate keys.
By convention and for simplicity and ease of use it is usual to choose just one key per table to be used for foreign key references. Usually (not always) that is the one designated as "primary" key but it doesn't have to be so if you find a good reason to do otherwise.
When you create foreign key references, the key in the referenced table should be a primary key. It doesn't make sense to have a "partial" reference.
Instead, you should have a Brands table that has a primary key (perhaps BrandId, perhaps BrandName -- I prefer the former). Then tables that need information about a brand can directly reference this table.

RDBMS best practices - autoid for association table?

I have two tables, let's say they are called table A and table B. An item from table B can be present in multiple instances of A, and each A can contain multiple Bs so I have a table called a_b which links them together by their primary keys. My question is when I define this association table, should I have a primary key on the association table? Or is it not needed? Just trying to avoid ending up on TDWTF, that's all :)
The primary key would be on the table A PK column and table B PK column in your association table. That way, you ensure you don't get any duplicate rows in your association table by accident.
One of the main purposes of primary keys is to guarantee referential integrity. That is, keep the data in your table clean, with no duplicates. The PK in this case will ensure you never have 2 duplicate rows in the association table.
I think you might want to use a primary key in order to show your intent. If for example you do not want
a, b
a, b
Then a primary key defined on A.a and B.b would make that more clear. If you don't care, but you have a,b and other fields, then adding a surrogate key as your primary key might help in giving you a uniform way to delete a row that you do not want. Otherwise you will have to delete where a=a and b=b and ?? then pick some field value from the row you want deleted. Whereas with a surrogate key you can just pick the row and say delete where mykey = 36 or something...
But really it depends on the business case. Many intersect tables have some kind of date range, or additional fields related to the relationship in addition to the keys of the two tables. Defining a primary key on the existing columns, a new surrogate key, some unique indexes, some constraints, or even having no indexes could all be valid courses of action depending upon your needs.
I would say definitely do whatever makes your intentions the most clear.
Not needed. Both keys should form the primary key of your association table. If you're going to be doing bidirectional navigation, consider adding an index with the keys reversed.
The primary key is needed always.
However, I'd say it depends what should it be. If you are going to use some sort of ORM systems (e.g. Hibernate) then it is best to have a surrogate identifier, while those two foreign keys (pointing to tables A and B) should form a unique index.
Also, if there would ever be a need to reference such a relationship from another table then this surrogate identifier would be really handy.