I'm taking a class on database management systems (absolute beginner) and I'm working on a database for a very simple blog system.
I have a question regarding one M:N relationship between blog posts and categories where the posts belong (one blog posts can be in several categories.)
The part of the scheme looks like this:
Scheme
I know that somehow this scheme allows to add a blog post that doesn't belong to any category. However, I don't know why that is. Could someone please explain this to me?
Thanks.
It's probably a combination of two things. One would be a lack of referential integrity in your database design, ie you need foreign keys. The other would be that your front end application is allowing blogs without categories to be posted.
Because you can add a blog_posts record without having to add an associated post_cat record.
Related
I am aware of database relations, I was taught similar like this below:
I am developing an web apps with strapi cms, in there I can see some relations those are not named academic like one to one, one to many etc. vice-versa. Instead they used has one, belongs to many something like this. Not only strappy, I have also encountered this in some other ORM documentations as well. Which is completely okay, but I am not understanding to relate with the above image.
In stripy also the relational symbols are different than the above image.
For example:
Has One:
Has and belongs to one
Belongs to many
Has Many
Has and belongs to many
Has many
I need to know these phrases to relate, is one to many similar to has many?, is one to one similar to has one? etc. Also, what is the benefit of use these phrases rather than one to one etc.? Is it a topic in DB systems I may be missed?
There are lots of different notations for describing relationships, each with its own vocabulary. There’s a reasonable description of them here.
On top of these, individual products may use their own, non-standard, notations
I have seen an article in Dzone regarding Post and Post Details (two different entities) and the relations between them. There the post and its details are in different tables. But as I see it, Post Detail is an embeddable part because it cannot be used without the "parent" Post. So what is the logic to separate it in another table?
Please give me a more clear explanation when to use which one?
Embeddable classes represent the state of their parent classes. So to take your example, a StackOverflow POST has an ID which is invariant and used in an unbreakable URL for sharing e.g. http://stackoverflow.com/q/44017535/146325. There are a series of other attributes (state, votes, etc) which are scalar properties. When the post gets edited we have various versions of the text (which are kept and visible to people with sufficient rep). Those are your POST DETAILS.
"what is the logic to separate it in another table?"
Because keeping different things in separate tables is what relational databases do. The standard way of representing this data model is a parent table POST and child table POST_DETAIL with a defined relationship enforced through a foreign key.
Embeddable is a concept from object-oriented programming. Oracle does support object-relational constructs in the database. So it would be possible to define a POST_DETAIL Type and create a POST Table which has a column declared as a nested table of that Type. However, that would be a bad design for two reasons:
The SQL for working with nested tables is clunky. For instance, to get the POST and the latest version of its text would require unnesting the collection of details every time we need to display it. Computationally not much different from joining to a child table and filtering on latest version flag, but harder to optimise.
Children can have children themselves. In the case of Posts, Tags are details because they can vary due to editing. But if you embed TAG in POST_DETAIL embedded in POST how easy would it be to find all the Posts with an [oracle] tag?
This is the difference between Object-Oriented design and relational design.
OO is strongly hierarchical: everything is belongs to something and the way to get the detail is through the parent. This approach works well when dealing with single instances of things, and so is appropriate for UI design.
Relational prioritises commonality: everything of the same type is grouped together with links to other things. This approach is suited for dealing with sets of things, and so is appropriate for data management tasks (do you want to find all the employees who work in BERLIN or whose job is ENGINEER or who are managed by ELLIOTT?)
"give me a more clear explanation when to use which one"
Always store the data relationally in separate tables. Build APIs using OO patterns when it makes sense to do so.
I have to design a database for an advert site.
Until now this is the design i came up with:
Administrator(Id,Name,Password)
Advert(Advert_Id,Title,Description,Category,User,Date_created,Picture,Type)
User(User_Id, Name ,Phone,email,Address)
Category(Cat_id,Cat_Name)
Type(Id,Type_Name)
Picture(Picture_Id,Name)
The administrator refers to to the person that will manage the site.
The type refers to the type of the advert: selling, buying etc.
I must have minimum 5 tables at least 2 one to many relationships and at least one many to many relationship. The problem is that I can't find a many to many relationship that would make sense.
If an advertisement can have more than one category, then advertisements and category would be many to many.
If an ad can have more than one picture and a picture can be used in more than one ad, ads and pictures would be many to many.
However, you have to know the business rules. None of us will.
Like Dan mentioned on the answer, you have to know the Business Rules. It's a project for a class, so the business rules might be flexible, I remember back in college, for example, they would tell us that if a client wanted to have advertisement be of at least one category, but could have up to 3 or 4 different categories, that changes your DB structure a lot.
An advertisement can also have many pictures, not just one. It can even have some videos, and many of them as well. Make sure you clarify well the Business Rules and that you understand them fully, as in a real life situation, that can represent either the success of your project or the failure of it.
In the project I'm developing I've got several "common objects" that span and associate several other tables.
Think, for example, at the object "Comment". It should be applicable to many kind of different objects: a photo, an action, an event... and it always haves the same structure (author, text, insertion_time, ...)
The first solution I adopted was to have separate tables for each kind of comment: PhotoComments, EventComments and relate those to pertinent objects with a one-to-many relationship with (for example) a photo_id column.
The second (and current one) consist in having a single Comments table (each with its own id) and have as many as needed "many-to-one" support tables to relate those comments with (ie) their photo.
Are there any downsides in having such a design?
If you load the data a comment belongs to, and then look for comments assigned to it, then a single comments, with a one to many works well.
If however you want to find the entity a comment belongs to then one to many tables becomes painful, as you have to look through all the link tables to find what a comment belong to. Of course you could add another column to your comments table to indicate what entity type it belongs to and then you know which link table to go to. From the sounds of things your comments don't belong to multiple entities, which removes that complication.
I'd go with the single comments table (and probably move author to a table of its own, so you can easily see which comments belong to one author, without duplicating the author information in each record)
One downside I can think of comes from table locking.
Say there is a query for a photo comment. Depending on your setup, the table could lock in order to retrieve this photo comment. Then say another query comes for an action comment. If the table is locked down for the photo comment, this new query has to wait for it to complete.
Depending on the size of the table and how often queries are done for data in it, this table could become a performance bottleneck within your schema. If you don't think this could become an issue, then doing a single table can be easier to maintain. However, if there will be a lot of contention for comments, then splitting up the tables will help you out.
I read up on database structuring and normalization and decided to remodel the database behind my learning thingie to reduce redundancy.
I have different types of entries that can be learned. Gap texts/cloze tests (one text, many gaps) and simple known-unknown (one question, one answer) types.
Now I'm in a bit of a pickle:
gaps need exactly the same columns in the user table as question-answer types
but they need less columns than question-answer types (all that info is in the clozetests table)
I'm wishing for a "magic" foreign key that can point both to the gap and the terms table. Of course their ids would overlap though. I don't like having both a term_id and gap_id in the user_terms, that seems unelegant (but is the most elegant I can come up with after googling for a while, not knowing what name this pickle goes by).
I don't want a user_gaps analogue to user_terms, because then I'd be in the same pickle when it comes to the table user_terms_answers.
I put up this cardboard cutout collage of my schema. I didn't remove the stuff that isn't relevant for this question, but I can do that if anyone's confusion can be remedied like that. I think it looks super tidy already. Tidier than my mental concept of this at least.
Did I say any help would be greatly appreciated? Answerers might find themselves adulated for their wisdom.
Background story if you care, it's not really relevant to the question.
Before remodeling I had them all in one table (because I added the gap texts in a hurry), so that the gap texts were "normal" items without answers, while the gaps where items without questions. The application linked them together.
Edit
I added an answer after SO coughed up some helpful posts. I'm not yet 100% satisfied. I try to write views for common queries to this set up now and again I feel like I'll have to pull application logic for something that is database turf.
As mentioned in the comment, it is hard to answer without knowing the whole story. So, here is a story and a model to match. See if you can adapt this to you example.
School of (foreign) languages offers exams for several levels of language proficiency. The school maintains many pre-made tests for each level of each language (LangLevelTestNo).
Each test contains several (many) questions. Each question can be simple or of the close-text-type. Correct answers are stored for each simple question. Correct terms are stored for each gap of each close-text question.
Student can take an exam for a language level and is presented with one of the pre-made tests. For each student exam, the exam form is maintained which stores students answers for each question of the exam. Like a question, an answer may be of a simple of of a close-text-type.
After editing my question some Stackoverflow started relating the right questions to me.
I knew this was a common problem, but I really couldn't find it, just couldn't come up with the right search terms, I guess.
The following threads address similar problems and I'll try to apply that logic to my own design. They all propose adding a higher-level description for (in my case terms and gaps) like items. That makes sense and reflects the logic behind my application.
Relation Database Design
Foreign Key on multiple columns in one of several tables
Foreign Key refering to primary key across multiple tables
And this good person illustrates how to retrieve the data once it's broken up across tables. He also clues me to the keyword class table inheritance, so now I know what to google.
I'll post back with my edited schema once I've applied this. It does seem more elegant like this.
Edited schema