Postgres - How to reference a primary key to a non unique value - sql

so I've been working on this assignment I got lately and it has me stumped for how I have to reference a specific table. So let's say I have a table of works from the museum and it contains two primary keys, combined makes it alphanumeric.
CREATE TABLE Works (
wrk_charid pdkeyone,
wrk_numid pdkeytwo,
wrk_name workname,
wrk_type worktype,
wrk_subtype worktype,
wrk_donate donator,
wrk_creation workDate,
wrk_acquistion workdate,
wrk_insurance insurance,
wrk_desc description,
wrk_curloc locationname DEFAULT 'Storage'
REFERENCES LocationAreas
ON UPDATE CASCADE ,
PRIMARY KEY (wrk_charid, wrk_numid),
UNIQUE (wrk_charid, wrk_numid)
);
So that is my table for works, and we have a separate table for materials. However, many works have more than one value for their materials, causing an error that it is not unique. So far I have the table for my materials as follows:
CREATE TABLE Materials (
mt_charid pdkeyone,
mt_numid pdkeytwo,
mt_material materialdesc,
PRIMARY KEY (mt_charid, mt_numid)
);
I don't know exactly how I can reference my works to my materials without running into a uniqueness error. Could someone please help push me in the right direction for what I'm supposed to do?

As the relationship is many to many (one work can have many materials, one material can be present in many works)
You should create a new Table to add the relationships between them. (Basically which work has which material).
Something like this:
CREATE TABLE Works_Materials (
wrk_charid work_pdkeyone,
wrk_numid work_pdkeytwo,
mt_charid material_pdkeyone,
mt_numid material_pdkeytwo,
PRIMARY KEY (work_pdkeyone, work_pdkeytwo, material_pdkeyone, material_pdkeytwo)
FOREIGN KEY (work_pdkeyone, work_pdkeytwo) REFERENCES Work(pdkeyone, pdkeytwo)
FOREIGN KEY (material_pdkeyone, material_pdkeytwo) REFERENCES Material(pdkeyone, pdkeytwo)
);

Related

How do I create a bridge table? Do I create two primary keys and two foreign keys?

I have a table that I want to make which is a bridge table for teacher and class table. This is the ERD
I initially thought I'm going to create this table by
CREATE TABLE class_teacher
(
teacher_id number(3),
class_id number(2),
CONSTRAINT class_teacher_pk
PRIMARY KEY(teacher_id, class_id),
CONSTRAINT class_teacher_teacher_fk
FOREIGN KEY(teacher_id) REFERENCES teacher(teacher_id),
CONSTRAINT class_teacher_class_fk
FOREIGN KEY(class_id) REFERENCES class(class_id)
);
But on the web I see people just having two foreign keys and no primary key, or table with no foreign key and having a primary key for two columns.
Am I doing it incorrectly?
Am I doing it incorrectly?
No, it looks correct.
Although I would question the size of the numeric data types as you are restricted to only have 1999 teachers and 199 classes (including negative numbers); this may be enough for immediate use but after several years when classes get re-organised or when the syllabus is re-written and new classes are created then you may run out of primary keys.
Does create statement returns any error? Otherwise you should be good.
Try to insert some data in all 3 tables and run some delete statements to see how it goes.

no matching unique or primary key for this column-list. Im not sure how to solve it for my case

I've been trying to create this table in my database. We were told to use Oracle-Apex for creating the database. So I keep getting this error that I cant solve:
If I remove the last line of the code, it creates the table fine without any errors.
Here are screenshots of the other tables being referenced here:
Company Table
Branch Table
IDK if this is a rookie mistake, I only learnt apex/sql in like an hour and went off to make the database. Thank you for helping me! :)
The column(s) referenced by a foreign key must have a unique index in the source table (or they must be the primary key of that table). Your code fails because of the following foreign key declaration, where the target is not unique:
foreign key (BranchNo) references Branch(BranchNo)
Here, I think that you want a compound foreign key that references the primary key of Branch rather than two different keys. Branch(CCode) references Company(CCode) already so there is no need to put that relationship in the Equipment table.
create table Equipment(
CCode int,
BranchNo int,
EquipNo it,
Description varchar2(50),
NumberOfEquip int,
primary key(CCode, BranchNo, EquipNo),
foreign key (CCode, BranchNo) references Branch(CCode, BranchNo)
);

SQL JDBC: parent key not found BUT the parent values have already been inserted into the database

I'm having a problem inserting mock data into the database
The table I'm trying to insert the values into is called 'purchased'
which has some foreign key values such as patient_id, pharmacy_id, drug_id.
The other 3 tables 'patient', 'pharmacy', 'drug' have already been added to the database successfully.
Patient table has a foreign key which is doctor_id. The 'doctor' table has also been added to the database.
Since I know that a foreign key patient_id in 'purchased' table depends upon another foreign key doctod_id, so I've done something like this
foreign key (patient_id, receipt_no) references patient(patient_id,doctor_id) ON DELETE CASCADE
Not sure what I've missed here, why does sqlplus complain that the parent key is not found? Just working for a database class project so I'm still learning.
Here's .sql code file
https://gist.github.com/mopkaloppt/de8fbf64c4d5711c90e2b389a72911ba
Any kind of help will be much appreciated.. I'm freaking out a bit now as I've been struggling with this for a while and it's due soon :(
This part of your FK constraint looks confused:
foreign key (patient_id, receipt_no) references patient(patient_id,doctor_id) ON DELETE CASCADE
^^^^^^^^^^ ^^^^^^^^^
You are getting the errors because there is no receipt_no in your purchased data that matches a doctor_id. This is perhaps unsurprising as the data are unrelated.
Having looked at the data in your patient table, it seems you haven't got the database design quite right. There's duplication in that table: if a patient has multiple illnesses or sees multiple doctors then there are repeated values for all other columns. This is also getting in the way of your FK constraint: you are trying to link a row in purchased to a patient, but there are multiple rows for some patients, so which row do you link to?
It seems you have a many-to-many relationship between patients and illnesses (a patient can have multiple illnesses, multiple patients can have an illness), and also between patients and doctors (a patient can be seen by multiple doctors, a doctor can see multiple patients). So, I would recommend introducing new tables for the relationships between patients and illnesses, and between patients and doctors. For example, here's the table you could use for the relationship between patients and doctors. Insert one row into this table for each combination of patient and doctor:
create table patient_doctor (
patient_id char(4) not null,
doctor_id char (4) not null,
primary key (patient_id, doctor_id),
foreign key (patient_id) references patient(patient_id) on delete cascade,
foreign key (doctor_id) references doctor(doctor_id) on delete cascade);
A linking table such as this is the standard way of representing a many-to-many connection in a relational database.
You don't yet have a table for illnesses, so I'll leave you to create a table for them, a linking table similar to that for patients and doctors (patient_illness perhaps), and the data in both tables.
Once you've done that, remove the doctor_id and illness columns from patient, remove the duplicate rows and make the patient PK depend only on patient. Your FK constraint from purchased to patient can then reference only patient_id.
Hopefully after doing all of this you should see your FK constraint violation errors go away.

MS SQL creating many-to-many relation with a junction table

I'm using Microsoft SQL Server Management Studio and while creating a junction table should I create an ID column for the junction table, if so should I also make it the primary key and identity column? Or just keep 2 columns for the tables I'm joining in the many-to-many relation?
For example if this would be the many-to many tables:
MOVIE
Movie_ID
Name
etc...
CATEGORY
Category_ID
Name
etc...
Should I make the junction table:
MOVIE_CATEGORY_JUNCTION
Movie_ID
Category_ID
Movie_Category_Junction_ID
[and make the Movie_Category_Junction_ID my Primary Key and use it as the Identity Column] ?
Or:
MOVIE_CATEGORY_JUNCTION
Movie_ID
Category_ID
[and just leave it at that with no primary key or identity table] ?
I would use the second junction table:
MOVIE_CATEGORY_JUNCTION
Movie_ID
Category_ID
The primary key would be the combination of both columns. You would also have a foreign key from each column to the Movie and Category table.
The junction table would look similar to this:
create table movie_category_junction
(
movie_id int,
category_id int,
CONSTRAINT movie_cat_pk PRIMARY KEY (movie_id, category_id),
CONSTRAINT FK_movie
FOREIGN KEY (movie_id) REFERENCES movie (movie_id),
CONSTRAINT FK_category
FOREIGN KEY (category_id) REFERENCES category (category_id)
);
See SQL Fiddle with Demo.
Using these two fields as the PRIMARY KEY will prevent duplicate movie/category combinations from being added to the table.
There are different schools of thought on this. One school prefers including a primary key and naming the linking table something more significant than just the two tables it is linking. The reasoning is that although the table may start out seeming like just a linking table, it may become its own table with significant data.
An example is a many-to-many between magazines and subscribers. Really that link is a subscription with its own attributes, like expiration date, payment status, etc.
However, I think sometimes a linking table is just a linking table. The many to many relationship with categories is a good example of this.
So in this case, a separate one field primary key is not necessary. You could have a auto-assign key, which wouldn't hurt anything, and would make deleting specific records easier. It might be good as a general practice, so if the table later develops into a significant table with its own significant data (as subscriptions) it will already have an auto-assign primary key.
You can put a unique index on the two fields to avoid duplicates. This will even prevent duplicates if you have a separate auto-assign key. You could use both fields as your primary key (which is also a unique index).
So, the one school of thought can stick with integer auto-assign primary keys, and avoids compound primary keys. This is not the only way to do it, and maybe not the best, but it won't lead you wrong, into a problem where you really regret it.
But, for something like what you are doing, you will probably be fine with just the two fields. I'd still recommend either making the two fields a compound primary key, or at least putting a unique index on the two fields.
I would go with the 2nd junction table. But make those two fields as Primary key. That will restrict duplicate entries.

How can I share the same primary key across two tables?

I'm reading a book on EF4 and I came across this problem situation:
So I was wondering how to create this database so I can follow along with the example in the book.
How would I create these tables, using simple TSQL commands? Forget about creating the database, imagine it already exists.
You've been given the code. I want to share some information on why you might want to have two tables in a relationship like that.
First when two tables have the same Primary Key and have a foreign key relationship, that means they have a one-to-one relationship. So why not just put them in the same table? There are several reasons why you might split some information out to a separate table.
First the information is conceptually separate. If the information contained in the second table relates to a separate specific concern, it makes it easier to work with it the data is in a separate table. For instance in your example they have separated out images even though they only intend to have one record per SKU. This gives you the flexibility to easily change the table later to a one-many relationship if you decide you need multiple images. It also means that when you query just for images you don't have to actually hit the other (perhaps significantly larger) table.
Which bring us to reason two to do this. You currently have a one-one relationship but you know that a future release is already scheduled to turn that to a one-many relationship. In this case it's easier to design into a separate table, so that you won't break all your code when you move to that structure. If I were planning to do this I would go ahead and create a surrogate key as the PK and create a unique index on the FK. This way when you go to the one-many relationship, all you have to do is drop the unique index and replace it with a regular index.
Another reason to separate out a one-one relationship is if the table is getting too wide. Sometimes you just have too much information about an entity to easily fit it in the maximum size a record can have. In this case, you tend to take the least used fields (or those that conceptually fit together) and move them to a separate table.
Another reason to separate them out is that although you have a one-one relationship, you may not need a record of what is in the child table for most records in the parent table. So rather than having a lot of null values in the parent table, you split it out.
The code shown by the others assumes a character-based PK. If you want a relationship of this sort when you have an auto-generating Int or GUID, you need to do the autogeneration only on the parent table. Then you store that value in the child table rather than generating a new one on that table.
When it says the tables share the same primary key, it just means that there is a field with the same name in each table, both set as Primary Keys.
Create Tables
CREATE TABLE [Product (Chapter 2)](
SKU varchar(50) NOT NULL,
Description varchar(50) NULL,
Price numeric(18, 2) NULL,
CONSTRAINT [PK_Product (Chapter 2)] PRIMARY KEY CLUSTERED
(
SKU ASC
)
)
CREATE TABLE [ProductWebInfo (Chapter 2)](
SKU varchar(50) NOT NULL,
ImageURL varchar(50) NULL,
CONSTRAINT [PK_ProductWebInfo (Chapter 2)] PRIMARY KEY CLUSTERED
(
SKU ASC
)
)
Create Relationships
ALTER TABLE [ProductWebInfo (Chapter 2)]
ADD CONSTRAINT fk_SKU
FOREIGN KEY(SKU)
REFERENCES [Product (Chapter 2)] (SKU)
It may look a bit simpler if the table names are just single words (and not key words, either), for example, if the table names were just Product and ProductWebInfo, without the (Chapter 2) appended:
ALTER TABLE ProductWebInfo
ADD CONSTRAINT fk_SKU
FOREIGN KEY(SKU)
REFERENCES Product(SKU)
This simply an example that I threw together using the table designer in SSMS, but should give you an idea (note the foreign key constraint at the end):
CREATE TABLE dbo.Product
(
SKU int NOT NULL IDENTITY (1, 1),
Description varchar(50) NOT NULL,
Price numeric(18, 2) NOT NULL
) ON [PRIMARY]
ALTER TABLE dbo.Product ADD CONSTRAINT
PK_Product PRIMARY KEY CLUSTERED
(
SKU
)
CREATE TABLE dbo.ProductWebInfo
(
SKU int NOT NULL,
ImageUrl varchar(50) NULL
) ON [PRIMARY]
ALTER TABLE dbo.ProductWebInfo ADD CONSTRAINT
FK_ProductWebInfo_Product FOREIGN KEY
(
SKU
) REFERENCES dbo.Product
(
SKU
) ON UPDATE NO ACTION
ON DELETE NO ACTION
See how to create a foreign key constraint. http://msdn.microsoft.com/en-us/library/ms175464.aspx This also has links to creating tables. You'll need to create the database as well.
To answer your question:
ALTER TABLE ProductWebInfo
ADD CONSTRAINT fk_SKU
FOREIGN KEY (SKU)
REFERENCES Product(SKU)