database modeling with multiple many-to-many relations - sql

I have 3 entities
workers
students
addresses
Each worker can have multiple addresses. Each student can have multiple addresses. Each address can be the address of x students and y workers.
My question is, how does the best data modeling look like. Implement the many-to-many relation in only one associative table for everything like so:
ID | Address_ID | Worker_ID | Student_ID
where ID is PK and Worker_ID or Student_ID can be null
or 2 tables like so:
Address_ID | Worker_ID
PK is Address_ID and Worker_ID
and
Address_ID | Student_ID
PK is Address_ID and Student_ID
Which option is the best and maybe why?
Thanks in advance.

First of all: it is not good modeling techniques:
Each address can be the address of x students and y workers
There is no need to specify an Address to two or more Students or Workers. If they have same Address you can repeat the Address. Note that: How many Students and Workers have the same Address?
In this case: Redundancy is better that Complexity.
Secondly: Your first approach is wrong (ID | Address_ID | Worker_ID | Student_ID) and make a Nullification trap in database. Your second approach is better.
Thirdly: I offer third approach.
You have Worker and Student tables. So absolutely these tables have common attributes. So You can make another table named it: Person. Then put all common attributes in it. Then you can relate Person with Address (many-to-many or one-to-many)
In this case there is inheritance between Worker and Person (and Student and Person). To Mapping the inheritance to relational model, you can use one-to-one relationship between Worker and Person (and Student and Person). In these one-to-one relationships, it's better to transfer Person_ID to Worker (and Person_ID to Student).

I have some questions.
Why you decided to make an Address table?
How many searches in you system are based on Address fields?
You can use Address as a String field. In database design we change a multi-field field to table in some conditions. The important condition is searching the fields are so much.
For example in Post System or Telephone or Address Finding System, not in regular systems.

Related

Doctors, Patients and Contact information for both

I have two tables DOCTORS and PATIENTS. I want both the doctors and the patients to have contact information (such as telephone numbers, addresses and so on) that aren't fixed. For example we can add multiple phones to either a doctor or a patient.
I thought about creating a separate table e.g. PHONES with fields phoneID, the phone number and a foreign key that points to a contact, such as below:
PHONES
phoneID [pk]
number
contactID [fk]
DOCTORS
docID [pk]
fname
sname
specialization
.
.
.
PATIENTS
patID [pk]
fname
sname
.
.
.
The first problem comes from the fact that the patID and the docID might (and will eventually) have the same value. So relating a phone to one and only one person becomes more difficult.
So far I've thought three possible solutions:
Have custom format primary keys for the doctors and patients. For example doctors could have ids in the form of "d00001", "d00002" and so on, and patients ids like "p00001", "p00002". My concern is this could complicate things unnecessarily.
Another solution would be to keep both doctors and patients in one table, and define if they are a doctor or a patient by using another field.
Create separate PHONE tables for doctors and patients, but that's even more clumsy.
Somehow I think both approaches are not the best. Any advice?
You could introduce a PERSON-table. This is 1:1 related to your doctors and patients (and later maybe to employees, suppliers, institutions, whatever). Let the contacts be related to this person-table.
Application code can model this with inheritance quite easily...
Within your person-table you keep some general information like DisplayName and PersonType (reference to a person-type-table with entries like Doctor, Patient and ...).
Keep this table slim...
If you have to choose out of your own ideas, I'd prefer the second. Keep them in one table and mark them with a type column. Avoid speaking keys...
You are thinking about the relationships wrong.
There is a many to many relationship between person and phone number.
A single person can have many different phone numbers (home, work, mobile, etc.)
A single phone number can be associated with many people (husband, wife, children, co-worker, ...)
I don't see why you need a primary entity with phone number as a primary or alternate key.
I would use 5 tables:
Doctor PK=DoctorID
Patient PK=PatientID
PhoneType PK=PhoneTypeCode
DoctorPhone PK=DoctorID,PhoneTypeCode,PhoneNum
FK1=Doctor.DoctorID
FK2=PhoneType.PhoneTypeCode
PatientPhone PK=PatientID,PhoneTypeCode,PhoneNum
FK1=Patient.PatientID
FK2=PhoneType.PhoneTypeCode
You might consider having distinct DoctorPhoneType and PatientPhoneType tables, given that the phone roles are likely to be different between the two classes of people.

More joins or more columns?

I have a very basic question, which would be a more efficient design, something that involves more joins, or just adding columns to one larger table?
For instance, if we had a table that stored relatives like below:
Person | Father | Mother | Cousing | Etc.
________________________________________________
Would it be better to list the name, age, etc. directly in that table.. or better to have a person table with their name, age, etc., and linked by person_id or something?
This may be a little simplistic of an example, since there are more than just those two options. But for the sake of illustration, assume that the relationships cannot be stored in the person table.
I'm doing the latter of the two choices above currently, but I'm curious if this will get to a point where the performance will suffer, either when the person table gets large enough or when there are enough linked columns in the relations table.
Id' go for more "Normality" to increase flexibility and reduce data duplication.
PERSON:
ID
First Name
Last Name
Person_Relations
PersonID
RelationID
TypeID
Relation_Type
TypeID
Description
This way you could support any relationship (4th cousin mothers side once removed) without change code.
It is a much more flexible design to separate out the details of each person from the table relating them together. Typically, this will lead to less data consumption.
You could even go one step further and have three tables: one for people, one for relationship_types, and one for relationships.
People would have all the individual identifying info -- age, name, etc.
Relationship_types would have a key, a label, and potentially a description. This table is for elaborating the details of each possible relationship. So you would have a row for 'parent', a row for 'child', a row for 'sibling', etc.
Then the Relationships table has a four fields: one for the key of each person in the relationship, one for the key of the relationship_type, and one for its own key. Note that you need to be explicit in how you name the person columns to make it clear which party is which part of the relationship (i.e. saying that A and B have a 'parent' relationship only makes sense if you indicate which person is the parent vs which has the parent).
Depending on how you plan to use the data a better structure may be
a table for Person ( id , name etc )
a table for relationships (person_a_id, person_b_id, relation_type
etc)
where person_a_id and person_b_id relate to id in person
sample data may look like
Person
ID Name
1 Frank
2 Suzy
3 Emma
Relationship
A B Relationship
1 2 Wife
2 1 Husband
1 3 Daughter
2 3 Daughter
3 1 Father
3 2 Mother

sql many to many relationship where do I put type field

If I have the following tables listed below, would I want to put the AddressTypeID in the Address table or the CompanyAddress table?
COMPANY
CompanyID
COMPANYADDRESS
CompanyAddressID
CompanyID
AddressID
ADDRESS
AddressID
ADDRESSTYPE
AddressTypeID
First, stop to think about whether this is really a many-to-many relationship. Will you ever really assign the exact same address record to more than one company? You may be able to simplify your design by eliminating CompanyAddress and adding a CompanyID column directly to Address.
If this truly is a many-to-many relationship, then to answer your original question, keep the AddressTypeID in Address, not in CompanyAddress, since it should be the same type for every company that uses it.

Question on Database Modeling

Tables:
Students
Professors
Entries (there’s no physical table intry in the database for entries yet, this table is on the front-end, so it is probably composed from multiple helper tables if we need them. Just need to create valid erd)
Preambula:
One student can have an association to many professors
One professor can have an association to many students
One entry can have 0,1 or more Students or professors in it.
Professor is required to be associated with one or more students
Student is not required to have an association with any professor
It should be more like this (front-end entry table):
Any professor in this table must have an associated name in the table.( For example Wandy is associated to Alex)
It is not required for student (but possible) to have associated professors in this table
One row (for example Linda (Student), Kelly (Professor),Victor (Professor))
Cannot be associated between each other in any manner.
But it is absolutely fine if Linda associated with David.
The problem is that I do not quite understand how one column can have ids of different tables (And those are multiple!) And do not quite understand how to build valid erd for that.
I will answer any additional questions you need. Thanks a lot!
If you simply want an association between Students and Professors - just make a many-to-many relationship in ERD. In logical (relational) schema it will make an intermediate table with foreign keys to Student and Professor tables.
But from your example it looks like you need to design the DB for your "PeopleEntries", which is not straightforward. ERD seems to have the following entities:
Students(ID, name)
Professors(ID,
name)
PeopleEntries(ID, LoveCats,
LoveDogs, LoveAnts)
Relationships (considering people cannot appear in entries more than once):
Students Many - 1 PeopleEntries
Professors Many - 1 PeopleEntries
Students Many - Many Professors
Relational schema would contain tables (foreign keys according to erd relationships):
Students(ID, name, PeopleEntryID FK)
Professors(ID, name, PeopleEntryID
FK)
PeopleEntries(ID, LoveCats, LoveDogs,
LoveAnts)
StudentProfessor(StudentID FK,
ProfessorID FK)
I don't know how to implement the constraint, disallowing association between people from the same entry, on conceptual level (ER-diagram). On physical level you can implement the logic in triggers or update procedures to check this.
As per my quick understanding,
Create a table with following columns
PersonName
Designation
.....
Create one more table
PersonName
LinksTo
In the second table each person entry will have multiple records based on the relation
You want a junction table:
ID StudentID ProfessorID
0 23 34
1 22 34
2 12 33
3 12 34
In the table above, one professor has 3 students, one student has two professors.
StudentID and ProfessorID should together be a unique index to avoid duplicate relationships.

Storing a hierarchy tree in SQL where each son can have several fathers

I'm trying to store a hierarchical tree in SQL. In my case, the same son can have many fathers (the tree represents a VLSI design where the same cells can be used several times in different designs).
All models I've found on the web describe the employee/manager relationship where each employee has one manager. In my case, the number of fathers can be quite large and if I try to store all of them in a table field, they can exceed the character limit of the field.
Can anyone suggest a better method for storing this tree ?
Thanks,
Meir
One possible way to store this relationship in a relational database would be to create two tables - EMPLOYEE_TABLE and EMPLOYEE_MANAGERS_TABLE
create table EMPLOYEE_TABLE(
emp_id number,
emp_name varchar(200),
primary key(emp_id)
)
create table EMPLOYEE_MANAGERS_TABLE (
id number,
emp_id number,
manager_id number,
primary key(id),
foreign key(emp_id) references employee_table(emp_id),
foreign key(manager_id) references employee_table(emp_id)
)
EMPLOYEE_MANAGERS_TABLE will contain one row per employee_manager relationship.
You can apply the same schema to store the father-son relationship where a son can have more than 1 father.
Use a link table. I'm going to assume you are talking about people and will use that vernacular.
You have a person_table listing all the people and their respective id's. You then have a father_son_table describing the links between each person. Eg.
person_table
id | Name
1 | Matthew
2 | Mark
3 | Luke
4 | John
Say Matthew is Mark's father and Mark was father to Luke and John. In the father_son_table you would have:
father_son_table
id | father_id | son_id
1 | 1 | 2
2 | 2 | 3
3 | 2 | 4
Here you can define as many fathers and sons as you wish.
the number of fathers can be quite large and if I try to store all of them in a table field
eh? Your data is not normalised if you're trying to put multiple values in the same field.
While you say its hierarchical this usually implies that a node has a single 'parent' and 0 or more descendants. If that's not the case then its NOT a hierarchical data model - its a M:N relationship.
Or do you mean that there each node exists in more than one hierarchy?
The question is imposible to answer unless you provide an accurate description of the relationship between records.
You find some clever methods for tree handling in the book of Joe Celko:
http://www.amazon.com/Joe-Celkos-SQL-Smarties-Programming/dp/1558605762
...however, I don't know if it covers your problem
You might want to consider what queries you will most frequently be running against this table. Different strategies for storing hierarchies have advantages / disadvantages based on how the hierarchy is used.
Also, any single-parent strategy for storing a hierarchy could be adapted to handle multiple parents simply by treating each element of the tree as a pointer. Pointers under different parents could each point to the same record.
I would go for additional many-to-many connection table with father_id and son_id columns.