Creating a relationship based on columns that are NOT the primary keys? - ms-access

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.

Related

Primary Key/Foreign Key for a table with two junction tables

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. :-)

How Primary key can be only one in a table

After googling a lot, I found 2 statements for Primary Key.
Some says, Primary key can be only one in a table.
Some says, Primary key can consists of more than one column.
And also says, it is the difference between Primary key and Unique key.
I read this post: difference between primary key and unique key
But, this post also confuses this difference.
My Question is:
When Primary key can consists of multiple columns, then how can it be only
1 for a table and then how this can differ from Unique Key except from
null value difference?
A primary key is used by the optimiser to create a clustered index around that key. If that key happens to be a combination of columns (for instance in a table that handles a many to many relationship) then that is fine. A unique key is an attribute of something that is unique to that thing but not an attribute that you want to use as the primary key.
One example that i work with is cars. The vin is unique to the car. However because the vin and body number are used at different stages in the vehicles life. Whilst it is unique to the car, it isn't a good primary key candidate. So we have a unique identifier per car as a primary key.
Similarly we handle user group tables with primary keys over multiple columns. So the combination of the userid and the usergroupid is a primary key preventing the entry of people in to the same group more than once. The use of a primary key here rather than a unique key is to conform to the 3rd normal form mostly.
I hope that helps but if you would like further clarification please let me know.
You can have only one primary key in a table, but it can consist of multiple columns. This doesn't mean that each column is a primary key, but that the combination of all these columns' values are unique.
A unique constraint is similar to a primary in preventing duplicate values, but a unique constraint allows nulls (since they aren't values). A primary key does not. You could think of a primary key as a unique not null constraint.
In SQL: Any number of sets of one or more columns can be declared UNIQUE. One set of columns can be declared PK (PRIMARY KEY). PK means UNIQUE NOT NULL. A set of one column is "simple" & a set of more than one is "composite".
In standard SQL a UNIQUE column set has a distinct subrow value in every row--where NULL<>NULL. MySQL does that--but some DBMSs evaluate that "distinct" treating NULL equal to NULL. Read the manuals.
SQL DBMSs use UNIQUE & PK declarations for other things--typically for default INDEXes. INDEX is not standard SQL & is a different notion. Read the manuals.
PK & other terms have different definitions in the RM (relational model)--even for tables that have an obvious interpretation as relations because they have no duplicate rows & no NULLs. Read some published academic textbook(s).
There's no need for PK in SQL or the RM--it's just a tradition.
Re related terms in SQL & the RM.
Primary keys can consist of any number of columns. They then have three properties:
The combination of values in the columns is unique.
The values in each column are never NULL.
There is only one primary key per table.
The first two conditions can be true on any number of columns or combinations of columns in a table. These are called candidate primary keys. You would implement them with unique and not null constraints.
The third condition is simply states that at most one of these candidates can be chosen as the primary key.
One way to think about this is that the primary key is special. For example, in MySQL, the data is actually ordered on the data pages by primary key (this is called a clustered index). However, nothing in SQL in general requires that the primary key also be a clustered index, and not all databases implement this.
There is no inconsistency in what you read
A primary key is "one or more columns, whose combination of values must appear on only one row"
A primary key can be single column, and then the value must be unique. It can be multiple columns, and all values considers together must be unique:
Key1, Key2
1 , A
1 , B
2 , A
2 , B
Here it's true that both key1 column and key2 column have repeated values but when we consider the combinations of key 1 and key 2, they are unique: 1A, 1B, 2A, 2B
Regarding the PK vs Unique Key query, see this answer. It goes into more detail about primary keys, the basic principle of which is that none of the columns making up the primary key allows a null value: What's wrong with nullable columns in composite primary keys?
the main differences between a primary key and a unique key is the primary key main job is to uniquely identify a row in a table and the main job for a unique key is to allow you to place additional unique conditions on your columns
For example say you have a employees table with employee ID as the primary key and a accountNumber.. the accountNumber would be set as the unique ID... so you wouldn’t have the accountNumber set as the primary key incase accountNumber is generated by another organisation outside of your database..
When Primary key can consists of multiple columns, then how can it be
only 1 for a table and then how this can differ from Unique Key
except from null value difference?
Its true that a table can only have one primary key. This key can contains multiple columns(combination of columns). That combination of columns is collective is a Primary Key.
Lets take an example
Table A
Id, Clientid, Branchid, Name, Address, .......
Here I created a primary key with combination of "Id, Clientid, Branchid"
so its is possible to have duplicate Id or duplicate CLientid or duplicate Branchid but its not possible to have the whole combination asa duplicate
for example
Id Clientid Branchid
1 1 1
1 2 1
1 1 2
2 1 1
the above combination is true
but below combination is not allowed as its a primary key and cann't have duplicate values
Id Clientid Branchid
1 1 1
1 1 1
and all columns as null is also not possible as primary key doesn't allow null

SQL Foreign key for Primary key with 2 values

As far as I'm aware, you can only assign primary keys and unique columns to foreign keys... yet I have a table that has a primary key between two columns:
alter table NAME add constraint PK primary key(VALUE1, VALUE2)
I'm trying to make Value1 a foreign key in another table, but it's not recognizing it as a primary key or unique - obviously because the primary key is shared between two values... So what do I do from here? I'm pretty new to SQL syntax...
You are correct that you can only assign primary keys and unique columns to foreign keys. I am not much aware of the business requirement here but ideally, you should be having a third table which has the VALUE1 as a primary key. If not you should create one.
The main idea is that you can't link a foreign key to a value that can hold duplicates on the referenced table. So if your main table has a compound key (more than 1 column), linking the foreign key to one (or many but not all) of it's columns would be linking the table to more than one row (since that column might have duplicates by itself).
If you really need to establish the link between the two then you have a problem, either:
Your primary key isn't really 2 or more columns. You can read about normalizing your database (in standard normal forms) to solve this.
Your relationship between the tables isn't 1 to N (it's N to M). You can't add a foreign key, you will have to create a 3rd table with both primary keys to link them.

When to use foreign key as a primary key at the same time?

I have get an intermediate table ArticleLanguage
idArticleLanguage
ArticleId
LanguageId
Name
Foreign keys are:
ArticleId
LanguageId
Should I use primary keys for:
ArticleId
LanguageId
Because these fields are primary keys in related tables?
Link / Junction Tables
Assuming the linked tables are defined as:
CREATE TABLE Article
(
ArticleId INT PRIMARY KEY
-- ... other columns
);
CREATE TABLE Language
(
LanguageId INT PRIMARY KEY
-- ... other columns
);
As per #JulioPérez Option 1, the link table could be created as:
CREATE TABLE ArticleLanguage
(
ArticleId INT NOT NULL,
LanguageId INT NOT NULL,
Name VARCHAR(50),
-- i.e. Composite Primary Key, consisting of the two foreign keys.
PRIMARY KEY(ArticleId, LanguageId),
FOREIGN KEY(ArticleId) REFERENCES Article(ArticleId),
FOREIGN KEY(LanguageId) REFERENCES Language(LanguageId)
);
i.e. with a composite primary key consisting of the two foreign keys used in the "link" relationship, and with no additional Surrogate Key (idArticleLanguage) at all.
Pros of this approach
Enforces uniqueness of the link, i.e. the same ArticleId and LanguageId cannot be linked more than once.
Saves an unnecessary additional surrogate key column on the link table.
Cons of this approach:
Any downstream tables which needs to reference this link table, would need to repeat both keys (ArticleId, LanguageId) as a composite foreign key, which would again consume space. Queries involving downstream tables which reference ArticleLanguage would also be able to join directly to Article and Language, potentially bypassing the link table (it is often easy to 'forget' that both keys are required in the join when using foreign composite keys).
SqlFiddle of option 1 here
The alternative (#JulioPérez Option 2), would be to to keep your additional surrogate PK on the reference table.
CREATE TABLE ArticleLanguage
(
-- New Surrogate PK
idArticleLanguage INT NOT NULL AUTO_INCREMENT,
ArticleId INT NOT NULL,
LanguageId INT,
Name VARCHAR(50),
PRIMARY KEY(idArticleLanguage),
-- Can still optionally enforce uniqueness of the link
UNIQUE(ArticleId, LanguageId),
FOREIGN KEY(ArticleId) REFERENCES Article(ArticleId),
FOREIGN KEY(LanguageId) REFERENCES Language(LanguageId)
);
Pros of this Approach
The Primary Key idArticleLanguage is narrower than the composite key, which will benefit any further downstream tables referencing table ArticleLanguage. It also requires downstream tables to join through the ArticleLanguage link table in order to get ArticleId and LanguageId, for further joins to the Language and Article tables.
The approach allows for an additional use case, viz that if it IS possible to add the same link to Language and Article more than once (e.g. two revisions or two reprints etc), then the UNIQUE key constraint can be removed
Cons of this Approach
If only one unique link per Article and Language is possible, then the additional surrogate key is redundant
SqlFiddle of option 2 here
If you're asking for an opinion, I would stick with option 1, unless you do require non-unique links in your ArticleLanguage table, or unless you have many further downstream tables which reference ArticleLanguage (this would be unusual, IMO).
Table per Type / per Class Inheritance
Unrelated to OP's post, but another common occurrence where a Foreign Key can be used as a Primary Key in the referencing table is when the Table per Type approach is taken when modelling an object oriented class hierarchy with multiple subclasses. Because of the 0/1 to 1 relationship between subclass and base class tables, the base class table's primary key can also be used as the primary key for the subclass tables, for instance:
CREATE TABLE Animal
(
AnimalId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-- Common Animal fields here
);
CREATE TABLE Shark
(
AnimalId INT NOT NULL PRIMARY KEY,
-- Subclass specific columns
NumberFins INT,
FOREIGN KEY(AnimalId) REFERENCES Animal(AnimalId)
);
CREATE TABLE Ewok
(
AnimalId INT NOT NULL PRIMARY KEY,
-- Subclass specific columns
Fleas BOOL,
FOREIGN KEY(AnimalId) REFERENCES Animal(AnimalId)
);
More on TPT and other OO modelling in tables here
You have 2 ways:
1) Put "ArticleId + LanguageId" as your only primary key in "intermediate table" and you can name it as "idArticleLanguage". This is called a "composite" primary key because it is composed by 2 (in other case more than 2) fields, in this case 2 foreign keys (PK= FK + FK).
2) Create "idArticleLanguage" that has no relation to the other two "id" and set it as primary key.It can be a simple auto-increment integer.
Both alternatives are accepted. Your election will depend on the goal you want to achieve because what happens if you need to add in this intermediate table the same Article with the same language (Wilkommen German for example) because you have 2 different editions of the article? if you choose alternative 1 it will throw an error because you will have the same composite primary key for 2 rows then you must choose alternative 2 and create a completely different primary key for this table
In any other case (or purpose) you can choose alternative 1 and it will work perfectly
About the change of your question title:
When use foreign key as primary key in the same time?
I will explain it with this example:
You have 2 tables: "country" and "city". "country" have all the countries of the world, "city" have all the cities of the world. But you need to know every capital in the world. What you should do?
You must create an "intermediate table" (named as "capital") that will have every capital on the world. So, we know that country have it's primary key "idcountry" and city have it's primary key is "idcity" you need to bring both as foreign keys to the table "capital" because you will need data of "city" and "country" tables to fill "capital" table
Then "capital" will have it's own primary key "idcapital" that can be a composite one "idcity+idcountry" or it can be an auto-increment integer in both cases you must have "idcity" and "idcountry" as foreign keys on your "capital" table.

One to Many MySQL [duplicate]

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)