I have a situation, where with time, the same logic has been scattered at different places (stored procedures) in the application. I am trying to bring it in one place and re-use it as required.
Scenario:
We sell products online, that are classified into categories and the business rules vary by category. When performing a search, it is possible that multiple products are returned from the same category.
Examples of business rules are:
Can the agent sell a product from this category (permission, licensing etc.)?
Can the category be sold in a particular state?
Is there a tax to be applied on the category?
What is the markup for this category?
Does this 'product' meet the customer's requirements?
Current Implementation:
Step 1 - Searching
We have a stored procedure that takes #agent_id, #state_id, #markup_amount, #category_id, #customer_id as inputs and returns all products from a specific category, that meet the customer's requirements. The customer's requirements are derived using customer_id. (SELECT 'product' stored procedure)
Step 2 - Quoting
When adding a particular product to the shopping cart, the above logic is again executed with an additional parameter #product_id, to make sure that the product being added to the shopping cart, satisfies the original requirements (INSERT 'cart' stored procedure)
Step 3 - Re-Validation
If the customer's requirements change, it is possible that products already in the shopping cart still qualify. The ones that do not qualify have to be removed from the UI (is_active_flag is set 0 on SQL). So we re-use the same logic to determine what the products still meet the customer's requirements. (UPDATE 'cart' stored procedure)
Step 4 - Sale
The customer can only buy one product from a particular category. When the customer is ready to buy, we re-run the same logic to see if that particular product still passes all business rules including meeting the customer's requirements (INSERT 'sale' stored procedure)
Consolidation:
What I am looking to do is consolidate this logic in one place and reference it in different stored procedures, as required. The only variable is #product_id. When the initial search is performed, we do not know what products will qualify. Once we have a finite list of product ids, we are drilling down that list at each step.
For Example: The search stored proc may return 500 products which forms the finite list and the customer may end up adding 3 products to the shopping cart, and in the end can buy only 1. The 3 products that were added and the 1 product that was ultimately sold are a part of the finite list of 500 qualifying products.
What is the most efficient way to achieve this? Thank you.
If your goal is create something readable, you can create a boolean sql function that evaluates each product in each scenario.
Related
I am making an online market for a learning project. Pardon me for not having a diagram.
I have the tables Seller and Product,which contains data about the seller and products, respectively. A Seller can have multiple products. There is also a Receipt table that stores information regarding purchases made by a customer. This is an important record and must persist. The receipt should be able to have information on the item purchased.
However, products are dynamic, products may be added and removed. But since the Receipt should reference the Product, it means that I should not delete a Product row even if it is no longer on sale.
Is this the right way to do it? Are there any better design pattern I can use?
Yes, that is the right way to do it. If you set the referential integrity right, the system will not allow you to delete a product or seller if it has receipts. The next thing to do is to use a flag to mark the product or seller as deleted or archived. It could be either a boolean or a date that indicates when it became inactive. Using a 'From' AND a 'To' date to indicate valid time intervals, as Hellmar Becker suggests, is very powerfull, but it opens a whole new can of worms: you can have more than one 'valid' period, so you have to extend your primary key.
Modern databases like HANA (from SAP) just don't allow deletes any more, and have inbuilt 'deleted' flags.
This isn't a proper answer. I just want to give you the gift of a diagram since you didn't have one! :)
(Disclaimer: QuickDatabaseDiagrams is my project)
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
We currently have a SQL database with a table that holds online sales for our company, which sells products using other websites (say, Amazon). The table schema has been set up to hold specific sale data/attributes provided by the website our items are currently sold on (say, Site A).
We are expanding sales to other websites that provide different attributes than Site A uses when an item is sold (e.g. Site A might provide a unique sales id number, and site B might not provide a unique sales id number, but also provide some other info that Site A doesn't provide that we still need to capture).
The question is do I add a separate table for sales on each 'site' that we sell on, as the schema will be different, or try to combine all sales into one table, no matter the platform, leaving some columns null if it doesn't pertain to the particular platform? Or maybe a hybrid approach, separating only the attributes that aren't common among the two sites into separate tables, while a "master" sales table holds attributes that are shared (sale_price, sale_date, etc)?
There are also other tables in play that hold internal information (product Ids, costs, etc), that are linked to the sales table via a unique identifier. Whichever route I choose, I'd need come up with a unique identifier I could use across all tables (auto incremented sale_id, e.g.), and store that in a table for reference/joins.
Any suggestions are welcomed!
A sale is a sale >> same data belongs to the same table. I would definitely not recommend splitting your sales to several tables as this creates lots of difficulty for all that might follow: sales statistics and so on. Try to keep all sales in one table.
If it's a very small project, it might be the best shot to integrate the different fields into one table. Otherwise you might try to create profiles for every sale platform: In this case, use an Entity-Attribute-Value model.
Do not add a table for each site. It sounds like you have a many to many relationship between sites and attributes, so set up your database that way. Also, for any unique identifier you need, create it yourself.
Based on the information I have provided below, can you give me your opinion on whether its a good idea to denormalize separate tables into one table which holds different types of contracts?.. What are the pro's/con's?.. Has anyone attempted this before?.. Banking systems use a CIF (Customer Information File) [master] where customers may have different types of accounts, CD's, mortgages, etc. and use transaction codes[types] but do they store them in one table?
I have separate tables for Loans, Purchases & Sales transactions. Rows from each of these tables are joined to their corresponding customer in the following manner:
customer.pk_id SERIAL = loan.fk_id INTEGER;
= purchase.fk_id INTEGER;
= sale.fk_id INTEGER;
Since there are so many common properties among these tables, which revolves around the same merchandise being: pawned, bought and sold, I experimented by consolidating them into one table called "Contracts" and added the following column:
Contracts.Type char(1) {L=Loan, P=Purchase, S=Sale}
Scenario:
A customer initially pawns merchandise, makes a couple of interest payments, then decides he wants to sell the merchandise to the pawnshop, who then places merchandise in Inventory and eventually sells it to another customer.
I designed a generic table where for example:
Contracts.Capital DECIMAL(7,2)
in a loan contract it holds the pawn principal amount, in a purchase holds the purchase price, in a sale holds sale price.
Is this design a good idea or should I keep them separate?
Your table second design is better, and, is "normalised".
You first design was the denormalised one!
You are basiclly following a database design/modelling pattern known as "subtype/supertype"
for dealing with things like transactions where there is a lot of common data and some data specific to each tranasaction type.
There are two accepted ways to model this. If the the variable data is minimal you hold everthing in a single table with the transaction type specfic attributes held in "nullable" columns. (Which is essentially your case and you have done the correct thing!).
The other case is where the "uncommon" data varies wildly depending on transaction type in which case you have a table which holds all the "common" attributes, and a table for each type which holds the "uncommon" attributes for that "type".
However while "LOAN", "PURCHASE" and "SALE" are valid as transactions. I think Inventory is a different entity and should have a table on its own. Essentially "LOAN" wll add to inventory transaction, "PURCHASE" wll change of inventory status to Saleable and "SALE" wll remove the item from inventory (or change status to sold). Once an item is added to inventory only its status should change (its still a widget, violin or whatever).
I would argue that it's not denormalized. I see no repeating groups; all attributes depending on a unique primary key. Sounds like a good design to me.
Is there a question here? Are you just looking for confirmation that it's acceptable?
Hypothetically, what would you do if the overwhelming consensus was that you should revert back to separate tables for each type? Would you ignore the evidence from your own experience (better performance, simpler programming) and follow the advice of Stackoverflow.com?
I'm working on an ERP application where multiple inventories need to be dynamically supported, ie. each depot/branch needs a separate stock value for each product. One approach - avoiding using static table columns - is to have a separate Stock table as follows:
[Product]
Code
...
[Branch]
Code
...
[Stock]
ProductCode
BranchCode
StockValue
...
This effectively becomes a many-to-many relationship separated by the Stock table. Immediately there appears to be pitfalls in this approach, for instance:
If there are 5 branches (depots), and 50k product lines, then there will be 5*50k Stock lines. Is this excessive?
Each time a Product is added, 5 new Stock lines need to be added - one for each Branch.
Each time a Branch is added, 50k new Stock lines need to be added.
The main rationale behind this is to avoid using static columns (which may lead to modifying the mapping files as new Branches are added). So it is supposed to be more dynamic.
Has anyone worked with a similar concept in the past and may perhaps have a more efficient solution? Or if this appears to be a suitable solution, then what NHibernate association method may be most effective?
Thanks.
I would create a separate entity -- Warehouse and Stores are common names -- as a container for stock. Then create a many-to-many relationship between a Branch and the Warehouses they can access Stock from. This gives you the flexibility to have stock stored at the branch and another location (rented space) or allow multiple branches to pull stock from multiple warehouses. Robust ERP systems further classify stock locations into shelf and position, for example.
Unless every product is stocked at every branch then I don't see that your list of potential pitfalls are valid. Using the Warehouse model, Stock is a record in a many-to-many table containing the number of items in stock at a warehouse. If the record does not exist than there are none at that location.