CakePHP: Using a join table on non-HABTM relationship - mysql

I have a relation represented in MySQL that is
Classified belongsTo Category
Category hasMany Classifieds
Previously, I have had Classified.category_id set, but some Classifieds do not have Categories, and many Categories do not have any ads. This relationship is optional.
I have normalized the database to represent the database in a third table, categories_classifieds.
categories_classifieds
----
classified_id (primary, not null)
category_id (not null)
The reason this was normalized this way is to avoid null values, and also to
I am trying to create Models for the database in CakePHP 2, and there does not seem to be support for this simple relationship. Is this possible? Does the categories_classifieds join table need to be made into its own Model?
Thanks in advance for any insight.
Here are crow's-feet notation ER diagrams of the current, and proposed schemas:
http://i.stack.imgur.com/1BBVV.jpg

This is a hasAndBelongsToMany relation.
Make sure to follow cake's conventions though and make a seperate id field as primary key for the connecting model. You may not even need to have a model created for it and let it all to automagic after building the necessary relations in the models.

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.

Solution for decomposing/avoiding Many to Many relationship

As far as I know, there are two options to deal with Many-to-Many relation in a relational database (MySQL, MariaDB) and object-relational database (Postgres)
Common scenario:
---> A Product appears(has) many bills
---> A bill has many products
===> Product (n) ------> (n) Bill
I've googled to find a way to decompose Many-to-Many and here is my result:
Create a lookup table that takes 2 Product_ID and Bill_ID as foreign keys to decompose the Many-to-Many relationship into two One-to-Many. This is fine for both relational and object-relational database
Take advantage of object-relational database data type such as an array, JSON, etc. For example, add product_ids as an array of an integer into Bill table and vice versa (Like this tutorial: http://blog.bguiz.com/2017/postgres-many2many-sql-non-relational/)
So I tried to seek another solution and I found this: https://dba.stackexchange.com/questions/175894/mutually-exclusive-many-to-many-relationships/175908#175908
But it seems unclear to me
So I was wondering any others solution for the object-relational database (Postgres)? any keywords?
I really appropriate your help
Thank you

Is having relationships to a pivot table a good idea?

Suppose we have the following tables:
companies
id
name
...
categories
id
name
category_company
category_id
company_id
Now, for each category the company belongs to we need to store the products they offer for that category. I'm wondering if it's a good idea to add an auto-incrementing primary key to the pivot table and then use that id on the products table as shown below.
category_company
id
category_id
company_id
products
id
category_company_id
name
Is there a better way to handle this? In the real proyect that I'm working on I have 5 more tables that depend on the category company relationship.
There are other approaches to your problem, but yours is correct too. You may or may not have the id in your category_company table, depending on if you are using some specific framework or ORM, but as #AndrewShmig stated you don't need it.
IMPORTANT: Remember you are building many-to-many relationships, so you need to add a primary key or unique compound index to 'category_company' table on columns 'category_id' and 'company_id', even if you are keeping the 'id' column. You don't want the same Company listed twice in a Category, or vice versa.
In MVC model ORM's your approach (with an 'id' in category_company / pivot) is prefered, because you can assign additional information to the relationship itself, treatening your pivot table like another object.
Is not the same, but think of these two cases:
If you are a more Object Oriented programmer, something like the second option may fit your needs (which is kind of what you have), plus you can add extra information for the relationship like 'categorized_by', 'date_of_categorization' or something like that.
*If you have 5+ tables that depend on that relationship (like 'products'), of course handling the relationship in an intermediate table is way better than to have 'category_id' and 'company_id' fields in each of them.
Sources:
http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association
Many-to-many relationships examples

Can a Core Data Relationship Have Attributes

I'm porting a MySQL database to Core Data for a Mac OS app. I have two many to many tables in my database. In addition to containing the foreign keys, there are a few data columns. Is it possible to add attributes to a many to many relationship in Core Data? It doesn't look like it to me. My fallback is to replicate the linkage table in Core Data. Are there any problems doing this?
An example:
A record has one or more artists performing on it.
An artist performs on zero or more records.
The linkage table row contains a foreign key for the record, a foreign key for the artist, the instruments the player performed with, and a notes column that adds additional information such has which track the artist performed on.
You are correct: relationships themselves cannot have attributes. And you are on the right track in modelling the linking table as an intermediate entity. This approach is alluded to in the CoreData Programming Guide section on "Modelling a relationship based on its semantics". In their case, they model a (reflexive) many-many relationship from Person to Person using an intermediate FriendsInfo entity with a ranking attribute.
In your example, you might have a Record entity, an Artist entity, and an intermediate Appearance entity. The Appearance entity would have attributes for Instruments and Notes, and (to-one) relationships to Record and Artist (each with a to-many inverse).
The slight downside is that you have to create the Appearance object in order to link a Record object and an Artist object, rather than just adding them to the relevant relationship. You will also have to watch for uniqueness of the combination of Record/Artist, if that's important to you: by default there could be many Appearances for the same Record and Artist.

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.