I'm trying to figure out most of the database design and normalization before I do much for my current project. Unfortunately I don't have much experience with database design, so it's a fairly slow process. One of the issues I'm trying to figure out is what's the best way to deal with a situation where one table may, or may not, be associated with another table.
A little background will help clear the question: I'm building a web application, using Rails 3.2, that helps manage races. People will be able to create accounts (/user accounts), host races, and manage the various aspects.
One thing is that the participants in a given race may or may not be users. In fact, we can assume that most of them will not be users. But for those who are, it would be nice to be able to link to their profiles (and, going the other way, link from their profiles to the races they've participated in).
It's sort of like blog posts where people can post anonymous comments, but if they do decide to log in and use their account then it's linked with the post in various ways.
I've searched for a while, but haven't really found solutions. I figure the way to do it is to have the Participants model note "has_one UserParticipation", which would usually be nil.
Is that a valid solution?
Is there a better way to go about this?
Here's a small diagram I threw together in Paint to concisely show the issue:
Question 2:
This is a little less important, but I figured I'd ask it in the same question because I've already posted the relevant question: several things will reference participants, is there any reason to set up a composite {Race_ID, Participant_Number} super key rather than always reference it using "race.participants"? (As far as I can tell, these would work very similarly.)
You may be over thinking it a bit. If I am following you correctly, this is a simple entity relationship diagram I whipped up in Dia:
Some explanation on the assoications of a User to Participants:
A Participant will have the belongs_to :user association, which is nil if there is no associated User.
A User will have the has_many :participants association, allowing none to many Participants relations. If there are none, a user instance will have user.participants equal an empty array.
As to the second question, you would only need to use both keys if you are querying for a specific participant for specific race, e.g. where participant_id = 7 and race_id = 4.
So a race has many participants (some of whom are users), and a participant has many races (hopefully :-).
Taking the user part of things out of the picture for a moment, this is a simple many-to-many relationship which Rails handles beautifully with has_and_belongs_to_many on both Race and Participant models, described here http://guides.rubyonrails.org/association_basics.html#the-has_and_belongs_to_many-association. Another alternative, not necessary in your case is has_many :through which creates a first-class model backed by the join table. But what you have described makes this unnecessary.
The relationship between User and participant is one-to-one, and conditional. It's not clear to me if you can be a user without being a participant but if you have a User who is a Participant, you want them related. This is a :has_one relation.
The cool part of Rails that I'll bet you're looking for is that relationships can be conditional, so in this case a Participant has_one User conditionally. The linked Rails Guide document describes how to define all of this.
Related
Ticket Booking Entity Diagram
I am practicing to build databases. I just modeled this in draw.io before building a physical model. However, I am confused if this model is a proper one. What should be the best way to implement this ticket booking database? What aspect of this model needs to be changed, or what action of design should not be followed? Please help in this regard.
No, this model wouldn't work.
In your model tickets are associated with the cinema, which doesn't make sense.
Your timings also have nothing to do with Movie. While you've got the right ID there your relationship lines are a bit wonky.
There are a couple of different ways of doing it, but based on what you've got so far I'd go for something along these lines:
The way to think about it is what has what: A Cinema has times that it can show movies. A movie is shown at a time. A time has seats that are sold via tickets to users. You can certianly put the MovieID into the Tickets or Seats table for your foriegn keys, but the above is how I see the main relationships going.
Depending on how you want to model it you could make it that cinemas have movies, and movies have timings. I went with Cinemas having timings, because that feels more right to me. You may have a different opinion.
I have to design a database for an advert site.
Until now this is the design i came up with:
Administrator(Id,Name,Password)
Advert(Advert_Id,Title,Description,Category,User,Date_created,Picture,Type)
User(User_Id, Name ,Phone,email,Address)
Category(Cat_id,Cat_Name)
Type(Id,Type_Name)
Picture(Picture_Id,Name)
The administrator refers to to the person that will manage the site.
The type refers to the type of the advert: selling, buying etc.
I must have minimum 5 tables at least 2 one to many relationships and at least one many to many relationship. The problem is that I can't find a many to many relationship that would make sense.
If an advertisement can have more than one category, then advertisements and category would be many to many.
If an ad can have more than one picture and a picture can be used in more than one ad, ads and pictures would be many to many.
However, you have to know the business rules. None of us will.
Like Dan mentioned on the answer, you have to know the Business Rules. It's a project for a class, so the business rules might be flexible, I remember back in college, for example, they would tell us that if a client wanted to have advertisement be of at least one category, but could have up to 3 or 4 different categories, that changes your DB structure a lot.
An advertisement can also have many pictures, not just one. It can even have some videos, and many of them as well. Make sure you clarify well the Business Rules and that you understand them fully, as in a real life situation, that can represent either the success of your project or the failure of it.
We're making an application using Ruby on Rails with Mongoid.
I've been reading up on the documentation of mongoDB and the Mongoid gemregarding how to design the database schema when utilizing a document-based database. I've been going over it in my head for a while now, and would really appreciate some input from people with more experience than me to know whether or not I'm completely lost :p
Anywho, here's an overview (I've tried to keep it as simple as possible to keep the question facutal) of the appliction we're making:
The application consists of the following entities:
Users, Subjects, Skills, Tasks, Hints and Tutorials.
They are organized in the following manner:
Subjects consists of a set of 1..n Skills.
Skills consists of a set of Tasks, (sub-)Skills or both (i.e. skills can be a tree
structure, where one main skill (say, Geometry) is the root and other skills are
child nodes (for instance, the Pythagorean Rule might be a sub-skill)). However,
all skills, regardless of whether they have sub-skills or not, should consist of
0..n tasks.
Tasks have a set of 1..n Hints associated with them.
Hints are each associated with a particular task.
Tutorials are associated with 1..n Skills (this skill can be either a root
node or a leaf node in a skill tree).
Users can complete 0..n Tasks in order to complete 0..n Skills.
Now, we imagine that there will mostly be read queries called to the database for the collection of skills/tasks completed by certain users, and read queries to display the various skill trees associated with a subject. The main write queries will probably be related to relationship between various users and tasks, in the following form
User A completes Task B
and so forth. Also, we imagine that the size of the number of entitites would be as follows: Users > Hints > Tasks > Skills > Tutorials > Subjects
Currently, this is the solution we have in mind:
Subject.rb
has_and_belongs_to_many :skills
Skill.rb (uses Mongoid::Tree)
has_and_belongs_to_many :subjects
embeds_many :tasks
Task.rb
embedded_in :skill, :inverse_of => :tasks
embeds_many :hints
Hint.rb
embedded_in :task, :inverse_of => :hints
We haven't really started implementing the tutorials and the connection between user and skills/tasks yet, but we imagine that the relationship between user and skill/tasks necessarily has to be N:N (which I guess is rather inefficient).
Is using a document-based database for this kind of application a bad idea? And if not, how can we improve our schema to make it as efficient as possible?
Cheers, sorry for the wall of text :-)
In my honest opinion unless some part of your data is going to be completely unstructured I see no need to use a NoSQL solution for your problem.
I'm going out from a point of view that you do have databases knowledge so you are familiar with MySQL/PostgreSQL/etc.
I sincerely believe that PostgreSQL (or Mysql for the matter) will be easier for you to set up, to write your code, to maintain and perhaps eventually to scale up.
My take on NoSQL is use it when you have unstructured datasets and you need the flexibility of adding fields on the fly, there are pitfalls using MongoDB.
It's not a silver bullet.
Some of the pitfalls are for instance, in()s are slow, if you write something to mongo and then want to immediately read it, you have to expect you won't get it (sharding in mongo), map reduce is kind of a hassle (I haven't tried the aggregate framework with Moped but it does look promising, sometimes indexing can have issues with sharded collections).
Issue: Is there a better way to model the following or create a basic recommendation system than the database diagram below? If an extremely lengthy answer is necessary, you could instead just point me in the right direction and suggest things to research further.
I'm building a rudimentary event recommendation system by allowing users to answer questions and storing their user-answer relationship in the responses model. Each question's answer relates to a tag. Each event is also tagged. Thus, I should be able to provide users with recommended events via selecting matching tags and using this 5 table relationship. However, it seems like I would have to go through several has_many :through relationships in order to accomplish this, which I don't believe is preferred using Rails.
Would it be better to instead create a relationship from users to events via a background rake task or something, computing the relationship after questions are answered? Am I missing the concepts completely here and looking at this from the wrong angle? Eventually this system would be replaced with a more robust algorithm, perhaps using Mahout or something, but for now I'm just trying to get a simple proof of concept working.
Here's a link to the database diagram: Database Diagram
Update Edited to reflect clarifications requested by Chris Holmes below. Originally I was referring to a Terminal as a Site but changed it to better reflect my actual domain.
At heart, I think this is a question about modeling a many to many relationship between two root entities where the relationship itself carries some semantic meaning.
In my domain
You can think of a Terminal as a branch location of our company
A Terminal can have a relationship with any number of customers
A customer can have a relationship with any number of terminals (standard many to many)
A customer\terminal relationship means that a customer can potentially store products at the Terminal
This relationship can be enabled\disabled. To be disabled merely means you are temporarily not allowed to store product, so a disabled relationship is different from no relationship at all.
A customer can have many Offices
A Terminal that has a relationship with a customer (enabled or not) must have a default office for that customer that they communicate with
There are some default settings that are applied to all transactions between a Customer and a Terminal, these are set up on a Terminal-Customer Relationship level
I think my objects here are pretty clear, Terminal, Customer, Office, and TerminalCustomerRelationship (since there is information being stored specifically about the relationship such as whether it is enabled, default office, ad default settings). Through multiple refactorings I have determined that both Terminal and Customer should probably be aggregate roots. This leaves me with the question of how to design my TerminalCustomerRelationship object to relate the two.
I suppose I could make the traversal from Terminal to TerminalCustomerRelationship unidirectional toward the relationship but I don't know how to break the relation from the relationship to the customer, especially since it needs to contain a reference to an Office which has a relationship to a Customer.
I'm new to this stuff and while most of DDD makes perfect sense I'm getting confused and need a fresh outlook. Can someone give me their opinion on how to deal with this situation?
Please note that I say Relationship not relation. In my current view it deserves to be an object in the same way that a Marriage would be an object in an application for a wedding chapel. Its most visible purpose is that it relates two objects, but it has other properties that rightfully belong to it as well.
By your description, you definitely need a "TerminalCustomerRelationship" entity to track the associated information. I would also convert the 'IsEnabled' flag into a first class 'Event' entity with a timestamp - this gives you the ability to save a history of the state changes (a more realistic view of what's happening in the domain.)
Here's a sample application (in VS2008) that refects your problem. You can tweak/test the code until the relationships make sense. Run "bin/debug/TerminalSampleApp.exe" and right-click "Terminal->Create Example" to get started.
Let me know if you find it useful.
Names can often clarify an object's responsibilities and bring a domain model into focus.
I am unclear what a Site is and that makes the entire model confusing, which makes it difficult for me to offer better advice. If a Site were a Vendor, for instance, then it would be easy to rename SiteCustomerRelationship as a Contract. In that context it makes perfect sense for Contract to be its own entity, and have the the model look like Vendor-Contract-Customer-Office.
There are other ways to look at this as well. Udi has a decent post on this sort of many-to-many relationship here.
You should not have a object Like SiteCustomerRelationship, its DB specific.
If its truly DDD you should have a Relation like:
Aggregate<Site> Customer.Site
IEnumerable<Aggregate<Office>> Customer.Offices
and perhaps
Aggregate<Office> Customer.DefaultOffice