I got my first professional project where I have to create a warehouse inventory web application. I have completed the front-end however I am stuck on the database modal - I'm not entirely sure if I got it right.
(ignore the scribble)
Basically, the company only needs to keep track of their stock level in each of their warehouse and do not need to add supplier details or any cost/sale prices.
These are all the tables and links I could think of however, even though this might work (or not), is this the correct design modal? (specifially the central table)
.
.
Right and Wrong are not absolute. That being said, here is my opinion on your model:
1) Are you sure purchases and sales should be two different tables? They have the same fields. Make them one and add a field that determines whether it's a purchase or sale.
2) The fact that the stock table has the same keys (warehouse,item) that the sales/purchases,inventory, and transfers table does not make it a logical centre table. My design would be:
Tables barcodes,items,warehouses as you already have them.
The remaining tables should have foreign keys on items,or warehouses, or both, whatever exists. There is no reason to make a 2-field FK towards the stock-locations table
The transfers item should have both warehouse_from and warehouse_to FK referenceing warehouses. And item, of course.
Related
I am designing as a project a web store (using PHP Laravel and MySQL FYI) and I am at the part where I have to create the logic behind the production system, which goes like this:
-On my Database,
I have 1 ORDER table where I have all the information regarding the shipping, customer, etc.
I have another table called ITEM where are listed all the Items in an order (so if an order has 3 items, there will be 3 lines in the ITEM table with a Foreign Key pointing to the ORDER).
Now I'm creating the PRODUCTION DASHBOARD. Right now I'm able to scan the item ID and get the shipment information on the Dashboard.
After that, for orders with multiple items what I want to do is for the system to tell the user to deposit the item in a numbered box to wait for the rest of the items from the order. That way the user can keep scanning items from other orders and once another item from the ordered stored in X box is produced, he can scan it and the system will then tell him that the other items from the same Order and placed on X box and he can do that until the order is complete.
My question is what would be the best way and logic Database wise (and also Laravel wise if you want to further expand your answer hehe) to implement this BOX system.
I hope my question is clear enough and thank you very much :)
I had a similar system for a project that I was working on. What I did was, was create a database table called temp_orders with a column called items that each item was separated by a line break. Until the order was finalized (100% processed), the order would remain in temp_orders.
Once finalized, it would get deleted from temp_orders and moved over to the orders table. If I needed to check items, I would explode() the data from the items column in temp_orders table using a line break, thus putting them into an array and then using the data however I needed to.
You need to determine when you want to finalize the order. It could be upon credit card payment, or upon user order confirmation, for example.
I am designing a database for a system that will handle subscription based products, standard one off set price purchase products, and billing of variable services.
A customer can be related to many domains and a domain may have many subscriptions, set priced products or billed variable services related to it.
I am unsure whether to seperate each of these categories into their own 'orders' table or figure out a solution to compile them all into a single orders table.
Certain information about subscriptions is required such as start date or expiry date which is irrelevant for stand alone products. Variable services could be any price so having a single products table would mean I would have to add a new product which may be never used again or might be at a different cost.
What would be the best way to tackle this, and is splitting each into seperate order tables the best way?
Have you looked at sub-typing - it might work for you. By this I mean a central "order" table containing the common attributes and optional "is a"/one-to-one relationships to specific order tables. The specific order tables contain the attributes specific only to that type of order, and a foreign key back to the central order table.
This is one way of trying to get the best of "both" worlds, by which I mean (a) the appropriate level of centralisation for reporting on things common and (b) the right level of specialisation. The added nuance comes at the cost of an extra join some times but gives you flexibility and reporting.
Although I am a little biased in favour of subtypes, some people feel that unless your order subtypes are very different, it may not be worth the effort of separating them out. There is some seemingly good discussion here on dba.stackexchange as well as here. That being said, books (or chapters at least) have been written on the subject!
As with any data model, the "best" way depends on your needs. Since you don't specify a lot of details regarding your specific needs, it's difficult to say what the bets model is.
However, in general you need to consider what level of detail is necessary. For example if all subscriptions cost the same and are billed on the 1st of the month, it may be sufficient to have a field like is_subscription ENUM ('Y', 'N') in your orders table. If billing dates and prices for subscriptions can vary however, you need to store that information too. In that case it may be better to have a separate table for subscriptions.
Another consideration is exactly what an "order" represents in your model. One interpretation is that an order includes all the purchases included in one transaction, including both one-off purchases, variable services and subscriptions. A completed order would then result in a bill, and subscriptions would be automatically billed on the proper day of the month without a new order being made.
You should aim to have one database design that is not hardwired into specifics regarding its contents, and if it does (have to) it does in such a way that it seperates the specialization from the core DB design.
There are certain fields that are common for each order. Put these in one table, and have it refer to the other rows in the respective (specialized) tables. Thats DB normalization for you.
You could have main table contain ID, OrderID, ItemType, ItemID when ItemType determines the table ItemID refers to. I advise against this, but must admit that i use this sometimes.
Better would be to have these tables:
Clients: ID, Name, Address, Phone
Sellers: ID, Name, CompanyAlias
Orders: ID, ClientID, SellerID, Date, Price
OrderItems: ID, OrderID, DiscountAmount, DiscountPercentage,
ProductDomainID, ProductBottleID, ProductCheeseID, ..
Now OrderItems is where the magic happens. The first four fields explain themselves i guess. And the rest refers to a table which you do not alter or delete anything ever:
Products_Cheese ID, ProductCode, ProductName, Price
And if you do need a variant product for a specific order add a field VariantOfID thats otherwise NULL. Then refer to that ID.
The OrderItems table you can add fields to without disturbing the established DB structure. Just constrict yourself to use NULL values in all Product*ID fields except one. But taking this further, you might even have scenario's where you want to combine two or more fields. For example adding a ExtraSubscriptionTimespanID or a ExtraServicelevelagreementID field that is set alongside the ProductCheeseID.
This way if you use ProductCheeseID + ExtraSubscriptionTimespanID + ExtraServicelevelagreementID a customer can order a Cheese subscription with SLA, and your database structure does not repeat itself.
This basic design is open to alterative ideas and solutions. But keep your structure seperated. Dont make one huge table that includes all fields you may ever need, things will break horribly once you have to change something later on.
When designing database tables, you want to focus on what an entity represents and having two or more slightly different versions of what is essentially the same entity makes the schema harder to maintain. Orders are orders, they're just different order types for different products, for different customers. You'd need a number of link tables to make it all work, but you'd have to make those associations somehow and it beats having different entity types. How about this for a very rough starting point?
What would be the best way to tackle this, and is splitting each into seperate order tables the best way?
That depends. And it will change over time. So the crucial part here is that you create a model of the orders and you separate the storage of them from just writing code dealing with those models.
That done, you can develop and change the database structure over time to store and query all the information you need to store and you need to query.
This for the general advice.
More concrete you still have to map the model onto a data-structure. There are many ways on how to solve that, e.g. a single table of which not all columns are used all the time (flat table), subtype tables (for each type a new table is used) or main table with the common fields and subtype tables containing the additional columns or even attribute tables. All these approaches have pros and cons, an answer here on Stackoverflow is most likely the wrong place to discuss these in full. However, you can find an insightful entry-level discussion of your problem here:
Entity-Attribute-Value (Chapter 6); page 61 in SQL Antipatterns - Avoiding the Pitfalls of Database Programming by Bill Karwin.
I am building a web application that has users and orders. I have a question about how to handle the relationship between the two.
An order belongs to a user. But here's the twist, a user can optionally choose to outsource an order to another user.
When an order is outsourced, the original user still remains the owner and only he can modify certain things like price, quantity etc on the order.
The user the order is outsourced to can view some of the order information and can update specific properties on the order like marking as fulfilled.
An outsourced order should show up on both users "orders index".
All the users are "equal" meaning on certain orders a user might be the owner and on others he might be fulfilling the order. A user can also fulfill his own orders.
It doesn't seem like a true many to many relationship as one of the users doesn't really own the order, he just has limited access to it.
What would be the simplest way to handle this order/users relationships? I would like to avoid using a complete permission system, is there a way to simply handle this with an "outsourced" table? How about having a user_id and outsourced_to field on the order table?
Thanks for your input!
If it's of any help, the application uses Laravel.
It seems like your Orders table has two separate relationships with the Users table.
Orders have an owns/owned-by relationship to Users.
Users(1) -- owns -- (*)Orders
One User can own many Orders. One Order is owned by only one User
Then there is a completely separate outsourced-to relationship between Orders and Users.
Orders(*) -- outsourced-to -- (1)Users
(Here I assume that an Order can only be outsourced to one other User. A User may have many Orders outsourced to them.)
The best way to represent this is to have the Orders table have a 'owner' foreign key column into the Users table and another 'outsourced_to' foreign key column also to the Users table.
What columns of Orders the outsourced user can edit will be controlled by the code and not by the dB.
A separate outsourced table will be needed only if Orders can be outsourced to multiple Users at the same time.
How about having a user_id and outsourced_to field on the order table?
Sounds good.
Also, think about a kind of de-normalization, like moving fields, which editable by "outsorced-to" user to separate table.
I have a pretty simple shop-system. I'm working with CakePHP. Actually I wouldn't call it shop, it's rather a basic form where you can type in your data and which items in which color you want and that's it.
There is one buying-form which is "open to the public" and then there are buying-forms which are password secured.
The latter ones have a selection of the items (or selection of colors) which you get on the public site, but have discounts.
I want to save the orders in a database. I have a table orders and ordered_products. That's working fine.
It works pretty good, but only because I made something not very good: Since there are just a few products I just wrote an array in the controller with the names, prices and stuff... the discounts or selection of products I handled by just overwriting the products-property.
Well, putting data in the controller is not really the idea behind the MVC-Structure, so I was thinking about who to handle the products, the selection of products for the different password-secured buying forms and the discounts with models.
My idea was, to create the following tables:
products (id, name, price,...) -hasAndBelongsToMany Color
colors (id, name)
products_colors (product_id, color_id)
Now to set in which "closed-area", which products in which color and with which special price can be ordered I thought of the following tables (the actual table and field names are of course not wise chosen, but just for the idea):
product_selections (id, closed-area_name, product_id, special_price) hasAndBelongsToMany Color
product_selections_colors (product_selection_id, color_id)
When I'm creating the public buying form I would just use the top three tables. but building the "closed-area" I would use the bottom two, selecting the product_ids and special_prices from product_selection as well as the different colors over the product_selections_colors-table for the according "closed-area" (i dont know a better name for that right now...). with the product_id i would get the other information about the product from the table products and create the buying form with this data.
I want to have it all in a database, because then I can better work with the orders (creating receipts, deliverynotes etc.).
I would like to know what you think about that, because I have the feeling that I'm going totally in the wrong direction, since it feel way to complicated for such a simple thing...
I hope you can help me.
Based on your description, I would recommend doing it this way:
Have a users table with a field for "group_id". This allows you to have multiple users with login privileges that all can view the same options or colors based on their grouping.
In the case of a general (non-logged in) user, the assign the group_id to default to 0.
Next, ditch the product_selections and product_selections_colors tables.
You don't want to have to repeat products across tables.
Simply add a new table that pairs which product ids can be purchased by which group_ids. (HABTM relationship in cake)
You will obviously need to tweak this general setup to work specifically for your needs.
I'm developing a relational system, that involves the following entities:
Enquiry
Quote
Supplier
Town
Vehicle
Enquiry is the main model for the system and contains foreign keys for all the other entities.
Now what I'm concerned of is for example if the client goes and deletes a Town - the Enquiry record has a reference to the town id and would therefore break the system. Similarly if the client goes and deletes a Vehicle then Supplier records would break.
So what is the best way to handle deletions of relational records? Should we even offer the facility to delete records (perhaps have a enabled/disabled boolean switch instead?).
Similarly when renaming records how can we preserve original data for older records (for example if the client decided to rename Vehicle "Bus" to "Minibus").
If you want to handle this at the database level, Foreign Key constraints with Cascading Updates and Deletes is what you are looking for. For handling this within your application, use an ORM, like Doctrine.
what is the best way to handle deletions of relational records?
Only allow deletions of orphaned records? If I delete records from ENQUIRY that relate to a specific Vehicle, then someone should be able to remove that vehicle. But not before the child references have been dealt with... Pretty easy to handle using NOT EXISTS:
DELETE FROM VEHICLES
WHERE NOT EXISTS(SELECT NULL
FROM ENQUIRY e
WHERE e.vehicle_id = VEHICLES.vehicle_id)
Similarly when renaming records how can we preserve original data for older records (for example if the client decided to rename Vehicle "Bus" to "Minibus").
This is why you make the name/description separate from the primary key for using as a foreign key. If the VEHICLES table has two columns--vehicle_id and vehicle_description--then the description can change without referential integrity impact because you define the foreign key on the vehicle_id column.
There are several issues you have raised with this post. First, it may be beneficial to allow users with low permissions to soft-delete a record by toggling a isLive column as you indicated with a bit value. Secondly, you might benefit from the creation of a shadow table that will be used to record CRUD operations performed by the user. Through this, you will be able to record WHO made the change, WHAT type of change (Create/Update/Delete), WHERE the change was made (Table A, Column 1). Thirdly, you will want to handle the deletion of values bound by a foreign key carefully. You must delete all related connections prior to deleting from the source table. So you would delete the record in Enquiry before deleting the record in Town. Hope this helps..
This is a common problem. The user wants to delete 'Bus' because they don't use it any longer and don't want to see it on the Enquiry form. But you need the record because it's tied to five hundred older Enquiries.
Add an enabled/disabled or active/inactive flag to the record. Allow the user to disable records when they want. (Also allow them to reenable the records when they realize they were wrong.) Don't show disabled records on the Enquiry form, but keep them in the database to be able to show older data properly.
If you like, you can also allow deletion (actual removal from the database) if there is no Enquiry tied to the record. I personally don't show a delete button unless I'm sure a record can be deleted because I find users get frustrated if they can click the delete button but then are told they can't delete. So I check whether the record can be deleted before giving the option.
The problem of a user editing a record and changing the value from 'Bus' to 'Minibus' or from 'ACME Wallpaper, Inc.' to 'XYZ Catering' is one you have to live with. User education and making it easy to add new records is the only real way to handle it. Users have to be taught that ADDING and EDITING are different. Sometimes they have to be reminded with help-text on forms, warning messages, etc. I'm unaware of anything you can do programmatically that can accurately distinguish between a correction to a field, and a total change to the field.