i will recapitulate your description:
- A user can create lists.
- A list tackles some tasks.
- Users can join some lists.
- A user can send an invitation to some users and propose to join some lists
Based on this description I would propose the following ERD
From this I would deduce the following relations
user('user_id')
list('list_id',user_id(creates))
joins('list_id','user_id')
task('list_id','task_id')
invitation('invitation_id',user_id(sends))
receives('invitation_id','user_id')
proposes('invitation_id','list_id')
Primary keys are between apostrophes. Foreign keys can be deduced by the names if the fields (so user_id in lists references user_id in user) The word in parantheses after a foreign_key describes from which relation in the ERD this foreign key is derrived.
I did not care abou the names of the id-columns. Perhaps an id is a surogate key (an artificial key) or some attribue of the entity. also i did not add additional attributes which can be easily added. The characterisation o task as a weak entity is rather arbitrary.
You should not need the extra FK in Times
as that information can be derived from the existing relationships, but you will need to JOIN
in the other tables to get at the extra property. Adding the extra key like that is sometimes a necessary optimisation but it does break "normal form" as you are duplicating data (meaning that either your business layer becomes responsible for maintaining the referential integrity of that duplicate, or you need to do the same in the database using triggers and other "powerful but be very careful with them" features of your chose database).
Your select * from times where stop_id = 1 and line_id = 1
should be something like:
SELECT times.id, times.stopid, ...
FROM times
JOIN stops ON times.stop_id=stops.id
WHERE times.stop_id=1 AND stops.line_id=1
To simplify queries you can create views that abstract out the underlying structure a little, meaning you can keep the data in best form while dealing with it as it it did have the extra columns with duplicated information.
I'm not sure I'd model a timetable store that way though. I would assume that stops are separate entities with a many-to-many link between lines (unless you are counting a stop at which the no. 4, 5, and 45x lines stop at as three separate stops even though they are physically the same location). Also I'd probably want to group the lines together so that all the times for the "no 4" service are identifiable as a related collection but you can distinguish between the arrival times of each (so you can ask "what is the arrival time at X for the service that leaves Y at HH:MM" and so forth. Of course I could just be misreading your intended model! I'm thinking something like:
TimedStop
TimedRoute =============
Line ============= ts_id (PK) Stop
============ route_id (PK) ===> route_id (FK) =============
line_id (PK) ===> line_id (FK) stop_id (FK) <=== stop_id (PK)
line_name arrival_time stop_name
depart_time stop_location
Here TimedStop becomes a many-to-many relationship store for timed routes and stops. Of course there are probably several perfectly valid ways to model such a system depending on your other constraints, and the above may be rendered an incorrect model when you consider the fuller design spec (without more detail of what you are trying to model and what outputs are desired this is not possible to completely pin down, I made a fair few assumptions, which may or may not be correct, when throwing the above diagram together).
As another aside on a point of style: select *
is generally best avoided in permanent code where possible. If you are instead specific about what you want out this because part of your API and other code using this output has more guarantees of what columns will be returned, even if the underlying structures are updated. It can also allow the query planner/runner to apply extra optimisations (potentially avoiding extra heap lookups or being able to replace a table scan with an index scan, and so forth).
Best Answer
The answer for to your question is further down in the article:
The key represents the "one" and the figure-eight (or infinity symbol, I presume) represents the "many".
The relationships aren't tied to the visually closest column name in the diagram, but to the column with the same name in each table. For instance, the one-to-many relationship between
publishers
andtitles
is tied to thepub_id
column.