Let's say I have two models, songs and users, and I want to let users favorite songs.
One way to do this would be to create a join table between users as songs, let's call it favorites. Each row of this table would just have a user id and song id and its own id. I have some experience with this method and it works fine as far as I know.
However, I was thinking that a second way you could implement favorites would be adding a column onto the user model that consists of an array of song ids. Each id would match a song that the user had favorited.
I'm wondering which of these solutions is preferable and why.
If your site have huge amount of traffic then you should go with materialized views database design concept.
Related
I am having difficulty querying for possible relationships in a Many:Many scenario.
I present my schema:
What I do know how to query with this schema is:
All Bands that a given User belongs to.
All Users that belong to a given Band.
What I am trying to do is:
Get all Band Members across all Bands that a given User belongs to.
ie, say I am in 5 bands, I want to know who all of my bandmates are.
My first questions are:
Is there a name for this type of query? Where I am more interested in the joined relationships than what I am joined to (just saying that made me want to put this whole system into a Graph DB :/ )? I'd like to learn proper terminology to help me google for problems down the road.
Is this a terrible idea in RDBMS land in general? I feel like this should be a common use case but I want to know if I'm totally approaching this wrong.
To recap:
I am looking to query the above schema with the expected output being one row per User as Band Members that a given User shares a Band with.
Terminology
Your terminology seems to be correct - "many to many", often written as "many:many" with a colon. Sometimes the middle table (band_members) is called the "bridge table".
You can probably drop band_members.id, since the two foreign keys also make up a composite primary key (and the primary key can actually be defined that way, since normally a User cannot be a member of the same Band twice. The only exception to that is if a User could have more than one role in the same Band).
Solution
On the surface of it, this sounds easy - we can see the relationships of the tables, and one would normally just use an INNER JOIN between them. There are three tables, so that would be two joins.
However, we have to conceptualise the problem correctly first. The problem we have is that the join between Users and Band Members (user ID) is actually to be used for two things:
which User is in what Band
filtering by User
So to do this we need to introduce one table with multiple purposes:
SELECT
Users.first_name, Users.last_name
FROM Users
INNER JOIN Band_Members Band_Members1 ON (Band_Members1.user_id = Users.Id)
INNER JOIN Band_Members Band_Members2 ON (Band_Members1.band_id = Band_Members2.band_id)
WHERE
Band_Members2.user_id = 1
You can see here that I have joined Band_Members twice, and when one does that, one has to alias them differently, so they can be separately referenced. The first instance does the obvious join between the Users table and the bridge table, and the second one does a link between "Users who are in Bands" and "Bands that I am in".
Of course, this solution requires that you know your User ID. If you had wanted to do a similar query but filter based on your name, then you would have to join to another (re-aliased) copy of the User table, so that you can differentiate between the two different purposes: "Users who are in bands" and "your User".
So, I'm building a large scale photo gallery and I'm a bit puzzled when it comes to building and structuring the DataBase. Having little experience with noSQL DB's, this seems to be a big step up.
Important to mention, that the DB will hold only url ref's to the photos, which will be stored in a cloud.
Basically, I want each user to have a few photo albums, and in each album around 3000 photos. I want to let the user filter each album fast and efficiently, but no more than one album to filter (meaning he cant search all his photos at once).
My 2 main question here are:
Which will be more suitable- SQL or noSQL?
Storing photos:
Should I store photos per album, meaning giving each albums an array field, which will include 3000 photo objects.
Or should I store photos as a separate collection/table and ref each to its album?
Keep in mind filtering efficiently is a high priority.
Any specific DB recommendation will highly appreciated :)
Thank you
I would think that you would want a SQL database that supports binary objects for this such as MariaDB which is quite efficient for online/web applications. I would guess the basic database structure would be something like this :-
create table ALBUMS (
user_id integer,
album_id integer,
album_name text
)
create table PHOTOS (
album_id integer,
photo_name text,
photo_data blob
)
Obviously you will want to think about keys and indices to make this more efficient and no doubt you will have additional meta data to add as extra columns. This assumes that the albums do not have a fixed order for the photos. If they do you will need a
column for that and will want to SORT BY that column in your select statement.
I am designing a feature for a database, but I am stuck on design.
I have a table called AgendaItems, this table is a table with Agenda Items that could be assign to possible multiple users.
Users is a table that contains a record of user names, containing a fixed amount of 17 names.
How would I design these tables possibly another table that keeps track of who is working on what Agenda Item. Keep in mind multiple users could work on an agenda Item and users could work on multiple items.
I am not sure who to design this, and wondering if it would even work?
Thanks
I don't know if I understood your problem but I think your relationship is N-N.
So, you need to create another table (UsersAgendaItems). This table must contain the AgendaItems ID and Users ID, where both of then are FK.
Your PK could be a composite PK. This way you can know what user is related with what AgendaItems.
But I don't know if that is what you want. If this is not your case, please, try to explain a little bit more!
Thanks!
I have the following tables and relations:
When I create a User, that user gets a CurrentWeekrow and that current week row in turn gets a CurrentWeekStatusrow. The user can add food items to the Foodtable and then can choose from these food items and select a few to insert in CurrentWeek.
In the client I want to grab CurrentWeekas an object that has a list of Foodobjects and a list of their corresponding status.
I am struggling as to how to make this happen. I think this can be done by making multiple queries to the database, one to fetch CurrentWeek and then from this extract all the FoodId's and make separate queries to fetch each Food. But this seems like a very bad solution.
The other solution I can think of is making a view with all the necessary data. But I don't know how to make this view and even if I manage to make the view I don't know how to separate each Food into different objects.
Do anyone know of a good way to accomplish this?
I use NodeJs as a REST API and Android Studio with retrofit to send REST calls.
After consulting StackOverflow and a few colleagues I changed the initial database schema into:
This was a design I initially chose to not go with as I thought adding one row on the CurrentWeek table for each user would be better than to add many rows for each user in the PlannedFood table. I see now however that this design have a few advantages as compared to the other design.
Designing it this way also solves my initial question as I can now grab all the rows in PlannedFood for a specific user, joining on FoodId and then map the Food data into a Foodobject on client-side.
I'm attempting to create a basic music database for a school project.
I would like to link each song to three (3) other 'similar' songs.
I know how to link two tables together with FOREIGN KEY but I'm unsure how to link two entries within the same table.
The programs I'm using are PHPmyadmin and DBDesigner 4.
Thanks in advance for any assistance :)
First of all, when designing a database, you never want to "assume '(3)'." In other words, you don't want "repeating groups" such that the database design would be broken if you ever needed 4.
To me, "is-similar-to" is a many-to-many relationship that would list an arbitrary number of songs that are similar, with a structure such as
SONG_ID_1,
SONG_ID_2,
DEGREE_OF_SIMILARITY (some kind of percentage ...?)
So, for any song, you'd be looking to this table to find all songs that have ever been listed as "similar to" this song. You'd incorporate this table with an INNER JOIN, and be prepared to deal with an arbitrary number of matches.
You're looking for a relationship table, where you keep the song id along with the linked song id.
Example:
Table Song - ID PRIMARY KEY, NAME
Table Song_Link - ID_SONG (from Table Song), ID_LINKED_SONG (from Table Song)
This way you can store the link between both songs on a row basis.
Take into consideration that the link goes both ways.