I’m trying to map a relational database to an ontology.
I read many approaches like 1 2 and they all agreed to model bridge tables (join table between two tables connected with each other with many-to-many relationship) as follows:
If the bridge table contains exactly two foreign keys without presence of independent attributes, it can be mapped into two object properties, the latter is an inverse of the former.
If the bridge table contains exactly two foreign keys with presence of independent attributes, it should be mapped into separate OWL classes.
With that in mind, if we have two tables: students and courses and the join table contains only three columns:
id, student_id, course_id
we model the ontology with two classes: student and course, and two relationships "object properties" :
student ---study---> course
course ---studied_by---> student
but if the join table contains one independent attribute or more, let's say it contains:
id, student_id, course_id, grade
then a new class should be created in the ontology. we model the ontology with three classes: student, course, student_course and two object properties :
student ---student_has---> student_course
course ---course_has---> student_course
is this the best solution?
This feels like the wrong way of going about knowledge graph creation. This approach constrains you to the schema you have in your DB. Rather than relying on the shared attributes you have in your relational tables, you could start with a blank slate and design the ontology to your downstream use-case.
This paper from Stanford provides 7 clear steps how to create an ontology.. There are also a huge number of ontologies you can adapt to your use-case.
In terms of mapping data into the ontology, you could consider using something like RML.
Related
I have a course entity that can be online or offline and has lessons. Depending on the type, the lesson can have two sets of fields. Datetimes for online courses and sections for offline courses that contain video files and some extra attributes such as 'is_watched' and etc. If we create a Fields table that has keys and values for each lesson, if the course is online those extra attributes for offline courses would have to be null. And if we create both tables for each type of course, we have to define two relations that one of them does not exist, and also we have to check for the type every time we are accessing the fields.
What is the best way to implement these tables and their relations? And how to access those fields based on the type?
you might need to check polymorphic relations in laravel
https://laravel.com/docs/8.x/eloquent-relationships
you could create two tables online/offline courses
the lesson model will have one method "call it courses"
the polymorphic relation will create two columns in lessons table
courseable_id --->id of either table
courseable_id --> name space of either model ex App\Models\OnlineCources or App\Models\OfflineCources
I am designing a database for school management.
Here instead of a single school, there are multiple schools with their own students, classes, teachers and subjects.
Here is the requirements.
• A school can have many classes
• A class can have many sub classes
• Many Students can belong to a section of a class
• Many Teacher can belong to a section of a class
• Many Subjects can belongs to a section of a class
• School wants to manage classes
• School wants to manage sections
• School wants to manage subjects in a section of a class
• School wants to assign a teacher for a subject in a section of a class
• School can assign a student a section of a class
Also, some school can have classes as named One, Two, Three and Some may have First, Second and Third. Also same for sections or sub classes
For entities School and Teacher things are straight forward. Below is my approach for them.
School
--------------
id
name
...
Teacher
--------------
id
school_id
name
But I am facing problem while mapping classes and sections for a school.
I tried to make two other entities classes and sections and give them a foreign key of the school
SchoolClass
-----------------
school_id
class_name
...
SchoolSection
----------------
school_id
section_name
...
For mapping a school's class to all its section I created a junction table, as it will be many to many relationship.
SchoolClassSection
---------------------------------------------------------
school_class_id
school_section_id
But as I mentioned above I also need to add subjects and teachers to a section of the class so tried something like below.
SchoolClassSections
---------------------------------------------------------
school_class_id
school_section_id
subject_id
teacher_id
But now I ended up having four foreign keys in the junction table.
Is there no issues in having more than two foreign keys in a junciton table?
Also, I need to add students too, but I can't now figure it out How to move further for students relation for classes, sections?
One thing I could thing of like below
student
-----------
school_id
school_class_section_id // but if SchoolClassSections can have subject_id and teacher_id too it will become confusing
No, it is not an "antipattern". There are many examples where a junction table might have more than two foreign keys:
A doctor's appointment might have a doctor, a patient, and a clinic.
A retail order might have a customer, a location, and a payment type.
An online subscription might have a customer id, product, payment type, and source.
Those are just some examples from other domains (and they do not even include a date dimension). It is not uncommon for a table to have multiple foreign keys.
I didn't analyze your schema, due to time constaints here.
But there's no problem from either the relational point of view or the SQL point of view with a table or junction table having more than two foreign keys. In fact, that's pretty common.
Some concepts, especially OO concepts, do not fit well with SQL.
SQL has "only":
1:1 relationships (generally this should not be used)
1:many (implement via a link in one table to the other)
many:many (requires a separate 'junction' table)
In each case "1" can degenerate to "0" and "many" can degenerate to "1" or "0". Usually "0" is not represented explicitly but by the absence of rows.
To create schemas:
Think of what "entity" tables to have. (Student, Class, School, etc.)
Create relations, thinking in terms of 1:many and many:many.
Optionally, establish FOREIGN KEYs for the links. (For referential integrity; implicitly creates an INDEX)
Make sure the appropriate columns are INDEXed. (For performance)
Later...
Write the SELECTs, UPDATEs, etc.
Use those queries to decide whether other indexes are needed.
Your question is mainly about the many:many tables.
The basic many:many table has exactly 2 column (links to two other tables)
The basic has two composite indexes (PRIMARY KEY(a,b) and INDEX(b,a))
Sure, make it many:many:many (Not common, but reasonable)
Add columns for attributes about the relations (also not common, but OK)
Add composite indexes for the queries that depend on those attributes (for performance)
More discussion of many:many: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table
I'm finding the best way to convert an eer diagram to the corresponding relational diagram. I have a generalization entity with some specializations which have separate relationships with other entities. The generalization entity has in turn a n-to-m relationsip with an entity. The following drawing clarifies the situation:
Eer diagram with specialization and n-to-m relationship.
As the two specialized entities have separate relationships, I should convert them to two separate tables. Meanwhile, I should create a table modeling the n-to-m relationship which relates the entity 'User' to the entity 'Newsletter' (or better, its specializations). How to cope with this problem? I've not found any useful information.
The only possible solution I thought to was to create two separate tables modeling the n-to-m relationship, one linked to 'User' and 'Programming newsletter' tables, one linked to 'User' and 'Travel newsletter' tables. But I'm looking for opinions for that.
I see no problem. I would implement your diagram using the following tables:
User (nickname PK, name, address)
Newsletter (name PK, supervisor, type)
Subscription (user_nickname PK/FK, newsletter_name PK/FK)
Programming_Newsletter (newsletter_name PK/FK, type FK, language)
Travel_Newsletter (newsletter_name PK/FK, type FK, means_of_transport)
I probably wouldn't use user nicknames / newsletter names as keys since I prefer stable compact identifiers, but that's another topic.
I think there are a couple of ways to go about this.
The simplest one, would be to break the assumption "As the two specialized entities have separate relationships, I should convert them to two separate tables". If you keep your specialisations together in a single table, you can use STI (Single table inheritance) for your generalisation. This approach has a drawback though, which is that your table will have many NULL values for those relationships that do not belong to the concrete specialisation.
The other approach, would be to use CTI (Class Table Inheritance). This approach assumes that there will be a specific table for each specialisation of your generalisation. This would get around the NULL problems, but it can potentially introduce a performance problem due to the fact that your code will need to eagerly join from the generalisation table to the specialisation on almost every single query you make to retrieve them.
I don't quite see the issue in the n-to-m relationship between User and Newsletter. You should be able to have a regular intermediate table that creates the association between the two, since there are no further attributes that complement that relationship.
Trying to implement an ER model where I have entities:teacher,student,papers and relationship: publishes,advises. Both teacher and student can publish a paper but only a teacher can advise a paper. Should I duplicate publishes relationship for both student and teacher or can I make it look like a three-way relationship with having no relationship between teacher and student?
It sounds like you could model it like:
student(student_id, name, etc)
teacher(teacher_id, name, etc)
paper(paper_id, title, text, etc)
contributor(contributor_id, paper_id, contribution_type, contributor_type)
Where contribution type is an enum(publisher,adviser) and similarly contributor type is an enum(teacher,student)... or booleans is_publisher, is_adviser.
The drawback is that this doesn't permit foreign keys from contributor to student/teacher, and you don't have a rigid constraint from advisers to teachers. A table adviser(teacher_id, paper_id) allows a constraint on the advisers, but still doesn't allow constraints or foreign keys on student ids.
Another options might be to break it up as:
teacher_contribution(teacher_id, paper_id, is_adviser)
student_contribution(student_id, paper_id)
which would allow completely constraining the database to the intended model, but could be more difficult to query in some situations.
Any are acceptable. It depends to some extent on your particular application and how you intend to query the data.
I am trying to lay out the concept for a Relational DB and I ran into some conceptual Problems:
If I have multiple discrete Entities that are "nested" in each other/have a hierarchy e.g.:
Bosses can have multiple Employees. These employees have different Projects they do and One Project has again multiple sections.
So
B1-Bn:
E1-En
P1-Pn
Section1 -SectionN
How would that be best mapped in a database?
Or in other words, how is this hierarchy best mapped in a relational db?
Now I have Costumers that interact with these Employees.
They are met by the bosses
Then they decide which employee will work for them.
Then they are assigned Projects, with one or more sections.
How would that be best mapped.
the Relations 1-n, m-n, 1-1: Can they be used for e.g.:
This is a Foreignkey because of the 1-n relationship.
This is a ManytoManyField because of the m-n relationship.
And is there a excellent online tool to better understand/visualize that.
Thanks so much for your time!
You may want to follow a course on relational database design; this subject takes more than a few days to explain or master. But you are on the right track.
The first thing you may be seeing is a hierarchy, but before you know it there will be relationships that aren't hierarchical, so a network is formed.
This is why relational databases do not work with hierarchies.
You identify different types of entities and have one table for each type.
For each entity type you identify the properties of such entities - each property will be a column of the table.
If a property does not have an atomic value, but a structured value, these structured values must be regarded as an entity, and must be given its own table, and the property will be a foreign key referring that table.
In this way, you will form a network of tables linked by foreign keys. This is called an entity-relationship diagram. Many designers advocate creating such a diagram first, without mapping the entity types to tables directly. They allow many-to-many relationships between entity types in the diagram. A foreign key between tables on the other hand is always many-to-1 or 1-to-1. So these designers have an "implementation" step in which they introduce an additional table for each many-to-many relationship. Personally I don't use many-to-many relationships in my diagrams to begin with.