We have a database, which keeps informations about music - we have e.g. table for artists, bands, songs, albums etc. The next step is to allow users to rate those things, using 10-point grading scale.
What is the best way to remember all of users ratings? Surely I can create simple table, that contains user_id, rating_value and rated_thing_element, but obviously I can't join it to EVERY table.
Is it better then, to create, for example, one table called ratings and few additional tables, like ratings_albums, ratings_songs, ratings_bands etc. to bind, or maybe just few ratingsXXX tables for each of elements I've mentioned above?
I'm not sure which way I should go... or does it really matter.=?
My personal preference is to go with a normalized table and strict foreign references. So I would use artist_ratings, album_ratings, and song_ratings tables. To make queries easier, I would create views to represent the most often joined tables.
You can use a ratings table with no foreign keys (well except for the user reference), but you lose referential integrity enforcement. This table would be
ratings {
id integer,
userId integer, -- FK to users table
referenceId integer, -- This is not a FK, but will contain the ID of the artist/album/song
type char, -- a = album, A = artist, s = song
rating int
}
Related
lets say we have 3 table in our database
tables:
table books:
book_id
book_title
...
table magazines:
magazine_id
magazine_title
...
and genres:
genre_id:
genre_name
and now we say want to know what book has what genre and what magazine has what genre, this is the way i know for two table
relation tables:
table book_genres:
genre_id
book_id
table magazine_genre:
genre_id
magazine_id
in this way we have to create several separate table for joining the books, magazine and maybe more tables. and i been told that always have 2 id column in join tables.
but i'm wondering about if i could do something like this
the table that not working!
table title_genres:
genre_id
book_id
magazine_id
...
this is more simple but i get an error when i insert a book genres that says magazine_id can't be empty NULL because its primary key.
its gonna be save me for creating a lot of tables. like if i decide to have a category table then i have to join books and magazine separately.
and my question: is the 2 column thing is a good practice or there is a better way for this?
You use bridge tables to represent m:n relationships. If a book can have many genres and a magazine can have many genres, then you need bridge tables like the book_genres table you are showing.
And if books are very different from magazines in your database, then yes, have separate tables for books and magazines.
This leads to two bridge tables, just as you describe and I see nothing wrong with this.
Your idea to have one bridge table is generally possible, but doesn't solve any problem.
But well, let's see how we would construct such a multi bridge table. First of all you'll want a check constraint ensuring that always exactly one of the columns book_id and magazine_id is filled. Then you want a unique constraint on COALESCE(book_id, magazine_id), genre_id. This would usually be done with a function index, which MySQL doesn't support as far as I know. I suppose though, that you could create a generated column which you can index in MySQL.
And then you want to read the relations as quick as possible. With a bridge table like book_genres you have one row per book and genre and an index to get the relation as quick as possible. With a multi bridge table like title_genres you don't. You have one table containing relations you are interested in and others you are not interested in. You'd want a partial index like
create unique index idx on title_genres (book_id, genre_id) where book_id is not null;
but MySQL doesn't support partial indexes. You could
create unique index idx on title_genres (book_id, genre_id);
which leads to a larger index, but serves the purpose. You'd do the same with
create unique index idx2 on title_genres (magazine_id, genre_id);
And now, with all this work, what have you gained? Your database has become way more complicated than with the simple book_genres and magazine_genres tables. Keep it simple. Use these two tables instead of the multi bridge monster :-)
You can absolutely store the records this way if you have a category field that has information such as (books, magazines etc). So, in other words your table is vertically partitioned by category field but logically it’s a single table.
Only drawback I can see is if this table grows fast then query performance would be a problem because (a) the table will be huge so it will consume more memory even if you are only looking for specific categories and not all of them (b) you always have to use inline sub query since your category filter have to applied every time for every join and when you use inline queries for joins the database would not be able to make use of indexes will be affect the performance of the queries.
Note : You would not be able to store the records in any other way. For example even if a magazine and a book have same genre you have to have them in separate rows and not the same row because if you do that your model will get into other kind of troubles.
I am using DBDesigner 4 for designing my database relations.
I have a users table and a recipes table. One user can own many recipes but one recipe cannot be owned by many users. This relationship is shown by the user_recipes relation in the picture. (A one-to-many relationship from users to recipes).
However, recipes can be liked by users. Many users can like many recipes. This is a many-to-many relationship between users and recipes and the pivot table for this is users_like_recipes.
But when I create this pivot table, I only need the users_id and recipes_id column. The recipes_users_id column is getting added on its own and I am not able to remove it. It says the third column has come from another Relation which is defined in the model. I guess its the user_recipes relation.
When I remove the user_recipes relation, I get the pivot table like I want to.
But I need the user_recipes relation too!
Please. Any help would be appreciated.
I would suggest removing user_id as a primary key from from the recipes table. Currently the combination if id and user_id provides identification for your recipes table. In this situation multiple user_id's can create the same recipe id because the combination has to be unique. user_id can just be a normal column in your table. If you REALLY want to, you can make an alternate key on (id, user_id) but you do not need it because the id is unique.
I am new to database designing. In my case I have to generate lot many keys per user per product. So, I have two options -
Create one table with product_id and key for all the users, or
Create a separate table for each user
In the former case I will have a single table but querying might take more time as all the entries are in the same table for all the users.
In the later case queries might return the result faster but more tables and if users cross 100 or more than it means lot of tables.
Definitely do not create a table for each user. if you create a single table for all users you can use relational database design and add specific information pertaining to each user like address or employee information and use the primary key from the users table as a foreign key. and there will not be any noticeable lag. And maintenance will be whole lot easier
if you want to build relation between your user and product then make table like below
user_product [table name]
id [Primary Key]
user_id [Reference key of user table]
product_id [Reference key of product table]
key
This is your table schema You must use.
if you generate each table then this will take more complex for database and relation management. So, just use above row base format.
if that helpful then let me know.
Thanks
I had to implement the following into my database:
The activities that users engage in. Each activity can have a name with up to 80 characters, and only distinct activities should be stored. That is, if two different users like “Swimming”, then the activity “Swimming” should only be stored once as a string.
Which activities each individual user engages in. Note that a user can have more than one hobby!
So I have to implement tables for this purpose and I must also make any modifications to existing tables if and as required and implement any keys and foreign key relationships needed.
All this must be stored with minimal amount of storage, i.e., you must choose the appropriate data types from the MySQL manual. You may assume that new activities will be added frequently, that activities will almost never be removed, and that the total number of distinct activities may reach 100,000.
So I already have a 'User' table with 'user_id' as my primary key.
MY SOLUTION TO THIS:
Create a table called 'Activities' and have 'activity_id' as PK (mediumint(5) ) and 'activity' as storing hobbies (varchar(80)) then I can create another table called 'Link' and use the 'user_id' FK from user table and the 'activity_id' FK from the 'Activities' table to show user with the activities that they like to do.
Is my approach to this question right? Is there another way I can do this to make it more efficient?
How would I show if one user pursues more than one activity in the foreign key table 'Link'?
Your idea is the correct, and only(?) way.. it's called a many to many relationship.
Just to reiterate what you're proposing is that you'll have a user table, and this will have a userid, then an activity table with an activityid.
To form the relationship you'll have a 3rd table, which for performance sake doesn't require a primary key however you should index both columns (userid and activityid)
In your logic when someone enters an activity name, pull all records from the activity table, check whether entered value exists, if not add to table and get back the new activityid and then add an entry to the user_activity table linking the activityid to the userid.
If it already exists just add an entry linking that activity id to the userid.
So your approach is right, the final question just indicates you should google for 'many to many' relationships for some more info if needed.
Newish to mysql DBs here. I have a table of USERS and a table of TEAMS. A user can be on more then one team. What's the best way to store the relationship between a user and what teams he's on?
Lets say there are hundreds of teams, each team consists of about 20 users, and on average a user could be on about 10 teams, also note that users can change teams from time to time.
I can think of possibly adding a column to my TEAMS table which holds a list of user ids, but then i'd have to add a column to my USERS table which holds a list of team ids. Although this might be a solution it seems messy for updating membership. It seems like there might be a smarter way to handle this information... Like another table perhaps? Thoughts?
Thanks!
ps, whats the best field type for storing a list, and whats the best way to delimit?
whats the best field type for storing a list, and whats the best way to delimit?
It's usually a really bad idea to try to store multiple values in a single column. It's hell to process and you'll never get proper referential integrity.
What you're really looking for is a join table. For example:
CREATE TABLE user_teams (
user_id INT NOT NULL FOREIGN KEY REFERENCES users(id),
team_id INT NOT NULL FOREIGN KEY REFERENCES teams(id),
PRIMARY KEY (user_id, team_id)
);
so there can be any number of team_ids for one user and any number of user_ids for one team. (But the primary key ensures there aren't duplicate mappings of the same user-and-team.)
Then to select team details for a user you could say something like:
SELECT teams.*
FROM user_teams
JOIN teams ON teams.id= user_teams.team_id
WHERE user_teams.user_id= (...some id...);