How to create Oracle Database based on a relational scheme - database

I am a beginner in Oracle databases.
I have a relational diagram and I want to create tables in Oracle, but I don't know how to make the relationships between them and the primary key at each. My teacher say that the tables "patients" and "doctors" have to inherit all the attributes from "Persons" table.
Also, the "prescription" table needs to inherit the attributes from "patients" and "doctors" table. So on with the "prescription" table.
This is the diagram

Everything you need you can find on this page: official oracle docs
Basic syntax of creating simple tables and inheritance of attributes in section "Parallelizing Table Creation".

CREATE TABLE empleat(
emp_no number(6,0) CONSTRAINT fk_empleat PRIMARY KEY,
nom varchar(20) CONSTRAINT nn_empleat_nom NOT NULL,
cognom varchar(20),
departament number(2,0) CONSTRAINT nn_empleat_dept NOT NULL
);
CREATE TABLE departament(
dept_no number(2,0) CONSTRAINT fk_departament_dept_no PRIMARY KEY,
nom varchar(20) CONSTRAINT nn_departament_nom NOT NULL,
localitat varchar2(30),
lider number(6,0) CONSTRAINT nn_departament NOT NULL
);

Not sure why a doctor wouldn't have a date of birth or a gender so you could just merge the people and patients tables
CREATE TABLE people (
id NUMBER CONSTRAINT people__id__pk PRIMARY KEY,
first_name VARCHAR2(250) CONSTRAINT people__first_name__nn NOT NULL,
last_name VARCHAR2(250) CONSTRAINT people__last_name__nn NOT NULL,
phone VARCHAR2(20),
date_of_birth DATE CONSTRAINT people__date_of_birth__nn NOT NULL,
gender CHAR(1) CONSTRAINT people__gender__chk CHECK ( gender IN ( 'M', 'F', 'X', 'Y' ) ),
doctor NUMBER CONSTRAINT people__doctor__fk REFERENCES doctor ( id )
);
CREATE TABLE doctor (
id NUMBER CONSTRAINT doctor__id__pk PRIMARY KEY
CONSTRAINT doctor__id__fk REFERENCES people ( id ),
specialization VARCHAR2(250)
);
My teacher say that the tables "patients" and "doctors" have to inherit all the attributes from "Persons" table.
If by this, they mean that the doctors table has to have all the columns of the people table then this breaks the idea of normalisation. If you are required to do this then it should be implemented as a VIEW rather than duplicating the data.
CREATE VIEW doctor_details IS
SELECT p.*, d.sepcialization
FROM people p
INNER JOIN
doctors d
ON ( p.id = d.id );

Related

Chicken or Egg problem in table schema [PostgreSQL]

How do I create and insert rows to the following table schema in PostgreSQL:
Table: employee
emp_id, emp_name, emp_dept, emp_manager
Table: department
dept_id, dept_name, dept_manager
emp_manager is a foreign key to employee(emp_id)
emp_dept is a foreign key to department(dept_id)
dept_manager is a foreign key to employee(emp_id)
It can work like this:
CREATE TABLE employee (
emp_id int PRIMARY KEY
, emp_dept int NOT NULL
, emp_manager int
, emp_name text NOT NULL
, CONSTRAINT fk_emp_manager FOREIGN KEY (emp_manager) REFERENCES employee(emp_id)
, UNIQUE (emp_dept, emp_id) -- needed for FK fk_dept_manager
);
CREATE TABLE department (
dept_id int PRIMARY KEY
, dept_manager int
, dept_name text NOT NULL
, CONSTRAINT fk_dept_manager FOREIGN KEY (dept_id, dept_manager) REFERENCES employee(emp_dept, emp_id)
);
ALTER TABLE employee
ADD CONSTRAINT fk_emp_dept
FOREIGN KEY (emp_dept) REFERENCES department(dept_id);
Note how I change fk_dept_manager into a multicolumn FK reference to only allow employees of the same department to be department manager. Assuming you want that.
You might also want a CHECK constraint in table employee to disallow employees from being their own manager:
CHECK (emp_manager <> emp_id)
How to INSERT?
As usual. To overcome mutual dependencies, either make FK constraints DEFERRABLE and run multiple commands in a single transaction (more expensive) or use a single command with one or more CTEs.
Example: to insert a new department and a new employee as its manager at once:
WITH ins_dept AS (
INSERT INTO department
(dept_manager , dept_name)
VALUES (nextval(pg_get_serial_sequence('employee', 'emp_id')), 'Sales')
RETURNING *
)
INSERT INTO employee
(emp_id , emp_dept, emp_manager, emp_name)
SELECT dept_manager, dept_id , NULL, 'Bob'
FROM ins_dept;
db<>fiddle here
Further reading:
Complex foreign key constraint in SQLAlchemy
SET CONSTRAINTS ALL DEFERRED not working as expected
How to deal with mutually dependent inserts

Is using specialization for tables which only differ by many-to-many relationships right?

Imagine I have the specialization (teacher, student) and generalization (person) tables with always same properties (in this scenario):
CREATE TABLE person (
id INTEGER PRIMARY KEY,
first_name VARCHAR(50) not null,
last_name VARCHAR(75) not null
);
CREATE TABLE teacher (
person_id INTEGER REFERENCES person (id),
first_name VARCHAR(50) not null,
last_name VARCHAR(75) not null,
PRIMARY KEY (person_id)
);
CREATE TABLE student (
person_id INTEGER REFERENCES person (id),
first_name VARCHAR(50) not null,
last_name VARCHAR(75) not null,
PRIMARY KEY (person_id)
);
CREATE TABLE assigned_exam (
person_id INTEGER REFERENCES person (id),
exam_id INTEGER REFERENCES exam (id),
PRIMARY KEY (person_id, exam_id)
);
CREATE TABLE student_exam (
id INTEGER PRIMARY KEY,
exam_name VARCHAR(50) not null
);
Specialization is normally described with the specialized table having different properties. But in this scenario there is only different many-to-many relationships. The assigned_exam is only applicable if the type is a student.
Now I feel that I have two options:
1. I put everything in the person table since the properties are all the same
2. I split the tables like I have done currently
My concern with option 1 is, I am not able to model the constraints properly.
My concern with option 2 is, I will end up with tables which look exactly the same. It feels wrong.

relationships in ms access do not communicate?

i am building a movie database and i am having some issues with forms in MS Access.
my project in more detail:
1.
2.PostgreSQL code (create tables of ER diagram)
CREATE TABLE People (
birth_date DATE NOT NULL,
last_name CHAR(30) NOT NULL,
name CHAR(30) NOT NULL,
person_id SERIAL,
PRIMARY KEY (person_id) );
CREATE TABLE Roles (
role_id SERIAL,
role_name CHAR(30) NOT NULL,
PRIMARY KEY (role_id) );
CREATE TABLE genre (
genre_name CHAR(30) NOT NULL,
genre_id SERIAL,
PRIMARY KEY (genre_id) );
CREATE TABLE Movies (
movie_id SERIAL,
title CHAR(30) NOT NULL,
rating REAL NOT NULL,
release_date DATE NOT NULL,
PRIMARY KEY (movie_id) );
CREATE TABLE film_people (
role_id INTEGER NOT NULL,
person_id INTEGER NOT NULL,
movie_id INTEGER NOT NULL,
PRIMARY KEY (movie_id, person_id, role_id),
FOREIGN KEY (movie_id) REFERENCES Movies (movie_id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (person_id) REFERENCES People (person_id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (role_id) REFERENCES Roles (role_id) ON DELETE CASCADE ON UPDATE CASCADE);
CREATE TABLE film_genre (
movie_id INTEGER NOT NULL,
genre_id INTEGER NOT NULL,
PRIMARY KEY (movie_id, genre_id),
FOREIGN KEY (movie_id) REFERENCES Movies (movie_id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (genre_id) REFERENCES genre (genre_id) ON DELETE CASCADE ON UPDATE CASCADE);
3.Using pgAdmim4
4.ODBC driver to link with MS ACCESS 10
My job is to design forms in access for insert data to the database.Forms about genre,people,roles is easy.The problem that i am facing is when i want to create a form for example:
1) rating (attribute from movies)
2) title (attribute from movies)
3) release_date (attribute from movies)
4) genre_name (atrribute from genre) <---- problem is here
.Access not importing relationships for SQL linked tables
but the "Enforce Referential Integrity" options are greyed out because that is a function of the database setup at the server, not in Access.
My purpose is to create a form which i am able to insert a movie and the genre of the movie and tables movies,film_gerne to update correctly.
Any idea ?

How to model this many-many relation in Database?

We have two tables ManagementPlan which tells what type of product model has to be used.Based on this model number, a particular product of that type is assigned to a patient during therapy session.How can we model the many-many relation between Product table and ManagementPlan table
MangamentPlan(
PlanID(PK),
DiagnosisID(FK),
PhysicianID(FK),
PMCModelID,
Objective,
Description,
DateTime
)
Product(
PMCProductID(PK),
ManuProductID(FK),
ManufacturerID(FK),
PMCModelID,
Manufacturer model,
Features description,
PurchaseDate,
Storage Location
)
Add a junction table:
ManagementPlanProduct(PlanID(PK, FK(ManagementPlan)), PMCProductID(PK, FK(Product)))
You need a junction table
ManagementPlanProduct (
PlanID (PK, FK)
PMCProductID (PK, FK)
)
CREATE TABLE ManagementPlanProduct (
PlanID int NOT NULL,
PMCProductID int NOT NULL,
CONSTRAINT PK_mpp PRIMARY KEY CLUSTERED (PlanID, PMCProductID)
);
ALTER TABLE ManagementPlanProduct
ADD CONSTRAINT FK_mpp_mp
FOREIGN KEY (PlanID) REFERENCES ManagementPlan (PlanID)
ON DELETE CASCADE;
ALTER TABLE ManagementPlanProduct
ADD CONSTRAINT FK_mpp_p
FOREIGN KEY (PMCProductID) REFERENCES Product (PMCProductID)
ON DELETE CASCADE;
You can also add other columns to the junction table like quantity, date added, sort order and so on.

Many-to-Many association with a twist

I am working on a Spring-MVC application in which I am designing group functionality for doing some common tasks together. So in the application, I have 2 tables, GroupAccount and GroupMembers. GroupMembers has a foreign key relation with GroupAccount. The email-address from GroupMembers is used by Spring-Security for Login. I will post the SQL code at bottom.
Currently with this architecture, A groupMember can be a part of only one GroupAccount. This is not what I want to implement. A groupMember can be a part of multiple GroupAccount. I know you will think many-to-many, but that means replicating the groupAccount or the groupMembers row, but I just want an association. So a single groupMember can be a part of Many groupAccounts and vice-versa, without creating duplicate rows as Spring-Security is involved. I hope I am making it clear. Any suggestions or ideas how to achieve this? If my post is not clear, just tell me, I will make my best effort to explain.
SQL code :
CREATE TABLE GroupAccount (
groupid NUMERIC NOT NULL,
groupName VARCHAR,
adminPassword VARCHAR,
CONSTRAINT groupid PRIMARY KEY (groupid)
);
CREATE TABLE groupmembers (
memberid NUMERIC NOT NULL,
musername VARCHAR,
mpassword VARCHAR,
groupid NUMERIC NOT NULL,
CONSTRAINT memberid PRIMARY KEY (memberid)
);
ALTER TABLE groupmembers ADD CONSTRAINT groupaccount_groupmembers_fk
FOREIGN KEY (groupid)
REFERENCES GroupAccount (groupid)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE;
Any pointers are welcome. Thank you very much.
Unless I'm missing something, you create a junction table for a many to many relationship.
CREATE TABLE GroupAccount (
groupid NUMERIC NOT NULL,
groupName VARCHAR,
adminPassword VARCHAR,
CONSTRAINT groupid PRIMARY KEY (groupid)
);
CREATE TABLE GroupMembers (
memberid NUMERIC NOT NULL,
musername VARCHAR,
mpassword VARCHAR,
CONSTRAINT memberid PRIMARY KEY (memberid)
);
CREATE TABLE AccountMembers (
groupid NUMERIC NOT NULL,
memberid NUMERIC NOT NULL,
PRIMARY KEY (groupid, memberid),
UNIQUE INDEX (memberid, groupid)
);
I don't think the syntax is correct for AccountMembers, but I hope you get the idea.

Resources