I'm not looking for the answer, I am just looking for some guidance or a little clarity here. I need to design a database as if I worked for redbox and I'm trying to track movies actors and directors. So I am assuming I need three different tables but I just don't understand how to "track" it. Would I create a custom ID for each movie and something that tracks where the kiosks are? Like I said, I think I can do this but I just fully understand it.
Any help is appreciated
In broad strokes here is what you need:
(Basic relational rules and strategy apply, so every table needs to have a Primary Key, and the keys will be used to relate the tables together).
movie:
One row per movie, with title, rating, year, etc.
person:
Add to that a related person table with one row for any person who might be a cast or crew member in any film.
credit:, credit_type
Now relate Movie <-> Person
Since this is a many to many relationship you need a table between the two. Typically this would be called "credit" and you need a credit_type table that will describe the credit (actor, director, writer, producer, etc).
Of course that has nothing to do with your "tracking" question. For that you would need a slew of tables:
inventory:
Here is where you have one row for every copy of a movie that exists. It should be obvious that there will be a foreign key for a movie in this table. In the real world there would be an assigned id that would then be printed out as a barcode and attached to the disk + sleeve of the physical material.
kiosk:
For every Kiosk there is a row, along with location information, which could be an address perhaps along with a note, in case there are multiple kiosks at the same location.
kiosk_bin:
For every Kiosk, you will have a 1-M bins, each with a number identifying it.
I wouldn't do it this way, but you could for simplicity add a column in kiosk_bin that would be a foreign key to the inventory table. In this way you are able to indicate that an inventory (a single copy of one particular movie) is sitting in a kiosk_bin.
member:
These are the people subscribed to the service.
member_checkout:
When a member gets a movie from a kiosk/kiosk_bin, a row gets created here, with the inventory_id, and the date, and the system would update the kiosk_bin row to remove the inventory_id and show that the bin is now empty and could accept another inventory copy.
As you can see, this is non-trivial. Database design of any relatively complicated business process is going to be more than 3 tables, I'm sorry to say.
Here's an ERD that illustrates some of the basic movie to credit relations I did for another similar question. The tables were named a bit differently but you should be able to match them up.
Related
I am designing a database for a website. I have 4 tables for posts. The first table is the master table that should assign a new ID and title for every single post regardless of the post type. The three other tables are cars, houses, and furniture tables. Each one of them should only have the post that is related to it. I am little bit confused of the type of relation between master table and other tables; should it be one to many or one to one. that is, in the cars table, there are columns for price, detail, manufacturer, type, cylinder, fuel, and so on. so, in the master table if the type of post is car, then, this post should be assign a one id in cars table with unique manufacturer. Therefor this is one to one. and each post in the cars table has a correspondent post id in the master table( one to one relationship). while each manufacturer may have many posts in the master table. hence, I assume this is one to many relationship. This is the same case with other tables.
please I do not need any referring to any documentation since I read all mysql official documentation and I know the theoretical prospect of all relationship types but when I turned into the practical part I became little bit confused.
If you want to know if the relationship between X and Y is one-one, many-one, or many-many, ask yourself these two questions:
Can one X have multiple Y's?
Can one Y have multiple X's?
Now count the Yesses:
0: One-one
1: Many-one
2: Many-many
For example, a manufacturer can have multiple cars, but a car only has one manufacturer, so that's many-one. The post/car relationship isn't as clear to me from your description. Can a post have multiple cars? Can a car appear in multiple posts?
You are right on the track, I ll suggest you to store all the post in post table as auto-increment id. Whenever you get any post of any type, make an entry in post table with suitable type. Also make entry about manufacture in post table.
Now take this post id and make a corresponding entry into cars/house/furniture table depending on the type, here in these table add additional details like price etc respectively.
So now post table becomes central repository of all post - depending on many types and manufacturer. You can later add/remove types of post accordingly. making it a scalable.
Further, you thinking right in terms of relationships where you have many to one relation between manufacturer and post(since one manufacturer can post multiple times), and one to one relation between post and its type(since a single post at any point in time will only belong to only one type).
I am creating a DB for my project and I am facing a doubt regarding best practice.
My concrete case is:
I have a table that stores the floors of a building called "floor"
I have a second table that stores the buildings called "building"
I have a third table that stores the relationship between them, called building_x_floor
The problem is this 3rd table.
What should I do?
Have only two columns, one holding a FK to the PK of building and another holding an FK to the PK of floor;
Have the two columns above and a third column with a PK and control consistency with trigger, forbidding to insert a replicated touple of (idbuilding, idfloor)?
My first thought was to use the first option, but I googling around and talking I heard that it is not always the best option.
So I am asking for guidance.
I am Using MySQL 5.6.17
You don't need third table. Because there is one-to-many relationship between building and floor.
So one building has many floors and a floor belongs to one building. Don't get things complicated. Even though you need a table with composite keys, you should be careful. You need to override equals and hashCode methods.
I am still not confortable with that approach. I am not saying it is wrong or innapropriate, very far from that. I am trying to understand how the informations would be organized and how performatic it would be.
If I have a 1:* relationship, like a student may be attending to more than one subject along its university course within a semester I would Have the 3rd table with (semester, idstudent, iddiscipline).
If I try to get rid of the join table my relationship would be made with a FK inside student table or inside subject table. And it does not make sense to do that because student table is a table for a set of information related with registering the info of a person while the discipline table holds the data of a discipline, like content, hours...it is more a parametric table.
So I would need a table for the join.
My question might be dumb since I think it's a very common design issue, and I guess there is a simple and usual solution to it:
I have a table Producer and a table Movie
ONE Producer has produced MANY Movies
ONE Producer has ONE favorite Movie among the ones he has produced
How do I implement this in MySQL?
just one ONE-TO-MANY relation between Producer and Movie, plus a 'favorite' boolean attribute in the Movie table
one ONE-TO-MANY relation to represent the 'has produced' relation, and a ONE-TO-ONE relation to represent the 'is favorite' relation
The first solution seems more natural to me, but when the producer wants to change his favorite movie, I guess the second solution is more efficient. As well as it should be more efficient to find a producer's favorite movie with solution #2.
What am I missing? Is there a best solution? If not in which case should I use solution #1 and solution #2?
(Of course, my problem is a bit more complex thant the example above...)
The (1) is not easy/efficient to enforce declaratively. Plus, you end-up wasting space on all non-favorite movies.
The (2) is the way to go. Unfortunately, this circular dependency will lead to the chicken-and-egg problem, which is solved:
either by deferring one of the FKs (if the DBMS supports it, which MySQL unfortunately desn't),
or by leaving the FK in user NULL-able, which is less than ideal since the user can now have zero or one favorite movies (as opposed to strictly one).
Assuming you want the same movie to be relatable to multiple users (making it a many-to-many relationship, not one-to-many as you stated), your model would end-up looking something like this in a DBMS supporting deferrable FKs:
But you don't have the luxury of deferring the constraints in MySQL, so you'll be forced to do something like this:
CHECK (FAVORITE_USER_ID IS NULL OR FAVORITE_USER_ID = USER_ID)
The boolean attribute not only takes up a lot more space, but also looks like it would prevent more than one user from having a favourite.
The second solution sounds correct. Have a field in User to represent each user's favourite and an additional table to make the one to many "has watched" relationship.
If you need to make sure that the user has actually watched his/her favourite movie, you should add that logic as a business rule in your data access object.
In general, I would go with solution 2. Along with making queries for the favorite simpler, this has the added benefit of a built-in constraint, limiting the user to having only one favorite movie. Furthermore, this will be slightly smaller, having one id per user instead of one boolean per watched movie-user. One side-effect, however, is that you are able to favorite a movie without watching it.
Solution 1 would be the preferred choice only if you wanted to extend your favorites system in the future to include more than one favorite. However, it would appear that this is explicitly not desirable.
It is also worth mentioning that the relationship between users and movies is many-to-many, not one-to-many, as each user has their own list of watched movies. Therefore you will need a third table to link the two. Unless of course you are just having a list of uncorrelated strings for each user, but I doubt this is the case.
If you are sure there will always only be one movie I would have a "favorite movie ID" attribute in the user table, along with a many-to-many relation between users and movies (the same movie can be watched by many users)
So, three tables total, flag in the users table.
I think second solution is more feasible. You can create two tables for these relations, one named HasWatched, the other one named Favorite. Both of these tables constist of two columns, named userId - movieId. The primary key for Haswatched table is (userId - movieId) tuple. But primary key of Favorite table is only userId. Therefore, you can apply all constarints.
I would do a third table... I don't think is a one to many relation, its a many to many, one user can watch many films but one film can be watched by many users...
I would do a users table, a movie table, and a user-movie-watched table with user_id, movie_id
and add a favorite_movie field pointing the movie_id the user favs.
The best way to describe this scenario is to use an example. Consider Netflix: do they
store their orders (DVD's they mail out) in a separate table from their member lists (NOT members table, but a joiner table of members and movies--a list of movies each member has created), or are orders distinguished by using additional information in the same row of the same table?
For those not familiar with Netflix, imagine a service that lets you create a wish list of movies. This wish list is subsequently sent to you incrementally, say two movies at a time.
I would like to implement a similar idea using a MySQL database, but I am unsure whether to create two tables (one for orders and one for lists) and dynamically move items from the lists table to the orders table (this process should be semi-automatic based on the member returning an item, where before a new one is sent out, a table with some controls will be checked to see if the user is still eligible/has not gone over his monthly limit)...
Thoughts and pros and cons would be fantastic!
EDIT: my current architecture is: member, items, members_items, what I am asking is if to store orders in the same table as members_items or create a separate table.
Moving things from one database table to another to change its status is simply bad practice. In a RDBMS, you relate rows from one table to other rows in other tables using primary and foreign key constraints.
As for your example, I see about four tables just to get started. Comparing this to Netflix, the grand-daddy of movie renting, is a far-cry from reality. Just keep that in mind.
A User table to house your members.
A Movie table that knows about all of the available movies.
A Wishlist or Queue table that has a one-to-many relationship between a User and Movies.
An Order or Rental table that maps users to the movies that are currently at home.
Statuses of the movies in the Movie table could be in yet another table where you relate a User to a Movie to a MovieStatus or something, which brings your table count to 6. To really lay this out and design it properly you may end up with even more, but hopefully this sort of gives you an idea of where to begin.
EDIT: Saw your update on exactly what you're looking for. I thought you were designing from scratch. The simple answer to your question is: have two tables. Wishlists (or member_items as you have them) and Orders (member_orders?) are fundamentally different so keeping them separated is my suggestion.
A problem with storing orders in the members table is that there's a variable number (0, 1, or several) of orders per member. The way to do this using a relational database is to have two separate tables.
I feel like they would store their movies as follows (simplified of course):
tables:
Titles
Members
Order
Order_Has_Titles
This way an order which has a foreign key to the Members would then have a pivot table as many orders could have many titles apart of them.
When you have a many to many realtionship in the database you then need to create a pivot table:
Order_Has_Titles:
ID (auto-inc)
Order_FkId (int 11)
Title_FkId (int 11)
This way you're able to put multiple movies apart of each order.
Of course this is simplified, and you would have many other components which would be apart of it, however at a basic level, you can see it here.
Say we have this scenario:
Artist ==< Album ==< Track
//ie, One Artist can have many albums, and one album can have many tracks
In this case, all 3 entities have basically the same fields:
ID
Name
A foreign of the one-many relationship to the corresponding children (Artist to Album and Album to Track
A typical solution to the provided solution would be three tables, with the same fields (ArtistID, AlbumID etc...) and foreign key constraints in the one-many relationship field.
But, can we in this case, incorporate a form of inheritance to avoid the repetition of the same field ? I'm talking something of the sort:
Table: EntityType(EntityTypeID, EntityName)
This table would hold 3 entities (1. Artist, 2. Album, 3. Track)
Table: Entities(EntityID, Name, RelField, EntityTypeID)
This table will hold the name of the entity (like the name of
an artist for example), the one-many field (foreign-key
of EntityID) and EntityTypeID holding 1 for Artist, 2 for Album
and so on.
What do you think about the above design? Does it make sense to incorporate "OOP concepts" in this DB scenario?
And finally, would you prefer having the foreign-key constraints of the first scenario or the more generic (with the risk of linking an artist with a Track for example, since there is no check to see the inputter foreign-key value is really of an album) approach?
..btw, come to think of it, I think you can actually check if an inputted value of the RelField of an Artist corresponds to an Album, with triggers maybe?
I have recently seen this very idea of abstraction implemented consistenly, and the application and its database became a monster to maintain and troubleshoot. I will stay away from this technique. The simpler, the better, is my mantra.
There's very little chance that the additional fields that will inevitably accumulate on the various entities will be as obliging. Nothing to be gained by not reflecting reality in a reasonably close fashion.
I don't imagine you'd even likely conflate these entities in your regular OO design.
This reminds me (but only slightly) of an attempt I saw once to implement everything in a single table (named "Entity") with another table (named "Attributes") and a junction table between them.
By stucking all three together, you make your queries less readble (unless you then decompose the three categories as views) and you make searching and indexing more difficult.
Plus, at some point you'll want to add attributes to one category, which aren't attributes for the others. Sticking all three together gives you no room for change without ripping out chunks of your system.
Don't get so clever you trip yourself up.
The only advantage I can see to doing it in your OOP way is if there are other element types added in future (i.e., other than artist, album and track). In that case, you wouldn't need a schema change.
However, I'd tend to opt for the non-OOP way and just change the schema in that case. Some problems you have with the OOP solution are:
what if you want to add the birthdate of artist?
what if you want to store duration of albums and tracks?
what if the want to store track type?
Basically, what if you want to store something that's psecific only to one or two of the element types?
If you're in to this sort of thing, then take a look at table inheritance in PostgreSQL.
create table Artist (id integer not null primary key, name varchar(50));
create table Album (parent integer foreign key (id) references Artist) inherits (Artist);
create table Track (parent integer foreign key (id) references Album) inherits (Artist);
I agree with le dorfier, you might get some reuse out of the notion of a base entity (ID, Name) but beyond that point the concepts of Artist, Album, and Track will diverge.
And a more realistic model would probably have to deal with the fact that multiple artists may contribute to a single track on an album...