Approach shopping cart storage, database with sessionID - asp.net-mvc-4

Just to be clear, I'm going to store my shopping cart in a database.
It's just that I would like information regarding the details on how to store it exactly.
I have the following structure for my shopping cart and orders:
First of all, is this technically a good approach?
A product is added to a cart with the sessionID, date and amount.
Do I add another table or rename the table given that it's not really carts but more collection of products from different carts?
When a user wants to order his products we place them in the order_items table. When the user selects purchase his order is placed in the orders table.
Is this a good approach, are there better ones?
P.S.: the user doesn't need to be registered to place an order.

What I usually do is have an intermediate table, something like ProductsInCart, with three columns, ProductID, CartID, and Quantity. ProductID keys into Products, CartID keys into Carts, and quantity is simply a positive integer.

Related

Need clarification re Product table and Sku table - BigCommerce

I see that the Sku fields are duplicated in the Product table.
When creating a product in BigCommerce from info in an independent POS system:
If there is only one Sku, do we create a Sku record in addition to the Product record?
If there are two Skus associated with an image and description, do we put the info for the first Sku in the product record and create a Sku record for only the second product, or do we create a sku record for each of the 2 skus?
In another ecommerce solution, each product has at least one variant (the default variant), and if there are 2 variations, then there are 2 variant records. It seems as though the Sku table is like what I am familiar with for variants. But BigCommerce may handle this differently and put the data for the default "variation" in the product record, and only use Sku records when there is more than one variation.
In BigCommerce (and some other systems), SKUs are considered unique identifiers. In BigCommerce, you can only have unique SKU once (no duplicating) and a unique product name (also not able to be duplicated).
SKUs in BC correspond to variants/combinations of options that make up a variant product. There is a default "parent product" or simple product associated with a parent SKU (if any) and then variants generally have unique SKUs, but aren't required to have SKUs.
If a product has variants, you do create additional skus in addition to the parent sku/product.
You can get a little bit more clarity through some of the API documentation for our V3 catalog api

Problems with modeling a POS (Point-of-sale) system

At first a apologize for being a beginner in databases. I'm developing a POS system and I'm having some trouble in modeling the part of the system which controls the customer's account. I'll try to explain the requirements below:
The customer has a unique credit account;
This credit account will have zero or several sales;
Each sale will be one or several products.
These are the mainly requirements. What I'm trying developing is a way you can, using the system, query the customer's account and see the sales and their respective products (grouped by dates for example) the customer purchased on that sale.
I've already taken a look on the kinds of database relationships, but I cannot find a solution on using the many-to-many relationship. Can you help me? Thanks.
The way I see it from what I understand is you're going to have to separate this out into data tables
From your description we can identify some entities,
Customer
CreditAccount
SaleOrder
Product
Once you had this set up, you could create a query to do what you just described, short of doing it for you, this would be a good start for a suitable solution.
Assuming you have tables such as:
CreditAccount
Product
your sale will most likely result in an Invoice table (or a Sale table - I don't know your business well).
This table will resolve the many-to-many between the Product table and the CreditAccount table.
The Invoice table may look like this (it may vary greatly based on your other needs):
InvoiceNumber (A good candidate for primary key, business rules required for pros and cons)
CreditAccount_FK (Foreign key pointing to the primary key in CreditAccount table)
Product_FK (Foreing key pointing to the primary key in Product table)
Other sale or invoice columns such as branch, sales person, date, time, tax, payment method, etc.
You could choose to define a unique key on the pair(CreditAccount_FK, Product_FK). If you don't have a unique InvoiceNumber, you may use the combination above to be the primary key.

One-to-one relationship or One-to-many?

Maybe I need more coffee this morning but here goes...
I have a very simple inventory system. Right now I have two tables: Items and Inventory.
Items
Id
Title
YearReleased
Inventory
Id
ItemId(Foreign key to Items)
Quantity
QuantityOnHand
Each item has one inventory and each inventory belongs to one item. The relationship between the two is one-to-one. However, when I diagram this out, the relationship based on my setup thus far is a one-to-many, due to the auto-incrementing id I have for Inventory.
Now, I could make this one-to-one by eliminating the auto incrementing id in the Inventory table, but this makes me feel dirty. I always use internal id's for primary keys.
I see a few options:
1.) Remove the auto incrementing id field in Inventory and live with the dirty feeling.
2.) Keep the tables as-is.
3.) Merge Items and Inventory into one table: ItemsInventory.
4.) Something else?
If your relationship is really one to one, drop the Id from the Inventory table and use ItemId as PK and FK. Also, name both keys ItemId -- helps.
If you're certain that the mapping will always be 1:1, then merge the two tables into one.
However, are you certain that the relationship will allways be 1:1?
Since many ORMs require a single auto-increment PK, I would:
4) Add a unique index to Inventory.ItemId and it should show as a one-to-one relationship.
Would making ItemId have a constraint to be unique be insufficient? That seems to satisfy your requirements.
If what the table structure you have mentioned is going to remain as it is now, then I think you should merge Items and Inventory into one table: ItemsInventory.
For such small tables it doesn't make sense to partition them vertically. That way you would remove an extra join. Select on a single table is always faster then joins.
I would merge the two tables together my main reason is you will have duplicate data as
well as unnecessary data if you stick with two tables. Querying will also be faster! Looking at the two tables I would merge into one for sure.
Items
Id
Title
YearReleased
Inventory
Id
ItemId(Foreign key to Items)
Quantity
QuantityOnHand
You will have two less collumns full of data if you merge to one table ("ID" ItemID" can be dropped). Writing your logic to retrive and send data to the database will also be easier for you.
I would have this table:
**ItemsInventory**
Id
Title
YearReleased
Quantity
QuantityOnHand
However you must be sure it is a one-one otherwise you may have give yourself a lot of work if the bussiness needs change.
Simon
If you really want to make it a simple inventory system, then merge the tables.
Reasons not to merge the tables/it doesn't stay simple.
How many items will NOT have an inventory record? Your example only shows a few inventory fields and maybe that's all it would ever have. But it the fields you track in inventory grow and there is a large part of items not in inventory, you're going to have a lot of null fields.
How often will inventory get updated? If these fields are a result of other transaction tables (purchases and sales) being updated frequently, no reason to constanatly update the items table just because inventory was purchased or sold. In your current system, users are expecting these values to be real time (If not then they know what isn't up to date since they didn't make the changes.).

Doubt regarding a database design

I have a doubt regarding a database design, suppose a finance/stock software
in the software, the user will be able to create orders,
those orders may contain company products or third-party products
typical product table:
PRIMARY KEY INT productId
KEY INT productcatId
KEY INT supplierId
VARCHAR(20) name
TEXT description
...
but i also need some more details in the company products like:
INT instock
DATETIME laststockupdate
...
The question is, how should i store the data?
I'm thinking in 2 options:
1 -
Have both company and third-party, products in a single table,
some columns will not be used by third-party products
identify the company products are identified by a supplier id
2 -
Have the company products and third-party in separated tables
3 - [new, thanks RibaldEddie]
Have a single product table,
company products have additional info in a separated table
Thanks in advance!
You didn't mention anything about needing to store separate bits of Vendor information, just that a type of product has extra information. So, you could have one products table and an InHouseProductDetails table that has a productId foreign key back to the products table that stores the company specific information. Then when you run your queries you can join the products table to the details table.
The benefit is that you don't have to have NULLable columns in the products table, so your data is safer from corruption and you don't have to store the products themselves in two separate tables.
Oooo go with 3! 3 is the best!
To be honest, I think the choice of #1 or #2 are completely dependent upon some other factors (I can only thing of 2 at the moment):
How much data is expected (affecting speed of queries)
Is scalability going to be a concern anywhere in the near future (I'd guess within 5 years)
If you did go with a single table for all inventory, then later decided to split them, you can. You suggested a supplier identifier of some sort. List suppliers in a table (your company included) with keys to your inventory. Then it really won't matter.
As far as UNION goes, it's been a while since I've written raw Sql - so I'm not sure if UNION is the correct syntax. However, I do know that you can pull data from multiple tables. Actually just found this: Retrieving Data from Multiple Tables with Sql Joins
I agree with RibaldEddie. Just one thing to add: put a unique constraint on that foreign key in your InHouseProductDetails table. That'll enforce that it's a one-to-one relationship between the two tables, so you don't accidently end up with two InHouseProductDetails records for one product (maybe from some dataload gone awry or something)
Constraints are like defensive driving; they help prevent the unexpected...
I would advice on using point #1. What happens when another supplier comes along? It's also more easy to extend on one product table/produst class.
Take into account the testing of your application also. Having all data in one table raises the possible requirement of testing both the 3rd Party & Company elements of your app for any change to either.
If you're happy that your Unit test would cover this off its not so much of a worry... if you're relying on a human tester then it becomes more of an issue when sizing the impact of changes.
Personally I'd go for the one products table with common details and separate tables for the 3rd party & Company specifics.
one table for products with a foreign key to the Vendor table; include your own company in the Vendor table
the Stock table can then be used to store information about stock levels for any product, not just yours
Note that you need the Stock table anyway, this just make the DB model more company-agnostic - so if you ever need to store stock level information about third-party products, there's no DB change required

Single or multiple mysql rows? (shopping basket)

I am currently creating a custom e-commerce site (in php, but that's not really relevant for this question).
I have just got to creating the shopping basket, and cannot decide between the following 2 options:
option 1:
Basket table:
id
user
items
In this option, I would have one row per user, with all of the items and quantities stored in the items field.
This format is already used in the cookie based basket for non-logged in users, so parsing of the items field is no problem.
option 2:
Basket_items table:
id
user
item
quantity
In this option, I would have one row per item in the basket.
option 3:
suggest a better idea.
conclusion
Both of these options are equally easy for me to implement, so the question comes down which would be more efficient/convenient for updating the basket.
Thank you for any answers, Nico
Option 2 is the way to go. Storing all items and quantities in items field (option 1) means you are going against the relational nature of MySQL. You'll have to define a format and parse it with option 1, additional code you don't have write with option 2. Also, with Option 2, you'll be able to do other things easier down the line, like calculate totals, shipping amounts, etc, as well as reporting on item quanities sold (just a simple query).
Of course, if I was writing this, I'd also ask myself if there is a library available to do this - why reinvent such common a functionality as shopping cart. I am not from PHP world, so I don't know what the options are, but I am sure there must be something you can reuse. So ultimately, I'd encourage you to choose option 3 - don't implement it yourself if you an avoid it :-)
Use Option 2 - you can't realistically support changes to a shopping cart using Option 1, or report from it.
OPTION 3
You will need, at a minimum, a basket table and a basket_items table. Shopping carts become inherently bloated and you will soon realize you're going to need more relation tables than you anticipated. Breaking the tables up in this manner provides a 1-to-many relationship for each user's basket to their items.
This will let you do things in the future like apply promotional codes to each user's basket.
basket
id
user_id
basket_items
id
basket_id
item_id
quantity
Option 1 would require you to serialize the data in the items column which is generally frowned upon for complexity and performance reasons.
You're using a DB for its linking capabilities so lets use them. Your cart_items table should work out really nicely. This way each cart can point to a user and all the items in the cart can point to the cart.
Option 2. This is the best option and provides good data normalisation. It will give way for possible future advanced selects and filtering of the users basket.
Options 2 is the preferred option.
"item_id" could be a id to a table where all items are stored (Store table) and where the complete description and other information is available for this item. But I would add a price tag to this basket for each item and often it makes sense, to add also the users session id /md5 hash to this basket. So the SQL query string for PHP to create such table, could be something like:
$sql="CREATE TABLE ".$table_prefix."Basket (
id int(11) NOT NULL auto_increment,
sid varchar(50) default NULL,
item_id int(10) default NULL,
quantity int(10) default 1,
price varchar(10) default NULL,
PRIMARY KEY(id)
) $collate_charset;";
$collate_charset: something like $collate_charset="DEFAULT CHARACTER SET utf8";
$table_prefix: often useful to have a prefix for the tables like $table_prefix="myshop_";
With such table you can benefit from SQL functions like "Sum" to get a quick subtotal of a user or all users without much code ("Select Sum(price * quantity) WHERE sid = '1234'").
If this basket is also for "guests", you need another table where the session-id and creation date is stored, so you can regularly cleanup the basket from unused entries.