tags from multiple tables - mysql

From what I understand relational databases are ill-equipped to handle polymorphic relationships, but is there any easy way of integrating multiple tables into one tags table. Basically what I want to achieve is to have one tags table, but have the tag names derived from 1 of 3 table (games, platforms or companies). See the below design as a mock-up:
Am I looking at this from the wrong way or am I on the right track? Is there a different approach someone would suggest?

Your case sounds like a mismatch between relational modeling and object modeling. If you are interested in designing relational tables that provide the closest thing to inheritance (not polymorphism) then look up the questions, answers, and info under these tags:
single-table-inheritance class-table-inheritance
If you're interested in more detail, look up Martin Fowler's handling of the same techniques.
If your interest is in diagramming the IS-A relationship between games, platforms, or companies and some unnamed superclass that I'll call "Tag Providers" , then look up "EER generalization/specialization". (EER stands for Enhanced Entity Relationship). This shows how to diagram the relationship, without providing any details about how to implement it.

You are correct as there is Many to many relationship between article,video & tags.
See,
One article => with => Many tags
One tag => belongs to => Many articles .
So to preserve mapping 3rd,4th mapping table is necessary .
3rd Table will have relationship between Article+Tags
4th Table will have relationship between Video+Tags
Update =>
For other tables to relate with Tags table , Make 3 more tables :
5th Table will have relationship between Company+Tags => companies_tags
6th Table will have relationship between Game+Tags => games_tags
7th Table will have relationship between Platform+Tags => platforms_tags

Related

Proper data and use of pivot tables

Maybe better as DBA question...
We have a Laravel/MySQL system. We have 4 model types that are also tables, Categories, Stars, Studios and Videos. Contractors set up pivot tables for each of these model types to house multiple many-to-many relationships to each other. The pivot tables are categoryables, studioables and videoables. These each contain the same structure (categoryables as an example):
id, category_id, categoryable_type ('App\Models\Video'), categoryable_id (ID of model type), created_at, updated_at
The current model types we have in each of those pivot tables are:
Categoryables: Star, Studio and Video
Studioables: Star
Videoables: Star, Studio
My questions are:
I know Laravel's pivot table naming convention is normally like category_video, so is appending "able" also a proper naming convention?
Are these even pivot tables, or are they called something else considering they're set up to have multiple data model types, eliminating a simple relationship of just two tables?
What is the best way to house our data for multiple many-to-many relationships? Each model type has a page on our front end, ie. going to a category shows a list of stars, studios and videos. Going to a studio shows a list of categories, stars, and videos, etc. There are 4 possible set ups I can think of:
3a. videoables table is all we use and it has relationships to
stars, studios and videos model types.
3b. We use categoryables, starables and studios only (calling them
category_video, star_video, studio_video) and each of them only has
a relationship to the video model type.
3c. We use all 4 pivot tables and they each contain all of the
relationships to the other 3 model types. This seems like a lot of
bloat and redundancy.
3d. Somewhere in between 3b and 3c. Some sort of perfect combination
of relationships that enhances query speed and performance without
suffering from table bloat and redundant data.
Thanks!
A many-to-many relationship needs an extra "mapping" or "junction" table. ("Pivot" may be used here, but is confusing since it has an unrelated meaning relating to transposing between rows and columns.)
Details on optimal implementation of a Many-to-many table. (I do not know whether Laravel is efficient here.)
Yes, it sometimes makes sense to have a table with 3 ids instead of just 2.
For further discussion, please provide the CREATE TABLEs of one 2- or 3-way relationship table.

Translating UML aggregation in a relational database

I'm making a JavaFX desktop application. It's a Point of sale system that tracks orders in a restaurant. I am very new to this and things got confusing after I fired up my phpmyadmin to create my database.
This is the relevant part of my UML :
Some examples to clarify the tables' content :
Ingredient table may contain : Flour, sugar, beef, eggs...
ArticleMenu table may contain : Pizza, Burger...
ArticleMenu is made of a bunch of ingredients , but these ingredient can still exist on their own, so it's an aggregation I thought.
The issue is to translate this into a relational database, and especially the aggregation.
What I tried :
in ArticleMenu, the 'recette' attribute is a FK that refrences a row from Ingredient table, the 'recette' attribute is of type ENUM , which can hold many values the user defines when creating a row in ArticleMenu.
Example :
ArticleMenu table has a row that represents let's say Pizza, one of it's attributes is recette of type ENUM and has the values "Cheese, flour, yeast, onions, tomato, mushroom, oil"
My question :
is this an acceptable way of representing an aggregation and what would be the most optimal way?
Edit :
After reading Christophe's answer it's clear that I did not
understand what ENUM is.
The IBM document he linked cleared a lot of confusion I had relating
to this topic.
Stock information shouldn't be part of the ingredient table since
there could be many states of the same ingredient, so I removed
those.
As for the quantities used in each recipie, those will be represented
using the quantity attribute from the recipie table.
So I re-thoought my approach and came up with this design:
Problem with your approach
You implemented what Martin Fowler calls a foreign key mapping, which implements a one to (potentially) many relationship:
Here, Recipe ('recette') would implement a many-to-one relationship between ArticleMenu and Ingredients: one article would have only one ingredient, and one ingredient can appear in many articles.
Moreover the ENUM lets you chose for one row only one value among severals. The ENUM is in fact just a handy replacement for using a number instead of a string.
So, no, it's not the right approach.
Many-to-many association and the hidden table
What you need is to implement a many-to-many association: each ArticleMenu could have many Ingredients, and conversely each Ingredient could be used in many ArticleMenu.
In an RDBMS, this can be implemented using an association table. It's a table taht is not visible in your conceptual model. This association table could for example be called Recipe and have two columns: idArticleMenu and idIngredient. You can then find:
all the ingredients of an article, by looking for every recipe row that has the relevant idArticleMenu.
all the articles in which an ingredient is used, by searching for the idIngredient
Completing your model
Now if you speak of recipe and flour, the next question in your application would be: how many flour do I need to make 1 pizza ?
Unfortunately, this Quantity is not a property of ArticleMenu, since every ingredient of the same article could have a different quantity. It is not either a property of Ingredient, since an ingredient is used with different quantities, depending on the article for which it is used. So where to put this ?
The answer is an association class
Additional advice
You can use the aggregation to express the whole-part relationship. However the aggregation semantic is not clearly defined in the UML specification. So there is no fundamental benefit in using it. You could therefore use a normal association here.
In a design model (conceptual), you should not show in a class the properties that implement a relation. You could show the name of such properties at the other end of the association it will implements. If an implementation model, you could very well show all the columns of a table. The usual practice is then to use a «table» stereotype for each class that would be mapped to a table.

Converting n to m relationship with specialization to relational model

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.

How to spot the relationship in RDBMS?

I was studying about relationships in RDBMS.I have understood the basic concept behind mapping relation ship,but I am not able to spot them.
The three possibilities :
one to many(Most common) requires a PK - FK relationsip.Two tables involved
many to many(less common) requires a junction table.Three tables Involved
one to one(very rare). One table involved.
When I begin a project,I am not able to separate the first two conditions and I am not clear in my head.
Examples when I study help for a brief moment,but not when I need to put these principles in to practice.
This is the place where most begineers falter.
How can I spot these relationships.Is there a simpler way?
Don't look at relationships from a technical perspective. Use analogies and real-life examples when trying to envision relationships in your head.
For example, let's say we have a library database.
A library must have books.
M:M
Each Book may have been written by multiple Authors and each Author may have written multiple Books. Thus it is a many-to-many relationship which will reflect into 3 tables in the database.
1:M
Each Book must also have a Publisher, but a Book may only have one Publisher and a Publisher can publish many Books. Thus it is a one-to-many relationship and it reflects with the PublisherId being referenced in the Books table.
A simple analogy like this one explains relationships to their core. When you try to look at them through a technical lens you're only making it harder on yourself. What's actually difficult is applying real world data scenarios when constructing your database.
I think the reason you are not getting the answers that you need is because of the way you are framing the question. Instead of asking “How do I spot the correct type of relationship between entities”, think about “How do my functional needs dictate what relationship to implement”. Database design doesn’t drive the function; it’s the functional needs that drive the relationships you need to implement.
When designing a database structure, you need to identify all the entities. Entities are all the facts that you want to store: lists of things like book titles, invoices, countries, dog species, etc. Then to identify your relationships, you have to consider the types of questions you will want to ask your database. It takes a bit of forward thinking sometimes… just because nobody is asking the question now doesn’t mean that it might not ever be asked. So you can’t ask the universe “what is the relationship between these lists of facts?” because there is no definitive answer. You define the universe… I only want to know answers to these types of questions; therefore I need to use this type of relationship.
Let’s examine an example relation between two common entities: a table of customers and a table of store locations. There is no “correct” way to relate these entities without first defining what you need to know about them. Let’s say you work for a retailer and you want to give a customer a default store designation so they can see products on the website that their local store has in stock. This only requires a one-to-many relationship between a store and the customer. Designing the relationship this way ensures that one store can have many customers as their default and each customer can only have one default store. To implement this relationship is as easy as adding a DefaultStore field to your Customer table as a foreign key that links to the primary key of the Store table.
The same two entities above might have alternate requirements for the relationship definition in a different context. Let’s say that I need to be able to give the customer the opportunity to select a list of favorite stores so that they can query about in stock information about all of them at once. This requires a many-to-many relationship because you want one customer to be able to relate to many stores and each store can also relate to many customers. To implement a many-to-many relationship requires a little more overhead because you will have to create a separate table to define the relationship links, but you get this additional functionality. You might call your relationship table something like CustomerStoreFavorites and would have as its primary key as the combined primary keys from each of the entities: (CustomerID, StoreID). You could also add attributes to the relationship, like possibly a LastOrderDate field to specify the last date that the customer ordered something from a particular store.
You could technically define both types of relationships for the same two entities. As an example: maybe you need to give the customer the option to select a default store, but you also need to be able to record the last date that a customer ordered something from a particular store. You could implement the DefaultStore field on the Customer table with the foreign key to the Store table and also create a relationship table to track all the stores that a customer has ordered from.
If you had some weird situation where every customer had their own store, then you wouldn’t even need to create two tables for your entities because you can fit all the attributes for both the customer and the store into one table.
In short, the way you determine which type of relationship to implement is to ask yourself what questions you will need to ask the database. The way you design it will restrict the relational data you can collect as well as the queries you can ask. If I design a one-to-many relationship from the store to the customer, I won’t be able to ask questions about all the stores that each customer has ordered from unless I can get to that information though other relationships. For example, I could create an entity called "purchases" which has a one-to-many relationship to the customer and store. If each purchase is defined to relate to one customer and one store, now I can query “what stores has this customer ordered from?” In fact with this structure I am able to capture and report on a much richer source of information about all of the customer's purchases at any store. So you also need to consider the context of all the other relationships in your database to decide which relationship to implement between two particular entities.
There is no magic formula, so it just takes practice, experience, and a little creativity. ER Diagrams are a great way to get your design out of your head and onto paper so that you can analyze your design and ensure that you can get the right types of questions answered. There are also a lot of books and resources to learn about database architecture. One good book I learned a lot from was “Database System Concepts” by Abraham Silberschatz and Henry Korth.
Say you have two tables A and B. Consider an entry from A and think of how many entries from B it could possibly be related with at most: only one, or more? Then consider an entry from B and think of how many entries in A it could be related with.
Some examples:
Table A: Mothers, Table B: Children. Each child has only one mother but a mother may have one or more children. Mothers and Children have a one-to-many relationship.
Table A: Doctors, Table B: Patients. Each patient may be visiting one or more doctors and each doctor treats one or more patients. So they have a many-to-many relationship.
An example of one to one:
LicencePlate to Vehicle. One licence plate belongs to one vehicle and one vehicle has one licence plate.

How to create mysql table with many hasMany association in CakePHP?

I'm defining a completely new database. I have now faced a problem
which I would describe as "usual" but still could not find good
information from web. So here's the problem:
I have many tables in my database (which I would describe as guides) such as:
Skills
Places
Activities
and so on...
Now to all these guide types I'd like to add a comment feature and
other similar features like attaching images and videos. I have many guide types so I dropped the idea of having a separate comment image and video tables for each of them. I need one table for each of them.
The question is, what is the best way to achieve this? I have heard and read about 3 solutions and I'm not familiar with none of them.
I have read about using UUIDs would fix this problem but I'm not very familiar how they function. Could someone elaborate on that if that is the correct way to go? Something about UUIDs I read but not quite understood it.
Other thing I have read about is creating a hierarchial model "tree table" which would hold association links. More info at Managing Hierarchical Data in MySQL.
I have also read about creating object tables and using program like object inheritance inside MySQL in a similar way like the hierarchical model.
UUIDs sound most simple so I would appreciate help in there.
I don't know anything about how to use them. But here's how I thought it works - at least you'll get a hang of it what I'm trying to achieve here and how/what I'm misunderstanding about them:
I would create a new table: Guides which could have UUID field.
Then link all those guide types (Skills etc.) to guide table (Guide as parent and the other as child)
Parent and Child have both UUID fields and when creating a guide Parent and Child gets same UUID so they can be linked. Child also has its own Id field.
Then link comments to Guides by using UUID field that points to Guide plus separate id int field for comments.
Please tell me if this is correct way or is it total garbage and if so, how I should do it?
Have you though about using a normal hasMany relationship with a condition? Read about it here.
class Skill extends AppModel {
var $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'conditions' => array('Comment.type' => 1), // 1 for skills, 2 for places etc. or something like that.
)
);
}
Check http://cakeapp.com, create your DB layout there and download the SQL later.
I read more about UUIDs and since they allow application wide unique IDs I was able to do "inheritance" style of database.
I used my own prefix at the start of the every table name to avoid reserved table name collisions such as object. You can use any kind of prefix, for example: my_ and to use it like: my_object. All tables should use prefixes in this example.
So I created table Objects. It has the id field with Binary(36) type. Cake recognizes it as UUID field. Then I used 1:1 identifying relationships and inherited other tables from it, which I wanted to interact with others.
So I created 1:1 identifying relationship to Comments, Videos, Pictures table so that the table had the identifying foreign key being also a primary key.
Then I created Mappings table to which I used two 1:1 non-identifying relationships without primary key. This means this was really HABTM relationship to self.
Now this let me to "inherit" other tables from Objects table, like News table with again 1:1 identifying relationship. Then it was possible to link Comments, or anything other that has the 1:1 identifying relationship to Object, to News table by using the Mappings table.
I hope this will help others who are pondering this kind of solution aswell.