Crows-foot notation in an Sqlite database model - sqlite

I'm getting to grips with using 'crows-foot' notation to design Sqlite databases using Navicat. In a book chapter designed to get users up and running with this software I have come across the following example, consisting of an ER diagram and some explanatory text:
There is a many-to-one relationship between the category table and the task table. In our case, a task can have one category associated with it, but a category can have many tasks under it. As such, a task can be assigned to one user, but a user can have many tasks.
I was surprised to read this because the notation seems to be at odds with the description. My way of reading these diagrams (arrived at by examining various freely available examples on the internet) is to start with the table (say Task) then look at the notation that is 'attached' to the related table (in this case 'one or more') and construct the relationship as follows: Task belongs to 'one or more' Categories. Such a relationship is possible of course, but it seems inconsistent with the verbal description of the desired relationship, namely: 'a task can have one category associated with it'. Am I misunderstanding crow's-foot notation?

In ERD (whether using Crow's foot or Chen notation) the "many" side has always the foreign key, The Task table has the foreign key Category_id and therefore is on the "many" side while Category has the related primary key named ID and therefore is on the "one" side. So, you're right in your interpretation actually.

Related

DynamoDB - Modeling bidirectional many-to-many relationship?

I'm having a hard time modeling a certain scenario without having to appeal to more than one request.
Think about a People table, each Person can be related to eachother n times, and this relationship has a description.
Consider the following modelling :
As you can see, I have two People, and person_0001 is child of person_0002.
Now, in this case, if I want to get all relationships that person_0001 has, it's easy, I just query :
GET WHERE PK = "person_0001" AND SK.BEGINS_WITH("rel")
But, since it is bidirectional, how can I get the relationships person_0002 has?
I could use a GSI that inverts the keys, so with one request I can simply query both tables at once.
But real problem comes when I need to update/delete, How can I delete/update all relationships person_0002 has with only one request? I can only read from GSIs.
It's a big difficulty I have in general, what do I do when I need to do a delete/update/write on a GSI?

Should DynamoDB adjacency lists use discrete partition keys to model each type of relationship?

Context
I am building a forum and investigating modeling the data with DynamoDB and adjacency lists. Some top-level entities (like users) might have multiple types of relationships with other top-level entities (like comments).
Requirements
For example, let's say we want be able to do the following:
Users can like comments
Users can follow comments
Comments can display users that like it
Comments can display users that follow it
User profiles can show comments they like
User profiles can show comments they follow
So, we essentially have a many-to-many (user <=> comment) to many (like or follow).
Note: This example is deliberately stripped down, and in practice there will be many more relationships to model, so i'm trying to think of something extensible here.
Baseline
The following top-level data would likely be common in any adjacency list representation:
First_id(Partition key) Second_id(Sort Key) Data
------------- ---------- ------
User-Harry User-Harry User data
User-Ron User-Ron User data
User-Hermione User-Hermione User data
Comment-A Comment-A Comment data
Comment-B Comment-B Comment data
Comment-C Comment-C Comment data
Furthermore, for each table below, there would be an equivalent Global Secondary Index with the partition and sort keys swapped.
Example Data
This is what I would like to model in DynamoDB:
Harry likes comment A
Harry likes comment B
Harry follows comment A
Ron likes comment B
Hermione likes comment C
Option 1
Use a third attribute to define the type of relationship:
First_id(Partition key) Second_id(Sort Key) Data
------------- ---------- ------
Comment-A User-Harry "LIKES"
Comment-B User-Harry "LIKES"
Comment-A User-Harry "FOLLOWS"
Comment-B User-Ron "LIKES"
Comment-C User-Hermione "FOLLOWS"
The downside to this approach is that there is redundant information in query results, because they will return extra items you maybe don't care about. For example, if you want to query all the users that like a given comment, you're also going to have to process all the users that follow a that given comment. Likewise, if you want to query all the comments that a user likes, you need to process all the comments that a user follows.
Option 2
Modify the keys to represent the relationship:
First_id(Partition key) Second_id(Sort Key)
------------- ----------
LikeComment-A LikeUser-Harry
LikeComment-B LikeUser-Harry
FollowComment-A FollowUser-Harry
LikeComment-B LikeUser-Ron
FollowComment-C FollowUser-Hermione
This makes it efficient to query independently:
Comment likes
Comment follows
User likes
User follows
The downside is that the same top-level entity now has multiple keys, which might make things complex as more relationships are added.
Option 3
Skip adjacency lists altogether and use separate tables, maybe one for Users, one for Likes, and one for Follows.
Option 4
Traditional relational database. While I'm not planning on going this route because this is a personal project and I want to explore DynamoDB, if this is the right way to think about things, I'd love to hear why.
Conclusion
Thanks for reading this far! If there is anything I can do to simplify the question or clarify anything, please let me know :)
I've looked at the AWS best practices and this many-to-many SO post and neither appears to address the many-to-many (with many) relationship, so any resources or guidance greatly appreciated.
Your Option 1 is not possible because it does not have unique primary keys. In your sample data, you can see that you have two entries for (Comment-A, User-Harry).
Solution 1
The way to implement what you are looking for is by using slightly different attributes for your table and the GSI. If Harry likes Comment A, then your attributes should be:
hash_key: User-Harry
gsi_hash_key: Comment-A
sort_key_for_both: Likes-User-Harry-Comment-A
Now you have only one partition key value for your top level entities in both the table and the GSI, and you can query for a specific relationship type by using the begins_with operator.
Solution 2
You could make the relationship a top-level entity. For example, Likes-User-Harry-Comment-A would have two entries in the database because it is “adjacent to” both User-Harry and Comment A.
This allows you flexibility if you want to model more complex information about the relationships in the future (including the ability to describe the relationship between relationships, such as Likes-User-Ron-User-Harry Causes Follows-User-Ron-User-Harry).
However, this strategy requires more items to be stored in the database, and it means that saving a “like” (so that it can be queried) is not an atomic operation. (But you can work around that by only writing the relationship entity, and then use DynamoDBStreams + Lambda to write entries for two entries I mentioned at the beginning of this solution.)
Update: using DynamoDB Transactions, saving a "like" in this manner can actually be a fully ACID operation.

ERD Issue: Gallery & Company Relationship is wrong

Quick Summary: I'm building an ERD diagram and got lost in connecting two tables.
Introduction:
I'm building an ERD diagram for my project. Idea is pretty straight forward: I can type information about the company and it will be saved in the database. Later, I can see the list of submitted companies, as a list. As of now, I've information on the "paper", which I've implemented into my ERD diagram, so that later I can tell database, what exactly must be saved and where.
I have a primary table "Company_Info" which stores all the information about the company in the database. Using common sense (or not :)) I've created "Foreign Tables" that would store information about the company: "Gallery Images", "Opening_hours", etc. This way I believe, the database would more or less clear and readable by others.
ERD Diagram with the Description of all relationships
Problem Statement
The idea was to create a simple gallery for the company, so that they can upload their Product-pictures. If it's possible I would like to talk about the relationship between the Gallery and the Company tables. The way I see it, I think it should be like this:
One company can have 0,1,2 or many images. (Gallery_Images Table)
Images must be assigned to only 1 company. (Company_Info Table)
The relationship is one mandatory to many optional. (Many images & one company)
Question: I think the relationship between the Gallery_Table and Company_Info table will not work. Reason: Wrong relationship. I'm confused about the connection between those two tables.
I have made a connection via company PK & FK. This way, I think, the database would know what images belong to that specific company.
Confusion is with gallery_id in Gallery_Images table. Shouldn't it be connected with the company_info table too?
Image(BLOB) is a repeating group in Gallery_Images. This is not a problem if your purpose is to draw a diagram of an ER model.
If your purpose is to draw a diagram of a relational model, then the repeating group is a departure from First Normal Form. Relational schemas that depart from 1NF are generally subject to terrible problems, both with regard to performance and with regard to data management itself.
I don't see the Gallery table in your diagram. Did I miss something?

ER diagram - design issues

There are 3 entities:
vehicle_model
vehicle
extra_options (such as open top, leather seats, etc..)
Vehicle model can have a subset of the extra options.
Vehicle can have a subset of it's model extras.
I've been trying hours to figure out how to represent this as er diagram, but without success. I Thought about ternary relationship ,and although I don't understand it completely I think this isn't the way.
I thought about creating another 2 entities, model_ext & vehicle_ext ,so that vehicle_ext would be connected to model_ext but this isn't a good design.
This is my first er diagram design. I'm really lost (read er-diagram chapter in "Silberschatz, Database System Concepts" three times already) so any idea would be appreciated.
did you try adding a new table say 'vehicle_vehicle_model_extra_options_map'? (you can name this table to any thing short, but for better explanation i use __map as a standard way for defining the map tables.)
note those two null able foreign key columns in this table.
Basically, vehicle has one to many relation to extra_options, and vehicle_model has one to many relation to extra_options table, therefore the new table was added.
updated:

Cube Design - Bridge Tables for Many To Many mapping with additional column

Am making a cube in SQL Server Analysis Services 2005 and have a question about many to many relationships.
I have a many to many relationship between two entities that contains an additional descriptive column as part of the relationship.
I understand that I may need to a bridge table to model the relationship but I am not sure where to store the additional column - in the bridge table or elsewhere?
Many To Many relationsip in SSAS can be implemented via an intermediate fact table that contains both dimension key that subject to the relation.
For example; If you have a cube that has a book-sales-fact table and you want to aggregate total sales by author (which may have many books and a book may be written by many authors) you should also have a author-book intermediate fact table (just like in relational database world). In this bridge table, you should have both dimension keys (Author and Book) plus some measure related to the current book and author such as wages paid to the author to write the book (or chapters).
As a result, if your additional column is kind of a measure you should add that column to the intermediate fact table.

Resources