ER Model Diagram Good design? how to express myself? - entity-relationship

I am trying to understand the concept of ER modelling, but I do not yet succeed. I have designed the ER model about movie database, but I do not know wheather it is a good design and how to connect the entities:
between Actor and Film i want to say "actor can play in each film only once" and at the same time "many actors can play in many movies" -- is it 1 to 1 relation or many to many?
and HOW do we need to think about entities ans relations between them? relations to one user, one film, one actor, one director, or in general?
UPDATE: new question : should the relation between Director and Film be 1 to many or many to many? I want to say : "one director can have many films && many directors can have may films" ??

Think about it like this: There are many movies. There are many actors. It makes sense that you would only want to include each actor in a particular movie once, but otherwise you want to be able to "mix and match" the movies and actors to express the relationship.
Looking at your diagram, you don't seem to have any fields which express the relationship between Film and Actor - those lines need to match actual fields. Read up on foreign keys: http://en.wikipedia.org/wiki/Foreign_key
The relationship between Actor and Movie that you want is actually many-to-many. You can express this with a "join table" (you'd need to add this to your diagram).
Something like this would work:
FilmActor
-------
uidFilm
uidActor
And put a unique constraint on those two fields together so it can't be duplicated (i.e. the same Actor can't appear in a Film twice)

Related

In Neo4j, is it possible to have the same relationship name for different entities

Let`s use the movie DB as an example.
If I would insert all people that worked on a movie in the DB, it would be difficult to find relationship names for everyone. Would it be a problem to have entities like: sound_designer, sound_engineer, set_designer, set_assistance, cable_guy, etc with the same relationship "WORKS_IN" to a Movie entity. Is it possible? Is it a good solution? Would I have problems? Are there alternatives?
Gabor's answer in the comments is a good one, there are no problems with nodes of differing labels having relationships of the same type to the same node.
Multi-labeling nodes with their role isn't a bad idea, however that assumes that a person's role is constant throughout the years captured by the graph, which may not hold true. Or rather, the labels would capture what roles they have been in their entire history, but what specific role they played within a particular movie is likely something you want as a property of the relationship itself, like a role property. Which might even be a list, if a person might have multiple roles for the same movie, similar to actors playing a part (where there is a roles list property on :ACTED_IN relationships).

Creating a relationship to a relationship in Neo4j

Is it possible to create a relationship to a relationship in Neo4j?
The use-case goes something like this:
I have a bunch of questions, like "What movie should we see?"
Each question can have many options like "Movie1", "Movie2", etc.
For each question I want a user to be able to vote for their favorite option.
The graph would preferably look something like this:
(:Question {name:"What movie?"})-[:Option]->(:Movie {name:"Movie1"})
^
|
[:Vote]
|
(:User)
I realize that one way I could solve this is with the following:
(:Question)-[:Option]->(:Movie)<-[:Vote]-(:User)
But then if I decide to remove the Movie as an Option in the future, I don't get to take advantage of DETACH and will have to manage removing the Vote relationship myself. Not to mention, if the Movie belongs to multiple categories, I have to keep track of which Question->Movie relationship it belongs to (probably with some sort of ID). It just seems very messy...
Is is possible to create a relationship to a relationship? Or am I going to have to manually enforce referential integrity?
Is is possible to create a relationship to a relationship?
No. This is not possible. According the docs:
A relationship connects two nodes, and is guaranteed to have a valid
source and target node.
That is: the start and end point of a relationship should be a node.
I believe you should do some changes in your data model. For example:
Maybe the Option can be a node and not a relationship. Make more sense, not? This way:
(:Category)-[:HAS]->(:Option)
Also, the Vote can be a node too, and not a relationship... This way, when the user makes (a relationship, ahn?) a vote, this vote node will reference the option and the category that it is relative to.
(:Category)-[:HAS]->(:Option)
\ /
[:FOR_CATEGORY][:FOR_OPTION]
\ /
(:Vote)
|
[:MAKES]
|
(:User)
If, for example, you need to delete a Option and consequently the :Votes related to it you can do something like:
MATCH (o:Option {id:10})<-[:FOR_OPTION]-(v:Vote)
DETACH DELETE o
DETACH DELETE v
Make any sense? Sorry for my ASCII art. :)
I'm investigating this. The only reasonable way I can find is to assign an identifier to the relationship (:HAS in your case) and then use it in the pointing relationship (:VOTE).
Neo4j has internal IDs for this (see the ID() function), but I usually prefer to try to assign a semantically meaningful ID (like a person's national insurance number, a page URL or, in case of relations, the hash code of its concatenated endpoint's identifers).

Bi-Directional Self-Referential Active record association

first week playing with rails and I'm a bit stuck on this active record relationship
I have 3 tables right now, Events, Fights and Fighters. Every fight belongs to an event and fighters can have many fights. I want to be able to store information in the fights table such as the winner, how the fight was won, the referee etc.
I've been doing some research and I think I'll need a bi-directional self-referential has many through relationship for the fights. Does this require 2 entries in the through table? If so, how can I query the fights while viewing an event without 2 records for each fight showing?
What would be the best way to store the winner if I want to show the fighters record on the fighters page? Have a winner_id and a loser_id in the table? This gets confusing when there can be draws and no contests.
There can also be fights with no outcome because they haven't happened yet. I'm thinking of using a seperate table for those.
Any suggestions are greatly appreciated!
Cheers
I suggest adding a few more tables:
Participants
could support more than two fighters in a match (not sure of your domain, but this could be useful for tag-team wrestling)
fight_id - foreign key to fight (belongs_to)
fighter_id - foreign key to fight (belongs_to)
Decision
The decision could have alot of information like type = "KO", "TKO", etc. Other info like Judges voting. Draws and no-decision would not go here
fight_id - foreign key to fight (belongs_to)
type
winner_id
loser_id
dt - datetime for when the decision was reached
And edit fights to contain a field on status:
Fights
status - (decision, no-decision, draw, cancelled, postponed, etc)

Core Data Programming Guide: intermediate join entity example, MUTUAL or NOT?

In the example of using "intermediate join entity"
To find out who one person’s friends are, you have to aggregate all the friend destinations of the friends relationship, for example:
NSSet *personsFriends = [aPerson valueForKeyPath:#"friends.friend"];
Is above line of code getting a given person's MUTUAL friends? or just ONE-WAY friends, which means only getting "peoples who are treated by this given person as his friends"?
I am not certain, because "To find out who one person’s friends are" sounds like ONE-WAY friendship (that could be why there is a strange relationship befriendedBy represents those who count the source as their friend. FriendInfo represents information about one friendship, “in one direction.” .)
This is a really confusing example. There are two possibilities.
In most cases being "friends" is a mutual thing. In this case you would have a self-referencing many-to-many relationship of a Person, perhaps called friends. The relationship would be mutual.
You seem to be implying that it is possible to add another person as a friend even if that person is does not reciprocate. In order to lift the confusion give this many-to-many relationship another distinct name, e.g. contacts. This would be the Persons that have been added unilaterally. In Core Data, all relationships are best modelled as mutual, so you can use another relationship potentialFriends that is the inverse relationship of contacts. Maybe there are better names, but you get the idea.
The intermediate join entity is only necessary if you want to store additional attribute with a particular relationship, e.g. the date a contact request was made. In this case, you would have the join entity e.g. friendLink, which would have a to-one relationship to two distinct Persons. You can model the state of the link (unilateral or mutual) in this entity.

Better solution for mongoid many to many relationship

The mongoid documentation told me that n-n relations should be used with caution
I understand his but don't have an idea how to solve my problem a better way using pure mongoid:
A course has many participants and a participant could participate with many courses. So wouldn't it be faster to store the participant on the course model and do a search over all courses when all courses of a participant are needed?
Your model should be reflective of your use cases.
One way to do this would be to have one model for the courses, one for participants and a 3rd that maps students to courses (with a unique index on course & student to prevent duplicates). This way there is a single model referring to the other 2. This may or may not be ideal based on your access patterns.
I think this is probably a good use case for embedding documents. See the sample syntax on the front page for embeds_many and embedded_in: http://mongoid.org/en/mongoid/
The main downside here is that if you have participants in more than one course, you will have duplicate participants in each of those courses.
Make sure you put an index on the fields you plan to do your lookups for participants with.

Resources