I have a table of business names and info about them, including an address column. A business name can have duplicate names and an address can have duplicates, but both the Business name and address cannot be duplicates. So there's a many to many relationship of sorts, but that is not between two tables, it's between two columns on the same table.
One or both of these fields also need to be a foreign key of another table.
Do I create a bridge table? Composite keys? If composite keys, how would I make them foreign keys in another table?
You might want to create 3 tables. One that stores the business names, another for the adresses, and then a junction table called, for example, business_adresses.
create table businesses (
id int primary key,
name varchar(50)
);
create table adresses (
id int primary key,
street varchar(200),
city varchar(200),
country varchar(200)
);
create table business_adresses(
business_id int,
adress_id int,
primary key (business_id, adress_id),
foreign key (business_id) references businesses(id),
foreign key (adress_id) references adresses(id)
);
With this set up, each entity has its own table, and information is not duplicated, unlike when using a single table. Meanwhile, in the junction table, you can efficiently enfore the unicity of business/entity tuples through the primary key (could also be a unique key), and maintain data integrity with foreign keys.
Related
I'm trying to create a foreign key between two tables. Problem is one of those tables has a composite primary key..
My tables are products (one row per product) and product_price_history (many rows per product).
I have a composite key in product_price_history, which is product id and start date of a specific price for that product.
Here's my code :
CREATE TABLE products (
product_id INT IDENTITY(1,1) PRIMARY KEY,
product_name VARCHAR(50) NOT NULL,
product_desc VARCHAR(255) NULL,
product_group_id INT
)
CREATE TABLE product_price_history (
product_id INT NOT NULL,
start_date DATE NOT NULL,
end_date DATE NULL,
price NUMERIC (6,2) NOT NULL
)
ALTER TABLE product_price_history
ADD CONSTRAINT pk_product_id_start_dt
PRIMARY KEY (product_id,start_date)
Now I'm trying to create a foreign key between the products table and the product_price_history table but I can't because its a composite key.
Also it doesn't make sense to add the start date (the other part of the foreign key) to the products table.
What's the best way to deal with this? Can I create a foreign key between these tables? Do I even NEED a foreign key?
My intentions here are
to enforce uniqueness of the product price information. A product can only have one price at any time.
to link these two tables so there's a logical join between them, and I can show this in a database diagram
The foreign key on the product_price_history table should only include product_id. Your target is to ensure that any entry product_price_history already has "parent" entry in products. That has nothing to do with start_date.
The way I see this situation, in theory, fully normalized version of the tables would have to have current_price as unique value in products table. And the product_price_history is simply a log table.
It's not necessary to do it this way, with a physical field, but thinking from this perspective helps to see where your tables model is slightly de-normalized.
Also, if you make product_price_history table anything but simple log table, how do you ensure that new start_date is newer than previous end_date? You can't even express that as a primary key. What if you edit start_date later? I would even think to create different compaund key for product_price_history table. Perhaps product_id+insert_date or only auto-increment id, while still keeping foreign key relationship to the products.product_id.
I have following question: let's say we have a Chen-Notation 1:n and m:n.
So 1 has a primary key and n also, where do I type the foreign key ? in the n ?
And the second question is about m:n, both have a primary key, and I need 1 more table because it's m:n, do I type the both primary keys as foreign keys in the 3rd table?
Example of a 1:n relationship : customers and orders
One customer may have several orders. In this situation, you want a column in the orders table with a foreign key that references the primary key of the customers table.
Sample DDL:
create table customers (
id int primary key,
name varchar(50),
email varchar(50)
);
create table orders (
id int primary key
price float,
customer_id int foreign key references customer(id)
);
Example of a n:m relationship : books and authors
A book may be written by more than one author. An author may have written more than one book. You create a bridge table, also called junction table, called books_authors, to represent that relationship, and that contains foreign keys to the two other tables.
Sample:
create table books (
id int primary key,
name varchar(50)
);
create table authors (
id int primary key,
name varchar(50)
);
create table books_authors(
book_id int foreign key references books(id),
author_id int foreign key references authors(id),
constraint pk_books_authors primary key(book_id, author_id)
);
So 1 has a primary key and n also, where do I type the foreign key ? in the n ?
The foreign key lives in the n, because 1 can have many keys, but you can't have a field that holds multiple values, you need to have one value per field, so it's in the n.
And the second question is about m:n, both have a primary key, and I need 1 more table because it's m:n, do I type the both primary keys as foreign keys in the 3rd table?
Yes, because that 3rd table in effect has a many-to-one relationship to both tables.
Lets say I have two tables teams and players and we assume that many players can be members of many teams(in different sports). Thus I have the first table
teams with PKs both team_name and sport. the second table "players" has PK player_id. Due to the -to- relationship I have also a third table with all the keys (team_name, sport and player_id).
the problem in this case is that the column team name is not unique in the first table. Of course I could give another column as the id and make this one the PK. But I am not sure if this is the best approach and how this is solved in the real world. So the questions are:
1. if I can have a composite key like this which one column doesnt have unique values
2. How do you normalize it appropriately?
3. Could I use just one of the composite key in the third table if this is convenience or I always have to take the whole key?
create table sports(
sport varchar(30),
capt_id int references captain(capt_id),
primary key(sport)
);
Create table teams(
team varchar(30),
sport varchar(30) references sports(sport),
primary key(team,sport)
);
create table teamplayer(
player_id int references player(player_id),
sport varchar(30) references sports(sport),
team varchar(30) references teams(team),
unique (team, sport),
primary key(player_id, team, sport)
);
I am using access 2010 to do this.
I have created two tables and I would like to get it one to one and i don't seem to get it in to one to one relationship.
CREATE TABLE Person(
ID VARCHAR(1) UNIQUE,
Name VARCHAR(30),
PRIMARY KEY (ID)
);
CREATE TABLE Passport(
ID VARCHAR(1) UNIQUE,
Country VARCHAR(30),
PRIMARY KEY (ID),
FOREIGN KEY (ID) REFERENCES Person(ID)
);
From the little knowledge that I have, This should be a one to one relationship but it is a one to many. How do I get it one to one via ACCESS?
I have tried most things that I can find in books but with no success.
Please help.
You may simply be misled by the way relationships are displayed in the Relationships window. I ran your exact DDL and when I view the relationship in the Relationships window it looks like one-to-many...
...but when I right-click on the line joining the two tables and choose "Edit Relationship..." the dialog shows that it is actually one-to-one:
I beleive that in fact you created a one-to-one relationship as you wish.
the person id is unique
the passport id is unique
the passport id(unique) equals one person id(also unique).
So its one-to-one
However, it should be better design to have different ids for person and passport to have more clear design. Something like this:
CREATE TABLE Person(
PERSONID VARCHAR(1) UNIQUE,
Name VARCHAR(30),
PRIMARY KEY (PERSONID)
);
CREATE TABLE Passport(
PASSPORTID VARCHAR(1) UNIQUE,
Country VARCHAR(30),
PERSONID VARCHAR(1),
PRIMARY KEY (PASSPORTID),
FOREIGN KEY (PERSONID) REFERENCES Person(PERSONID)
);
This will also accomodate cases of persons with multiple passports.
I have a database scheme with versioning data rows, e.g.
Table Person has the columns
id (int, PK)
name (String)
current (Bool)
firstid (int)
Current is 0 for previous data, 1 for the latest entry. All rows for the same entity have the same FirstID, which points to the first ID of the set.
Referencing table: Adress with the same principle:
id (int, PK)
street (String)
person_id (int)
current (Bool)
firstid (int)
Person_id points to patient.firstid. So firstid is never unique, only if current=1
My problem is: I would like to add referential integrity to my tables, but this only works, if the referenced column (patient.firstid) is unique...
You should look at refactoring your table structure. But to keep within the current structure, add a self-referencing foreign key to person
firstid references person(id)
Then, reference the "base person" from the address table
address.person_id references person(id) -- which should ONLY store a link to the first id
A FOREIGN KEY constraint does not have
to be linked only to a PRIMARY KEY
constraint in another table; it can
also be defined to reference the
columns of a UNIQUE constraint in
another table. A FOREIGN KEY
constraint can contain null values;
however, if any column of a composite
FOREIGN KEY constraint contains null
values, then verification of the
FOREIGN KEY constraint will be skipped.
Data from two related tables can be combined even if no PRIMARY KEY or FOREIGN KEY constraints are defined between the tables, but a foreign key relationship between two tables indicates that the two tables have been optimized to be combined in a query that uses the keys as its criteria.
reference http://msdn.microsoft.com/en-us/library/aa933117(v=sql.80).aspx