How to design schema many to many relations - database

I have table of customer and table of policies and table of coverage.
Each customer have 1 or more policies
Each policy have 1 customer
each policy have 1 or more coverage and each coverage appear in 1 or more policies
My problem is when I have policy with multiples coverage I don't know how to implement it in the schema so when I open policy I want the ability to add multiple coverage to my policy.
How the schema will look like?
Best regards to all

From my point of view, it is simpler to show than explain. This is Oracle syntax, but never mind that. I used only necessary primary and foreign key columns, just to illustrate the problem.
Customer is simple:
SQL> create table customer
2 (id_customer number primary key);
Table created.
Policy has a foreign key constraint that points to customer:
SQL> create table policy
2 (id_policy number primary key,
3 id_customer number references customer
4 );
Table created.
Coverage is also simple:
SQL> create table coverage
2 (id_coverage number primary key);
Table created.
This is what bothers you: how to store policies with multiple coverages - in a separate table! whose columns make foreign key constraints, pointing to appropriate tables, while its primary key is composite & made up of both columns:
SQL> create table policy_x_coverage
2 (id_policy number references policy,
3 id_coverage number references coverage,
4 --
5 constraint pk_pxc primary key (id_policy, id_coverage)
6 );
Table created.
SQL>

Related

Creating a foreign key against a composite key in MS SQL Server

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.

primary key used in one to many relationship in postgresql for project

I am creating a final year project-online shopping system, but I am having doubt regarding the primary key to be used in tables as it has to get auto inserted in other tables to extract data.
Example if I am having two tables shop and products here relation between shop and product is one to many means one shop has many products. I tried to use serial as a primary key but it's not working well because it's accepting only number of product which are equal to number shops.
so what should I do to resolve this issue as at the time of inserting product through GUI we can just enter product name
Please can you help me out ???
I have attached some images regarding this database.Image giving error
This is what I have done in Postgres
check_serial=# create table shop(id serial primary key,name text);
CREATE TABLE
check_serial=# create table product(pid serial primary key,pname text,id serial references shop(id) on delete cascade on update set null);
CREATE TABLE
check_serial=# insert into shop(name) values('abc');
INSERT 0 1
check_serial=# insert into shop(name) values('xyz');
INSERT 0 1
check_serial=# insert into product(pname) values('soap');
INSERT 0 1
check_serial=# insert into product(pname) values('tooth paste');
INSERT 0 1
check_serial=# insert into product(pname) values('shampoo');
ERROR: insert or update on table "product" violates foreign key constraint "product_id_fkey"
DETAIL: Key (id)=(3) is not present in table "shop".
check_serial=# insert into product(pname) values('pqr');
ERROR: insert or update on table "product" violates foreign key constraint "product_id_fkey"
DETAIL: Key (id)=(4) is not present in table "shop".
check_serial=#
If i understood correctly, you should create only many to one relation and remove relation one to many from shop. Then you can use this model without any problems. Just insert product name with shop id and also you can join product to shop by id.

MSSQL - Foreign key to the same column IF other column is not equal to the referring row

I have a database in which i have two tables:
CREATE TABLE Transactions (
ID BIGINT IDENTITY(1,1) NOT NULL,
AccountID BIGINT NOT NULL,
Amount BIGINT NOT NULL,
CONSTRAINT PK_Transactions PRIMARY KEY CLUSTERED (ID ASC,AccountID ASC),
CONSTRAINT FK_Transaction_Account FOREIGN KEY (AccountID) REFERENCES Accounts(ID)
);
CREATE TABLE Accounts (
ID BIGINT IDENTITY(1,11) NOT NULL,
Balance BIGINT NOT NULL,
CONSTRAINT PK_Accounts PRIMARY KEY (ID)
);
Transactions are inserted to their table by a stored procedure i wrote, so that two rows are generated when Account 1 transfers 25 "coins" to Account 21:
ID | AccountID | Amount
-------------------------
1 | 1 | -25
-------------------------
1 | 21 | 25
In the above schema, i want the first row to reference the bottom row based on ID and the AccountID being unequal to the AccountID of the bottom row.
And vica versa.
What i want to do would look something like this:
CONSTRAINT FK_Transaction_Counterpart FOREIGN KEY (ID) REFERENCES Transactions(ID) WHERE thisRow.AccountID != referencedRow.AccountID
I haven't found this possibility in the documentation on the table constraints.
So both out of curiosity and intent to use this i ask, is this possible? And if yes, how?
Edit:
Answers reflect that this is not possible, and i should adjust my design or intentions.
I think i will settle with assigning the two transaction rows to each other in the functional code.
A traditional foreign key can't be conditional (i.e. no WHERE clause attached). In your case, I'd probably just make sure that the inserts are atomic (in the same transaction) so that there'd be no possibility of only one of them inserting.
If the data model you are trying to implement is:
One transaction (ID) has two and only two entries in table Transactions
For the two rows of a given Transaction ID, the AccountIDs cannot be the same
Then one perhaps overly-complex way you could enforce this business rule within the database table structures would be as follows:
Table Accounts, as you have defined
Table Transactions, as you have defined
New table TransactionPair with:
Columns (all are NOT NULL)
ID
LowAccountID
HighAccountID
Constraints
Primary key on ID (only one entry per Transaction ID)
Foreign key on (ID, LowAccountID) into Transactions
Foreign key on (ID, HighAccountID) into Transactions
Check constraint on the row such that LowAccountID < HighAccountID
Process:
Add pair of rows to Transactions table
Add single row to TransactionPair referencing the rows just added
If that row cannot be added, something failed, roll everything back
Seems neat and tidy, but quite possibly overly complex. Your mileage may vary.

Extending SQL Table

I have 4 SQL tables: User, Student, Professor and Publication.
User has the common columns for any kind of user;
Student has columns specific for a student;
Professor has columns specific for a professor;
Publication is only for professors.
So I have:
create table dbo.[User] (
Id int identity not null
constraint PK_User_Id primary key clustered (Id),
-- Other user columns
)
create table dbo.Student (
UserId int not null
constraint PK_Student_UserId primary key clustered (Id),
-- Other student columns
)
create table dbo.Professor (
UserId int not null
constraint PK_Professor_Id primary key clustered (Id),
-- Other student columns
)
create table dbo.Publication (
Id int identity not null
constraint PK_Publication_Id primary key clustered (Id),
UserId int not null
-- Other student columns
)
alter table dbo.Student
add constraint FK_Student_UserId foreign key (UserId) references dbo.[User](Id);
alter table dbo.Professor
add constraint FK_Professor_UserId foreign key (UserId) references dbo.[User](Id);
alter table dbo.Publication
add constraint FK_Publication_UserId foreign key (UserId) references dbo.Professor(Id);
QUESTION
Should I have a column Id as PK in Professor and Student tables?
And make, for example, (Id, UserId) as the PK of Professor (Same for student)
Then Publication would reference Professor.Id and not Professor.UserId.
I am asking this because it sounds strange to have Publication to reference UserId from Professor table which can be confusing when I will have more tables.
Could someone please advice me on this?
In your current schema arrangement and without knowing your use cases (programmatically), one could make the argument that you don't need the Id identity columns for any of the extension tables. I assume this would be a 1 to 1 relationship to the User table anyway, so you'd at least want a unique constraint on the UserID columns, which you'd get by making it a PK anyway.
Things I like to consider are:
Can a professor ever become a different user ?
Is it possible for a professor to exist without an user ?
Is it possible for a single user to be two professors (multiple disciplines?)
If so, why wouldn't you give every professor an unique Id (ProfessorId), and only create a foreign key to the User table (UserId, you could call this UserFk).
In the publication table you can reference the professor by his/her id and call this one ProfessorFk. This way you create very efficient references between tables. The publication table than also gets a single PublicationId as primary key.
Correct me if i'm wrong, i don't know your use case. But it would seem reasonable that a professor can have multiple publications, but a publication can also be written by multiple professors ? This would mean you need an extra table between publication and professor for the n-n relationship.
About creating a professor key that is a combined key (Id, UserId). I personally dislike combined keys, if you want to reference this professor from your publication table you need two columns.
This would also suggest you can have multiple professors for the same user, if so, go for the single Id option.
This means i would create the following setup:
User Table
UserId
Student Table
StudentId
UserFk
Professor Table
ProfessorId
UserFk
ProfessorPublication Table
ProfessorFk
PublicationFk
Publication Table
PublicationId
So, it partly is based on what you want to be able to do with your data, and partly just your preference.

Database problem--student registering for the same class twice..how to stop it Access 20007

I am making a mock database and I have a student table, student_class linking table, and a class table. How can I make it so that a student cannot be registered for the same class twice?
Example: StudentID 21 and classID 34 can be entered X number of times in the linking table.
The tables are designed 3NF, too.
In your student_class linking table (otherwise called a composite table), make both values, StudentID and ClassID, primary keys. So that table will have 2 columns that are composite primary keys and also foreign keys to their associated tables. Does that make sense?
A student_class table probably has at least two columns. One would be a foreign key to the primary key in student; the other would be a foreign key to the primary key in class. You need a primary key constraint on that pair of columns.
For example, if student_class had the two columns student_id and class_id . . .
Open the table student_class in design view.
Select both those columns.
Click the key icon.
That should do it.
You could have a table that tells you which students are enrolled in which classes, named students_classes. If you make a composite primary key on this table containing student_id and class_id, then it should be impossible to have the database contain a student in the same class twice.
I should point out that you should not have an auto-increment ID primary key column on this table (I think Access likes to add this by default so if it did you may have to remove it). If you do, you could still end up with duplicates if all three are a part of the key. Example:
ID student_id class_id
113 1 2
114 1 2
Having the ID field still allows you have a student enrolled twice in the same class.

Resources