Database Design: How to prevent referential integrity violation? [closed] - database

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
Ok, maybe it's no the best title for the question, but this is the case.
I'm working on a project that already has an e-commerce. And part of the database looks like this. Everything works perfectly.
The problem comes with the references, if a user buys a product the shopping cart is closed, but if then the product is deleted or it's price changes the order becomes totally corrupted.
I've read this text -> Database Design for Real-World E-Commerce Systems
but I can't see the solution here.
What is the best way to do this. How big companies deal with this problem.
I mean what I need is to store all the details of an order with the data it had at the purchase moment.

There are different ways to solve this. One approach is to have a price history table rather than a price column that changes periodically. When you create an order you create it for a given price and given product. When you need to change the price of the product, instead of changing the value of the price column, you enter a new record in your price history table so future orders can then take the new price. Another approach is to decouple the product price information from the order. Rather than take the price from the product table, you have a column for unit price in the order table and the current value for the price is saved there.
As far as deleting products, it depends again on your situation. Generally it's not a good idea to delete rows that are needed for historical information. So if you no longer want to sell a product, rather than delete the record, you could have a column that has the availability of the product set to false. So previous orders would still relate to that product but new orders wouldn't be able to add it.

Every instance of every field in a table should have a 1:1 relationship with that instance of the table.
The problem is that the Price has a 1:1 relationship with the Product, which is good. But it should also have a 1:1 relationship with the Cart. And, since the price can change over time, it does not.
Two possible solutions: 1)Put a Timestamp on the Purchase, and keep all HistoricalPrices, then select the proper Price for the time of the purchase. This has the advantage of being able to tell exactly why the price changed, but can be extra work. 2)Add a PurchasePrice field to the Shopping_Cart_Products table. Assign the PurchasePrice value for that instance of that table at the time the purchase is made.

You have a few choices, if the products change while they're sitting in carts:
You update the cart and notify the user of the reason why.
You put all the information you need into the cart and work with that during checkout instead of the live product data.
Solution 1 requires you to do a sanity check at least once at the end of the checkout, to see if the cart is still valid. Solution 2 means that people may buy products that are somehow outdated.

Related

Order, OrderItem, Product. Write Product details to OrderItem?

This is not a question about a particular technical issue, more a general question about database design. Nonetheless, the tech stack is: ASP.NET MVC, SQL DB.
I've inherited a system recently which has an Order-->Order Item-->Product concept i.e. an order has many order items and each order item is associated with one product.
The Order Item stores the following when saved to the DB:
OrderID
ProductID
Qty
Unit Cost (written from Product)
Total NET (calculated based on Qty * Unit Cost)
VAT
Total GROSS
The Order Item viewed through the UI looks like this:
Qty | ProdCode | ProdDescription | Unit Cost | Total NET | VAT | Total Gross
Qty, Unit Cost and Totals are all pulled into the UI from the Order Item and the Product Code and Product Description are pulled from the associated Product record.
All seems sensible enough.
So my question revolves around which data should be written from the Product vs which data should be references from the Product. Specifically, the Unit Cost is written from the Product when when the Order Item is created. I assume this is because Product prices change and you don't want this change to apply to old orders. Fine, makes sense.
My question is: should the same logic should also apply to Product
Code and Product Description? And if not, why not?
To my mind, it seems like the Product Code and Description should also be getting written to the Order Item i.e. the Product Code and
Description are as liable to change as the Product Unit Cost. In which
case if you were to go back and look at an old order, the Prod Code
and Description on the order would appear to be different to what was originally ordered, which seems wrong to me.
The developer who built the system is no longer available to discuss his thinking when he designed it.
The system is working fine and there have been no complaints. However that is mainly because there have never been any updates to Prod Codes/Descriptions even though they are available to edit for various users.
I'd be interested to hear people's thoughts on it before I go making wholesale changes, is this a common scenario and am I worrying about nothing?
There are several aspects to take into consideration in such cases.
Let's start with the fact that the orders MUST be immutable.
Since the product code and description are not immutable, it would seem to make sense to keep them in the orders table at a first glance.
However, this may cause a massive amount of duplicated data, for each product in each order.
Another approach is to never keep the product code and description immutable.
One more approach is to enable the administrators edit the product code and description, but instead of updating the row in the products table you simply mark it as history (you will need to add a status column for that, of course) and add a new row with for that product, with the new code and description.
This solution will allow you to keep the integrity of the orders while allowing your administrator users to edit whatever they want, and keep the bare minimum of data, especially if the changes to the product code or descriptions are as sparse as you wrote.

Designing a database with several different kinds of products? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
As part of a recent project I have started planning out, I am required to build the structure of a database which will contain several products. As an example, think of the way Amazon is structured. It has several categories and within those categories, several sub-categories.
My problem is that conceptually I am unsure on how to build the database tables. I have thought of creating a self-referencing table for the categories and sub-categories, but since I do plan to have a wide variety of products within the database, I don't know if I should just group them into one table called "Products" or put them all in separate tables.
For example, a toilet would be one product while a television could be another. Even though they have different categories/sub-categories, they are both products. By placing them in one "Products" table, they would share attributes that would make no sense for both of them. A toilet would not need an attribute for resolution or display size(unless it is a very special toilet?) and a television wouldn't need a seat size attribute.
I thought that one to get around this and still keep everything in one table would be to create a bunch of NOT NULL attributes that could be missing for certain items if they weren't necessary, but common sense is telling me that this is probably not the best way to go about things.
So at this point, I feel that my real problem is figuring out how to structure this database and its tables with several categories/sub-categories and different kinds of items. Would I create a table for televisions and a table for toilets? How would this all be structured? How are these sort of problems normally planned out?
Thanks
A generic products table is a good way to go. You're not going to want to create a new table in your schema every time you have a new type of product.
Similar with the categories, a self referencing table is better with a parent/child relationship so you don't have to create a new table each time you want a new level of sub-category.
Your products table should contain information that's common amongst all your products. E.g. name and possibly price (although if you have different prices for an individual product, then price is best stored in another table that references the product).
If you have a bunch of other information that relates to characteristics for each product, then maybe create an attributes table and another table that references each attribute's value for that product.
Here's a simple example schema:
This is more of a design decision than anything else.
This is how I would separate the tables:
categories (e.g. household)
sub_categories (e.g. bathroom is a foreign key of household)
products (e.g. Ceramic toilet)
As for the extra attributes, you can either store these directly within the products table or create another table called products_extra_attributes and store an optional NULL value within the products table which would be a foreign key pointing toward the additional attributes for the individual product.
Make sense? I'll make an edit later on if not as I'm answering this question from my phone.
Depends on how many products. If you only sold toilets and televisions I'd say go ahead and make totally separate tables for them, however if you have 100s of different product types all of which would have different attributes I might suggest creating a products table that stored common attributes (they all have a cost and, probably, a size) then a product type table that specifies a set of attributes for each product type, then a attributes table to define the attributes and lat a product values table.
So for example, take a Sony TV. It would be in products with the price and a link to the product type, which would be TV. That would one to many join to attributes that all TVs had and Sony TV would have entries in the product values for each of those attributes. This way, you wouldn't have to redefine shared attributes, so when you started selling other things that had resolution, you could just add them to the product type.
Make sense?

design a database for a shopping-cart application? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have never designed a database/data-model/schema from scratch, especially for a web-application.
In some recent job interviews, i was asked to 'design' a database for a shopping cart application. Now i am working on a mobile shopping application (retail, uses phonegap) with a backend that needs to store and process product and order info. The scale of this problem is so huge, i don't know where to start. I was hoping for some advise on -
How should I approach such a problem (shopping cart application DB) ? where should i start ?
Are there any common mistakes/pitfalls that i should avoid ?
What optimization/efficiency paradigms should i keep in mind when designing such a DB ?
How should i go about identifying entities in the problem space (products, orders, etc)? how should i derive the relationships between them ?
When a interviewer asks such a question, what exactly is he looking for ? is there something i should/should not say ?
I should also clarify that -
Yes, I am a noob, and my motives are to learn database design AND prepare for upcoming job interviews. I have read DBMS books where they describe individual concepts in detail, but i have no clue how to put those things together and start designing a database.
I have seen other threads on database design. The authors already tend to posses some knowledge on how to break the problem down. i would like to understand the methodology behind doing that.
Links to outside resources, comments, suggestions and anything that will put me on the right track is much appreciated. I hope this thread serves as a learning experience for myself and others.
There can be five tables in database:
CATEGORY this table stores information about products categories of your store and categories hierarchy.parent field of this table stores ID of the parent category.
PRODUCT all products of your store are stored in this table. This table has a foreign key categoryID which identifies ID of the category to which a product belongs.
ORDER this table stores information about all orders made by visitors of your store.
ORDERED_SHOPPING_CART table is tightly connected with PRODUCT and ORDER tables; stores information on customers' orders content.
SPECIAL_OFFER table contains a list of products, which are shown on home page as special offers
A brief answer is the way that i would tackle this problem. Firstly, there are loads of open source or free, web based shopping carts. This means that you can get one, set up the database and then have a good look around what they did.
Ask yourself questions such as, why have they done that? Why is it good? What downside could there be? How would i do it differently? why?
I would try to procure a database design tool that allows you to visualize the database. (like database designer in visual studio or i have one from MicroOlap that does pgsql databases)
Then you need to think about what you need in the database. What is the customer going to do? Buy products! Therefore you need a products table. Without going down the whole route you can see the point. Imagine what is needed, then basically make a table for it.
If you have more than one option for a field in a table, make another table with a relation in it. So if you have a product table and you have a status field. you could have more than one status. (eg out of stock, limited number, big item, expensive) instead of hard coding these fields, make a table and allow the user to add items to the table. then in the product table add a field status_id and link it to the status table
Many - many relationships are useful things to know. (i fell short to this myself.) say you have a component and product tables. The products can be made up of lots of components and the components could be allocated to many products. Create a mediator table. Something like prodcomp( and in this you would have fields like id, prod_id, comp_id, qtyneeded).
Learn to index correctly.
Don't create the database until you have a solid idea of how it will work. this saves time in recreating it later.
There may be more to this, however, i hope i have given you a good start.

Best way to handle refunds or/ store credits in a database? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Let's say I've got a web application that is a store of some kind. I have a table that holds all of the monetary transactions.
custid, orderid,amount paid...etc
And this table is being used for sales reports and what have you.
Now we want to give a customer a credit of some kind, either a gift certificate or a refund.
is it a bad idea to just enter it in the same table with a -amount? Or is it better to put these in another table?
Is there a major flaw in setting the site up with this table structure to begin with?
I've set up a few systems like this but haven't had much feedback from others, how do you guys usually set up your tables for store like db's.
thanks,
Ken
Typically there would be a reason why you'd give a refund, so already the schema for this use case is different than that of a purchase.
So now your choice is should you store the refund in both places? It always makes me uncomfortable having multiple sources of the truth.
You will need to decide how you are going to work out the overall balance of a customer, storing the in/out in multiple places is going to make this harder than it should be. So you're back to having a single store for money in/out and a separate store for meta-data about a refund.
Purchase
--------
PurchaseId
ItemId
CustomerId
Payment
Refund
------
PurchaseId
Reason
Obviously there are other fields, as you say -ve values for refunds
As it happens this is nearer a real world paper ledger and separate 'refunds' book.
I've never had to do this , this is just me thinking out loud :-)
There are a hundred ways to skin a cat, but here are a few "food for thought" points:
You could potentially add a "Refund" column that would contain a "1" if it is a refund, or a "0" for a sale. You then have to decide whether to keep the amounts all as positive values (and just subtract if there is a "1" in the refund column) or if you want the amounts to be positive and negative and just look at the refund column as more of an indicator (possibly for reporting purposes)
You should consider your purchaseID! Do you consider it more of a "transaction ID" or an "order number". It may seem like there is no difference at first, but a transaction ID would have a unique ID for every entry that would mean a purchase would be 0000, and the refund would be 0001 (for exmaple). If you treat it as an order number, the purchase would be 0000 AND the return would also be 0000 so that you know the refund is related to that specific purpose.
Expanding on my previous point, I would suggest considering a separate Refund table that would contain a unique RefundID, CustomerID, OriginalPurchaseID, ItemID, Amount, and Reason column (and perhaps PaymentMethod). Your Sales table would remain pretty much the same: (unique) PurchaseID, CustomerID, ItemID, Amount, PaymentMethod. Also, be careful with your ItemID as the current setup would require a separate entry (with repeated purchaseID) for EACH itemID.
Hopefully this helps a little bit and can guide you to a better structure. Don't be afraid of having multiple tables, just make sure that you have a good method of relating them!

Database design for a small CRM/invoicing system

I'm currently developing a small customer relationship and invoice management system for my client. And I have run into some small issues which I would like do discuss.
What is the best practice around orders, customers and products. Should my client be able to delete orders, customers and products?
Currently I have designed my database around the principle of relationships between order, customer and product like this:
Customer
ID
Name
...
Product
ID
Name
Price
...
Order
ID
CustomerID
OrderDate
...
Order Line
ID
OrderID
ProductID
Like this I can connect all the different tables. But what if my client delete a product, what happens when he later open a order he created months ago which had that item in it. It would be gone, since it has been deleted. Same goes for customer.
Should I just disable the products and customers when the delete button is clicked or what is the best practice?
If I lets say diable a product whenever my client decides to delete it, what happens then if he later tries to add a new product with the same product ID as a disabled product, should I just enable that item again?
Please share your wisdom :D
"If I lets say diable a product whenever my client decides to delete it, what happens then if he later tries to add a new product with the same product ID as a disabled product, should I just enable that item again?"
Depends entirely on your business scenario - what is unique in the way customers maintain it currently? (say manually?) How do they handle when an old product which was earlier discontinued suddenly reappears? (Do they treat it as a new product or start referring to the old product?) I guess there are no right or wrong answers to these questions, it depends on the functionality - it is always advisable to understand the existing processes (minus the software) already followed by the customers and then map them to the software functionality.
For eg. you could always add a 'A product with this code already exists - do you want to use that instead of creating a new one?' kind of a message. Also, the product ids that you use in your tables as foreign keys, and the ones that you use to show the customer, better be different - you dont want to get them mixed up.
Why would you want to be able to delete orders? I would think that such a system would lock orders so that you know you have a good history. Same goes for customers, why delete them? Perhaps a way to "archive" them, having to set some flag, that way they don't show up on customer lists or something.
As for disabling and then entering a new item with the same product ID - I'm not sure why you'd do that either, each product ID is unique for a reason, even if you discontinue a product, it should keep it's product ID so you have a record. But if you must, then you could put a constraint in the business rules, something to the effect of "If there is no product that is active with this product ID then allow it. If we have a product that is active and it has the same product ID, then throw an error." Thus, you only allow for one active product with that product ID - but honestly, I think this would be confusing, and on the back end you'll want to use a unique id that is unchanging for each product to link between tables.
Instead of "deleting" I would add a boolean column for IsActive. That way you won't loose historical data. For instance, if they are able to delete a customer then they won't be able to look at history regarding that customer and it may make looking at statistical data hard or impossible. For the order table you could have a column that represents something like "current", "canceled", "filled" to accomplish the same thing. That column should be a code to a lookup/codetable.

Resources