Database Parent-Child Relationship - mysql

Can a parent table be a child table of its child table?
For example, if there are only two tables that are linked so one is parent, and another one is child. Can the parent table be a child table and vice versa?

Yes.
Say you have classes and teachers.
Teacher table can have a ClassID; Class can have a TeacherID. It may / may not make any sense depending on the model, but on the database level it's certainly possible.

It's like you want, so yes you can : you'll have to use join and alias to get back your data properly.
If you only get a A-B-A relationship it's OK, but be careful with recursive relationship when you don't have a fixed deep as, it's a big pain to get back everything on a single query (take a look a the Tree pattern and other specific DB structure, it can be a better choice).

Related

Access Automatically find matches and link after flat file import

I'm building an Access Database, and I'm a database design rookie. I have two tables, we'll call them Parent and Child. These tables represent a one-to-many relationship in the direction that one Parent can have many children. This data comes to us in the form of a flat file that we import the initial parent-child relationship. Later, we manually add other child relationships to the parent as situations demand.
When I do the initial flat file import, I bring in a unique identifier that I place into both the parent and child. My understanding is this type of duplication is poor database design because it's duplicative. I want to avoid this if I can. I can't think of another way to draw the link.
The other question I have, is, it is my understanding that it is best to use the AutoNumber primary key to do any database references. 1. Am I just wrong here? 2. Is it okay to use the unique identifier that I bring in with the flat file? 3. If it is bad design to bring in the duplicative data, is there a way, during the import process, to draw this link automagically to the Primary Key (I already have a macro on this import process to tie it to a user form, adding to this macro is not an issue)?
The purpose of this:
There is a subform on the parent record that should list any related child records in the child record database.
It would be a lot easier if you had provided a simple example.
If your data already contain IDs, example:
P:1,XX,YY
C:1,1,blah
C:1,2,fuh
P:2,zz,ww
C:2,1,doh
..then it would be next to impossible to match to autonumbering.
Either skip the ID completely, or if it's important, make the ID a different column and just use autonumber to make sure records are different.
So that master is
AutoID, PID, F1, F2,...
and child is
AutoID, ParentID, ChildID, FC1, FC2, ...
then match parent.PID onto child.ParentID.
If there is only ever 1 parent per child, you can set Parent.PID to "unique".
In the end, I just imported the unique record to both the parent and the child and used that. It's working great. It changed how I built my manual new child record creation process, but it all works now.

Properly join 2 tables with multiple result

I have 2 tables that needs to be joined wherein both of them can have as many of the other table.
A resident can have as many as relative and the relative can have as many as resident.
I need your opinion if this is a good way to join them properly. What I've done is I have a separate table that saves their respective ids.
I've attached a picture of reference. Thanks!
table picture
Yes, that is a classic relational implementation for a many-to-many relationship, implemented with an intersection table.

Grounds for having a one to one relationship between tables

If I have two different types of user, Parent and Child. They have identical fields, however a Child has a one to many relationship with exams, a relationship that does not exist for Parents.
Would Parent and Child best be modelled as a single table, or combined?
What if I have two different types of user, Parent and Child. They are the same apart from a child belongs to a school (a school has many children)
again, Would Parent and Child best be modelled as a single table, or combined?
They have identical fields, however a Child has a one to many relationship with exams
Even when fields are the same, different constraints1 means you are dealing with logically separate entities. Absent other factors, separate entities should be put into separate physical tables.
There may, however, be reasons to the contrary. For example, if there is a key that needs to be unique across parents and children combined, or there is another table that needs to reference all of them etc...
If that's the case, then logically both "parent" and "child" are inheriting from the "person", containing the common constraints (and fields). Such "inheritance" can be represented by either storing the whole hierarchy into a single table (and setting unused "portion" to NULL), or by separating all three "classes" into their own tables, and referencing the "base class" from "inherited classes", for example2:
PERSON_ID is unique across all parents and children. In addition to that, OTHER_TABLE can reference it directly, instead of having to separately reference PARENT_ID or CHILD_ID.
1 A foreign key in this case.
2 A very simplified model that just illustrates the point above and does not try to model everything you mentioned in your question
Parent and Child both are Persons without a doubt. You should never put them in seperate tables.
Only time separates them : what if a Child becomes a parent?
A parent easily can have children for that you need a relationship table.
Als a relationship table is the right way to model school membership.
so tables here :
person
is_child_of (many to many, join table) --> relations between persons can be is_parent_of
plain and simple
Remember : being a child is a relation from person to person.
How would you model a grandchild if needed? Yet another table? And a great grandchild?
And supose you are fine with that and you make a lot of tables for a lot of "kind of" relationships, an all of a sudden you want you have to add a field (day of birth) or alter a field format : you have to do it in all your different tables.
You have described three different entities in your question -- Parents, Child(ren), and Exams. You have shows how the three differ in the their relationships to each other.
From everything in your question, I would say that you have three entities and you should set them up as such in your database. That is, Parent and Child should have separate tables.
If the items are modeled differently in your system, I would say that they should be different tables. Just because parents and children both have similar properties (names, ages, etc.), does not mean they will always have the same relationships with other entities in your database. You could have parent and child be in same table with column relating child to parent, but this just leads to awkward self-join queries when trying to represent this relationship. This in itself can become very odd if a child has two parents. So to me you would have a number of different tables:
parent
child
child_to_parent (many-to-many join table)
school
child_to_school (one school to many children)
classes
child_to_classes (many-to-many)
classes_exams (one-to-many table relating exams to classes)
child_to_classes_exams (many-to-many table relating children to exams for specific classes)
* and maybe things like the following
teacher
teacher_to_classes (many-to-many)
Now certainly in your class design (if you are using OOP), you could have child and parent extend from a common "person" class which would handle logic for setting common properties.
I would break children out into a separate table for the simple reason that a parent may have many children (if not now, maybe in the future).
More than the current need, it is also important to consider what may happen in the future even if it doesn't make sense now. You may have two parent users who want to administrate one child and that child's exams.
Consider the most possible future functional requirements and program with them in mind.

Database Design - structure

I'm designing a website with courses and jobs.
I have a jobs table and courses table, and each job or course is offered by a 'body', which is either an institution(offering courses) or a company(offering jobs). I am deciding between these two options:
option1: use a 'Bodies' table, with a body_type column for both insitutions and companies.
option2: use separate 'institution' and 'company' tables.
My main problem is that there is also a post table where all adverts for courses and jobs are displayed from. Therefore if I go with the first option, I would just need to put a body_id as a record for each post, whereas if I choose the second option, I would need to have an extra join somewhere when displaying posts.
Which option is best? or is there an alternative design?
Don't think so much in terms of SQL syntax and "extra joins", think more in terms of models, entities, attributes, and relations.
At the highest level, your model's central entity is a Post. What are the attributes of a post?
Who posted it
When it was posted
Its contents
Some additional metadata for search purposes
(Others?)
Each of these attributes is either unique to that post and therefore should be in the post table directly, or is not and should be in a table which is related; one obvious example is "who posted it" - this should simply be a PostedBy field with an ID which relates another table for poster/body entities. (NB: Your poster entity does not necessarily have to be your body entity ...)
Your poster/body entity has its own attributes that are either unique to each poster/body, or again, should be in some normalized entity of their own.
Are job posts and course posts substantially different? Perhaps you should consider CoursePosts and JobPosts subset tables with job- and course-specific data, and then join these to your Posts table.
The key thing is to get your model in such a state that all of the entity attributes and relationships make sense where they are. Correctly modeling your actual entities will prevent both performance and logic issues down the line.
For your specific question, if your bodies are generally identical in terms of attributes (name, contact info, etc) then you want to put them in the same table. If they are substantially different, then they should probably be in different tables. And if they are substantially different, and your jobs and courses are substantially different, then definitely consider creating two entirely different data models for JobPosts versus CoursePosts and then simply linking them in some superset table of Posts. But as you can tell, from an object-oriented perspective, if your Posts have nothing in common but perhaps a unique key identifier and some administrative metadata, you might even ask why you're mixing these two entities in your application.
When resolving hierarchies there are usually 3 options:
Kill children: Your option 1
Kill parent: Your option 2
Keep both
I get the issue you're talking about when you kill the parent. Basically, you don't know to what table you have to create a foreign key. So unless you also create a post hierarchy where you have a post related to institution and a separate post table relating to company (horrible solution!) that is a no go. You could also solve this outside the design itself adding metadata in each post stating which table they should join against (not a good option either as your schema will not be self documentation and the data will determine how to join tables... which is error prone).
So I would discard killing the parent. Killing the children works good if you don't have too many different fields between the different tables. Also you should bear in mind that that approach is not good to solve issues wether the children can be both: institution and companies but it doesn't seem to be the case. Killing the children is also the most efficient one.
The third option that you haven't evaluated is the keeping both approach. This way you keep a dummy table containing the shared values between the bodies and each of the bodies have a FK to this "abstract" table (if you know what I mean). This is usually the least efficient way but most likely the most flexible. This way you can easily handle bodies that are of both types, and also that are only of type "body" but not a company nor an institution themselves (if that is even possible or might be possible in the future). You should note that in order to join a post to an institution you should always reference the parent table and then join the parent with the children.
This question might also be useful for you:
What is the best database schema to support values that are only appropriate to specific rows?

Should I use a reference table in a one -> many relationship on the same table?

I have a table structure for categories,
Each category can have many children, but can only be a child of one category.
I am deciding whether I should just add a parent_id column to the table, or whether I should add a reference table that just has the parent_id and child_id and maps them together.
If it is important a category can have no parent, in which case it is a root category.
The most common use cases for this table will be:
Selecting one category
Selecting all categories
Selecting all children of a category
Selecting the parent of a category
Selecting the child tree of a category
As far as I can tell there is no benefit of having a reference table for this setup? can anyone see any reason for using a reference table?
If you add a reference table, you create an n:n relationship, which you don't want.
So just add a parent_id to the table.
Make it nullable so you can define a category as the root.
Everything you want to select is quite easy, except for the child tree, but an extra table won't help with that. In Oracle you got connect by to select tree-like data, but MySQL unfortunatly doesn't support that, although alternative solutions are often requested and provided.
There are some obstacles:
Since you cannot make parent_id unique (multiple childs can have the same parent), you will have to add a trigger to enforce only one category being the root, although maybe you can live without that check for the moment.
You could theoretically create a loop: Make a the parent of b, b the parent of c, and c the parent of a. To check if this is the case, you should follow the path to the root. If on that path you'll find any category twice, you're in trouble. I think you could use a trigger to validate this as well, although maybe you can live without that check for the moment. It all depends on how you edit your data, but if you are going to query a full tree, you don't want to get into endless loops because of corrupt data.