I'm making a JavaFX desktop application. It's a Point of sale system that tracks orders in a restaurant. I am very new to this and things got confusing after I fired up my phpmyadmin to create my database.
This is the relevant part of my UML :
Some examples to clarify the tables' content :
Ingredient table may contain : Flour, sugar, beef, eggs...
ArticleMenu table may contain : Pizza, Burger...
ArticleMenu is made of a bunch of ingredients , but these ingredient can still exist on their own, so it's an aggregation I thought.
The issue is to translate this into a relational database, and especially the aggregation.
What I tried :
in ArticleMenu, the 'recette' attribute is a FK that refrences a row from Ingredient table, the 'recette' attribute is of type ENUM , which can hold many values the user defines when creating a row in ArticleMenu.
Example :
ArticleMenu table has a row that represents let's say Pizza, one of it's attributes is recette of type ENUM and has the values "Cheese, flour, yeast, onions, tomato, mushroom, oil"
My question :
is this an acceptable way of representing an aggregation and what would be the most optimal way?
Edit :
After reading Christophe's answer it's clear that I did not
understand what ENUM is.
The IBM document he linked cleared a lot of confusion I had relating
to this topic.
Stock information shouldn't be part of the ingredient table since
there could be many states of the same ingredient, so I removed
those.
As for the quantities used in each recipie, those will be represented
using the quantity attribute from the recipie table.
So I re-thoought my approach and came up with this design:
Problem with your approach
You implemented what Martin Fowler calls a foreign key mapping, which implements a one to (potentially) many relationship:
Here, Recipe ('recette') would implement a many-to-one relationship between ArticleMenu and Ingredients: one article would have only one ingredient, and one ingredient can appear in many articles.
Moreover the ENUM lets you chose for one row only one value among severals. The ENUM is in fact just a handy replacement for using a number instead of a string.
So, no, it's not the right approach.
Many-to-many association and the hidden table
What you need is to implement a many-to-many association: each ArticleMenu could have many Ingredients, and conversely each Ingredient could be used in many ArticleMenu.
In an RDBMS, this can be implemented using an association table. It's a table taht is not visible in your conceptual model. This association table could for example be called Recipe and have two columns: idArticleMenu and idIngredient. You can then find:
all the ingredients of an article, by looking for every recipe row that has the relevant idArticleMenu.
all the articles in which an ingredient is used, by searching for the idIngredient
Completing your model
Now if you speak of recipe and flour, the next question in your application would be: how many flour do I need to make 1 pizza ?
Unfortunately, this Quantity is not a property of ArticleMenu, since every ingredient of the same article could have a different quantity. It is not either a property of Ingredient, since an ingredient is used with different quantities, depending on the article for which it is used. So where to put this ?
The answer is an association class
Additional advice
You can use the aggregation to express the whole-part relationship. However the aggregation semantic is not clearly defined in the UML specification. So there is no fundamental benefit in using it. You could therefore use a normal association here.
In a design model (conceptual), you should not show in a class the properties that implement a relation. You could show the name of such properties at the other end of the association it will implements. If an implementation model, you could very well show all the columns of a table. The usual practice is then to use a «table» stereotype for each class that would be mapped to a table.
Related
I have a particular problem from my assignment which goes like this :
"Each product making up a set is supplied by a single supplier and is given a unique ID,. Products are always sold as part of a set, never on their own."
So based on this is assumed Many Products creates One Package(aka set), but i don't know if i'm right, if so how can I visually show a Many to One relationship as an ER diagram.
I have constructed my own Conceptual and Logical ER diagram, I just need to know if i'm right or wrong so that i can continue with the rest.
Here's a breakdown of the assignment and what I get from it:
Each product making up a set is supplied by a single supplier and is given a unique ID,. Products are always sold as part of a set, never on their own.
From this I get that we have these entities:
Product
Supplier
Package (Set)
You should know that each Entity needs its own primary key. Pros will either call this id, or product_id. There are ORM's that tend to work best out of the box, if you name the pk for each table 'id', especially when it is a simple sequence number.
It's also better not to do what you are doing with attribute names. In sql people stick with either all uppercase or all lowercase naming rather than camelcase. Also I'd suggest that you don't name the price attribute pPrice just because it's in the Package table. Just name it price, because it can be referred to as Package.price if you need to tell it apart from some other table that also contains a price column.
The important thing to understand is that the relationship between Package and Product is Many to Many
One Product can be part of Many Packages.
One Package can contain Many Products
In order to create entities for a Many to Many relationship, you need a table that sits between the 2 tables and will have foreign keys to both tables in it. Typically people will pick whatever they consider the dominant side -- I would probably use Package, and name the table "PackageProduct" to reinforce the idea that this table lets me package products together and sell or distribute them.
PackageProduct
--------------
id (pk)
package_id (foreign key to Package table)
product_id (foreign key to Product table)
You also need a supplier table, but you were informed that the relationship between Package and supplier is that a Package can have one and only one Supplier.
This is code for: create a one to many relationship between Supplier and Package. In doing this, Package will have a foreign key in it that stores the Supplier.id (or supplier_id)
So to conclude you should have these entities (tables):
Package
Product
Supplier
PackageProduct
ERD
Here's an ERD rendered with "Relational" format which I find a bit more descriptive, as the many sides of the connections use the crowsfoot, so it's very obvious.
According to your description your schema will have one to many relation i.e your single package comprises many products.
You can also find out your ERD diagram
Do table associations need to have roles. I find this difficult to understand for example if there is a product table and an inventory table and A row in the product table is associated with many rows in an inventory table.(eg. each copy of a particular product has a unique serial number which is a foreign key referencing a column in the inventory table)can be associated with one or (likely) more rows in another table
I find this kind of relationship difficult to describe. If it were inverted you could say a product is held in 1 and only 1 inventory and an inventory contains 1 to many products.
I was having trouble understanding a similar problem as described above until I found the various definitions for the relationships on this page
http://help.filemaker.com/app/answers/detail/a_id/9922/~/understanding-and-creating-many-to-many-relationships-in-filemaker-pro
Maybe I am thinking about it the wrong way
Read about Chen's ERM (Entity-Relationship Model) method/diagrams: Entities are boxes (& entity type tables), relation(ship) types are diamonds (& association tables), participations of entity types are lines from diamond to box (& FKs) and properties (non-entity "participants" or attributes) are ovals on lines. This makes it clear what is a relation(ship)/table and what is a participation/FK. Then some ER variants misuse the term "relationship" for FK and leave out diamonds so it's not so clear what the relation(ship)s and participations are. (See wikipedia Entity-relationship model.) You use the term "role", which is used in Object-Role Modeling for participation (by entity or property). It is the truest to the relational model and can be mapped to ER and ER variant methods. (ER has the problem of artificial distinctions. There is really no difference between an entity, relationship or property, and every table superkey corresponds to an "entity".)
I was studying about relationships in RDBMS.I have understood the basic concept behind mapping relation ship,but I am not able to spot them.
The three possibilities :
one to many(Most common) requires a PK - FK relationsip.Two tables involved
many to many(less common) requires a junction table.Three tables Involved
one to one(very rare). One table involved.
When I begin a project,I am not able to separate the first two conditions and I am not clear in my head.
Examples when I study help for a brief moment,but not when I need to put these principles in to practice.
This is the place where most begineers falter.
How can I spot these relationships.Is there a simpler way?
Don't look at relationships from a technical perspective. Use analogies and real-life examples when trying to envision relationships in your head.
For example, let's say we have a library database.
A library must have books.
M:M
Each Book may have been written by multiple Authors and each Author may have written multiple Books. Thus it is a many-to-many relationship which will reflect into 3 tables in the database.
1:M
Each Book must also have a Publisher, but a Book may only have one Publisher and a Publisher can publish many Books. Thus it is a one-to-many relationship and it reflects with the PublisherId being referenced in the Books table.
A simple analogy like this one explains relationships to their core. When you try to look at them through a technical lens you're only making it harder on yourself. What's actually difficult is applying real world data scenarios when constructing your database.
I think the reason you are not getting the answers that you need is because of the way you are framing the question. Instead of asking “How do I spot the correct type of relationship between entities”, think about “How do my functional needs dictate what relationship to implement”. Database design doesn’t drive the function; it’s the functional needs that drive the relationships you need to implement.
When designing a database structure, you need to identify all the entities. Entities are all the facts that you want to store: lists of things like book titles, invoices, countries, dog species, etc. Then to identify your relationships, you have to consider the types of questions you will want to ask your database. It takes a bit of forward thinking sometimes… just because nobody is asking the question now doesn’t mean that it might not ever be asked. So you can’t ask the universe “what is the relationship between these lists of facts?” because there is no definitive answer. You define the universe… I only want to know answers to these types of questions; therefore I need to use this type of relationship.
Let’s examine an example relation between two common entities: a table of customers and a table of store locations. There is no “correct” way to relate these entities without first defining what you need to know about them. Let’s say you work for a retailer and you want to give a customer a default store designation so they can see products on the website that their local store has in stock. This only requires a one-to-many relationship between a store and the customer. Designing the relationship this way ensures that one store can have many customers as their default and each customer can only have one default store. To implement this relationship is as easy as adding a DefaultStore field to your Customer table as a foreign key that links to the primary key of the Store table.
The same two entities above might have alternate requirements for the relationship definition in a different context. Let’s say that I need to be able to give the customer the opportunity to select a list of favorite stores so that they can query about in stock information about all of them at once. This requires a many-to-many relationship because you want one customer to be able to relate to many stores and each store can also relate to many customers. To implement a many-to-many relationship requires a little more overhead because you will have to create a separate table to define the relationship links, but you get this additional functionality. You might call your relationship table something like CustomerStoreFavorites and would have as its primary key as the combined primary keys from each of the entities: (CustomerID, StoreID). You could also add attributes to the relationship, like possibly a LastOrderDate field to specify the last date that the customer ordered something from a particular store.
You could technically define both types of relationships for the same two entities. As an example: maybe you need to give the customer the option to select a default store, but you also need to be able to record the last date that a customer ordered something from a particular store. You could implement the DefaultStore field on the Customer table with the foreign key to the Store table and also create a relationship table to track all the stores that a customer has ordered from.
If you had some weird situation where every customer had their own store, then you wouldn’t even need to create two tables for your entities because you can fit all the attributes for both the customer and the store into one table.
In short, the way you determine which type of relationship to implement is to ask yourself what questions you will need to ask the database. The way you design it will restrict the relational data you can collect as well as the queries you can ask. If I design a one-to-many relationship from the store to the customer, I won’t be able to ask questions about all the stores that each customer has ordered from unless I can get to that information though other relationships. For example, I could create an entity called "purchases" which has a one-to-many relationship to the customer and store. If each purchase is defined to relate to one customer and one store, now I can query “what stores has this customer ordered from?” In fact with this structure I am able to capture and report on a much richer source of information about all of the customer's purchases at any store. So you also need to consider the context of all the other relationships in your database to decide which relationship to implement between two particular entities.
There is no magic formula, so it just takes practice, experience, and a little creativity. ER Diagrams are a great way to get your design out of your head and onto paper so that you can analyze your design and ensure that you can get the right types of questions answered. There are also a lot of books and resources to learn about database architecture. One good book I learned a lot from was “Database System Concepts” by Abraham Silberschatz and Henry Korth.
Say you have two tables A and B. Consider an entry from A and think of how many entries from B it could possibly be related with at most: only one, or more? Then consider an entry from B and think of how many entries in A it could be related with.
Some examples:
Table A: Mothers, Table B: Children. Each child has only one mother but a mother may have one or more children. Mothers and Children have a one-to-many relationship.
Table A: Doctors, Table B: Patients. Each patient may be visiting one or more doctors and each doctor treats one or more patients. So they have a many-to-many relationship.
An example of one to one:
LicencePlate to Vehicle. One licence plate belongs to one vehicle and one vehicle has one licence plate.
We have a J2EE content management and e-commerce system, and in this system – for sake of a simple example – let’s say that we have 100 objects. All of these objects extend the same base class, and all share many of the same fields.
Let’s take two objects as an example: a news item that would be posted on a website, and a product that would be sold on a website. Both of these share common properties:
IDs: id, client ID, parent ID (long)
Flags: deleted, archived, inactive (boolean)
Dates: created, modified, deleted (datetime)
Content: name, description
And of course they have some properties that are different:
News item: author, posting date
Product: price, tax
So (finally) here is my question. Let’s say we have 100 objects in our system, and they all follow this pattern. They have many fields that overlap, and some unique fields. In terms of a relational database, would we be better off with:
Option One: Less Tables, Common Tables
table_id: id, client ID, parent ID (long) (id is the primary key, a GUID for all objects)
table_flag: id, deleted, archived, inactive (boolean)
table_date: id, created, modified, deleted (datetime)
table_content: id, name, description
table_news: id, author, posting date
table_product: id, price, tax
Option Two: More Tables, Common Fields Repeated
table_news: id, client ID, parent ID, deleted, archived, inactive, name, description, author, posting date
table_product: id, client ID, parent ID, deleted, archived, inactive, name, description, price, tax
For full disclosure – I am a developer and not a DBA, and because of that I prefer option one. But there is another team member that prefers option two, and I think he makes valid points.
Option One: Pros and Cons
Pro: Encapsulates common fields into common tables.
Pro: Need to change a common field? Change it in one place.
Pro: Only creates new fields/tables when they are needed.
Pro: Easier to create the queries dynamically, less repetitive code
Con: More joining to create objects (not sure of DB impact on that)
Con: More complex queries to store objects (not sure of DB impact on that)
Con: Common tables will become huge over time
Option Two: Pros and Cons
Pro: Perhaps it is better to distribute the load of all objects across tables?
Pro: Could index the news table on the client ID, and index the product table on the parent ID.
Pro: More readable to human eye: easy to see all the fields for an object in one table.
My Two Cents
For me, I much prefer the elegance of the first option – but maybe that is me trying to force object oriented patterns on a relational database. If all things were equal, I would go with option one UNLESS a DB expert told me that when we have millions of objects in the system, option one is going to create a performance problem.
Apologies for the long winded question. I am not great with DB lingo, so I probably could have summarized this more succinctly if I better understood terms like normalization. I tried to search for answers on this topic, and while I found many that were close (I suspect this is a common DB issue) I could not find any that answered all my questions. I read through this article on normalization:
But I did not totally understand it. On the one hand it was saying that you should remove any redundancies. But on the other hand, it was saying that each attribute should define only one object.
Thanks,
John
You should read Patterns of Enterprise Application Architecture by Martin Fowler. He writes about several options for the scenario you describe:
Single Table Inheritance: One table for all object subtypes. Stores all attributes, setting them NULL where they are inapplicable to the row's object subtype.
Class Table Inheritance: One table for column common to all subtypes, then one table for each subtype to store subtype-specific columns.
Concrete Table Inheritance: One table for each subtype, storing both subtype-specific columns and columns common to all subtypes.
Serialized LOB: One table for all object subtypes. Store common attributes as conventional columns, but combine optional or subtype-specific columns as fields in a BLOB that stores XML or JSON or whatever format you want.
Each one of these designs has pros and cons, so choose a solution depending on the most common way you access your data.
However, notice I use the word subtype above. I would use these designs only if the different object types are subtypes of a common base class. I'm assuming that News item and Product don't actually share a logical base class (besides Object); they are not subtypes of a common superclass.
So for the sake of OO design, I would choose Concrete Table Inheritance. This avoids any inappropriate coupling between these subtypes. There are columns the two tables have in common, but they basically amount to bookkeeping, not anything to do with the function of the class and hence the table.
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...