I am struggling to decide on the best way to design my database tables
around my resources.
Don't.
Design your API according to RESTful principes, design your database according to normalisation principles. One does not need to impact upon the other.
Your database should not contain a SaleResource
table, it should contain a Sale
(or purchase/order) table. That table will include a primary key that uniquely identifies a Sale and foreign keys to related User and Customer tables.
You REST api will translate a request for the resource identified by GET /users/{userID}/clients/{clientID}/sales/{salesID}
to the appropriate database query, retrieve the row, construct the resource that represents a Sale and return it to the client.
Be mindful that you are currently exposing what appears to be internal database identifiers (UserID/ClientId/SalesID) to the outside world. It may be appropriate in your case but generally <entity>ID
feels off in a RESTful API.
I want to call attention to one of your business rules: Representative is Customer and is Company.
This sounds like a superclass/subclass situation to me, and I think you have the EER diagram well in hand, as far as ER modeling goes. Where things start to get interesting (and a little messy) is when you try to switch over from an ER model (which is abstract and implementation neutral) to a relational model (which is not).
At this point, you'll have to choose between a few well known techniques that make up for the fact that the relational model doesn't incorporate inheritance. You may wish to include this tag in your original question: subtypes
Here are three of the techniques in a nutshell: single table inheritance, class table inheritance, and shared primary key.
Single table inheritance lumps all the subclasses together in one table. Data that does not pertain to a given instance is left NULL.
Class table inheritance has one table for the superclass and one table for each subclass. Generalized data goes in the superclass table, and specialized data goes in the appropriate subclass table.
Shared primary key enforces the one to one nature of the relationships between each subclass and the superclass. It also allows a foreign key elsewhere in the database to reference the superclass without knowing or caring which subclass it belongs to.
For a good treatment of this subject, look up Martin Fowler's treatment on the web.
Edit based on feedback
The question of which ER model is "correct" is usually determined by the database design team by analyzing the subject matter, and coming up with a model that depicts the way it works in "the real world". This presumes that the database is yet to be designed, but the business itself has already been designed, and the business design is not to be changed. Your comment makes me think that you are designing (or redesigning) the business itself, not just the database. If so, then the question is outside the expertise of database design.
To deal more specifically with the questions you asked:
- Is supertype / subtype needed here (since subtype Entities have no unique attributes and since it gives me a headaches)
If there are no attributes that are specialized to the subtypes , then no inheritance (from a data perspective) is needed. So it won't make any difference to the relational design. Don't give yourself headaches. Pick a model that works for your business, and let it go.
- How to implement inheritance with one entity in recursive relationship - if for instance Customer / Representative is in recursive relationship (relational table example needed)
If Customer and Representative are the same entity, give them a common name. One entity with two names is confusing. If they are different entities, rephrase your question. From my answer to question 1, why is implementing inheritance called for?
Are "recursive relationship" and "reflexive relationship" the same thing? If not, please clarify your question.
- Can you give me relational solution (EER to relational) with some examples (like table with data) so I can wrap my mind around it.
That's what I thought I was answering the first time. Fowler's treatment of inheritance/relational issues is available on the web. Here and here.
His examples are about players and cricketers, not customers and representatives, but the issues concerning implementing inheritance (really pseudo inheritance) in a relational system are not case dependent.
Best Answer
You should have a table for each class of thing you want to offer a discount on. From your question that would be a table each for products, customers and stores. Most likely you will have these tables in your design already. Each will have a column of an appropriate type to hold the discount. You don't say what you will offer but a percentage discount could be a
TINYINT UNSIGNED
since it can only be in the range 0 to 100 or aDECIMAL
if you prefer to handle your math that way, and so forth if you'll offer fixed-amount discounts ("$10 off your purchase over $120. This month only!"). Name your column to match your rule e.g.DiscountPercent
orDiscountAmount
. If it is important to track changes to discounts over time separate tables keyed by date will be required e.g.CustomerDiscount (CustomerID, StartDate, EndDate, DiscountPercent)
.Be sure to work out with your business how these rules interact. If I'm a 5% customer buying a 6% product do I get an 11% discount or a (0.95 * 0.94) price? For a $100 item will I be charged $89.00 or $89.30? Can I even get more than one discount on a single purchase? Which?
If only a few combinations receive the discount you could have an intersection table keyed by, say, product and customer as you mention in your question. This works up to a couple of levels then gets very unwieldy. Then a general decision table will be your best bet. This will have a column for each of your decision variables (product, customer and store in your examples) and another for precedence/ sort order. You manually assign the precedence to match your rules and at run time pick the highest precedence which matches this sale's parameters.
An example:
Sam buys some Foo in Melbourne. She gets 7% off since that's the row with the highest Precedence that matches all the criteria (or has a NULL). Anything else Sam buys has a 5% discount. Anyone else who buys Foo gets 3% off.
It is usual to copy relevant values to the
Sales
table for each transaction. This gives youa) a complete audit history, which accountants like
b) flexibility to award non-standard discounts.