I'm a complete beginner to SQL. I currently have "coders block" and need help pushing forward.
I am unsure how I should structure my database. I've included an image to hopefully give you a better picture of what I am trying to achieve. Please take a look at it
There will be multiple shops which contain multiple items. Each item will have a buying price and a selling price. An item may be used by multiple shops, and may have a different buying/selling price from other shops. My goal in creating this database is to be able to query an item and determine which shop(s) are buying or selling it at the lowest price.
EDIT:
My idea is to create three tables: Items, Stores, and ItemsStores.
Stores will have columns ID, Name
Items will have columns ID, Name
ItemsStores will have columns Store, Item, Buy Price, Sell Price.
I feel creating a column for just an ID and a name may be redundant. Am I wrong? Is there a better way to do this?
I've read a few articles and even watched videos on the basics of structuring databases, but for some reason it's just not clicking with me. Any help on what my tables / columns should look like would be greatly appreciated.
When you start designing a database, you need to think of the question by highlighting the objects that needs a table. The more the merrier (surprise surprise).
So this is how I would write down the problem:
There will be multiple shops which contain multiple items. Each item will have a buying price and a selling price. An item may be used by multiple shops, and may have a different buying/selling price from other shops. My goal in creating this database is to be able to query an item and determine which shop(s) are buying or selling it at the lowest price.
multiple is highlighted because that means a many to many relationship
obviously you need to decide (that's the tricky part) where you want the price to be: is price an attribute of item? or of an item in a shop?
Once your head stops spinning and you figure that one out you'll be in a much better position.
Related
I'm aware that someone will see this and say "I'm sure there's already an answer to "how do I make a subtable", so this question is repetitive." Well, no answers seem to be relevant to THIS situation. Here goes:
I own a car business. I want to make a rolling list of costs associated with each car, to eventually be summed into "totalCosts".
I have table
ASSETS
stock#,
make,
model,
purchase price,
totalCosts
and table
COSTS
description,
cost (in $)
so I want the COSTS table to contain several costs like:
purchase price $2,000
paint $50
new tires $200
I can figure out how to sum the costs, but mainly I need to know how do I make the COSTS table to exist for each car or stock#. So each stock# would have its list of COSTS, which I would sum and insert into total costs.
The only solution I see now is to make a costs table that contains every cost with a stock # on the same line, but I would like to have a separate costs table for each stock #
This is really the most basic related table you can make – quite much applies to near any database system.
You cost table will have
Id - pk id (all tables should have this PK)
Asset ID - standard long number column used to relate back to the assets table.
Item (description of the cost (paint, tires, seat repair, etc. etc. etc.)
Cost (the amount of the given item)
So you build a main form that is based on the assets, and then build a sub form that likely best setup of as a “repeating rows” or so called multiple items form (of which you drop into your main form, and thus the “costs” form becomes a sub-form of the assets.
So in effect, you attach each row of cost to a given single assets record. And access will “set” the Asset ID column for you automatic if you drop in the costs form as a sub form into the assets form.
The form will thus look something like this form:
In above, (a access application and a basic form I built in Access) I actually have “two” columns in which to select the “item” or “cost” type. I have sunglasses, but on the next row I could add tires, then paint, then whoever I want. Over time, you can add any kind of “new” cost item without having to create a new table or change the database structure.
If your design requires a “change” in the table structure for each new “thing” you enter, then you have the wrong design. Can you imagine an accounting package that you have to “stop” all the time and modify the software?
And then the real mess comes when you attempt to build a report. Once again, reports only work on pre-defined tables – you can “switch” tables on the fly for a report.
So any concept you have in regards to spreadsheets etc. must be tossed out of your mind. Computer information systems SIMPLY DO NOT WORK THAT WAY AND CANNOT WORK THAT WAY!
So keep in mind that Relational databases are NOT spreadsheets, and you don’t and CAN NOT adopt designs that require structure changes on the fly. Forms, reports, a query, and even computer code cannot function on tables that change for each record you enter – you MUST adopt a data model that reflects your current needs. That data model if done right can THEN be used for very complex accounting systems, ERP systems, or even a web store front that has 1000’s or even millions of different products. Such data models are designed first, and then the forms and user interface, the reports etc. are THEN created.
The same even goes for job costing. You might have liquids, labor costs, wall paper used in feet, paint used in gallons, and tiles used in meters. So just like an invoice system, job costing systems can handle “different” kinds of costs, and no table changes are required.
In above, we have an invoice like setup, and we can add as many things we want to a tour booking. (Tickets, jackets, books, skates, tires, paint, seats, and windows - whatever we want – we simply add a new row for whatever we need.
Think of any kind of “invoice” software you used – you can add as many items you want to that invoice.
A relational database does NOT support a whole new table for each new “cost” that you want to build – databases simple do not work this way. So you only (so far) really need a master table of the asset, and then the child table of “costs”.
You can’t create a whole new “cost” table for each asset as the built in tools in near any and all databases don’t support nor work with creating a new table for each new set of data you create.
And for ease of data entry, you could build a table of cost Items, so the user does not have to type in paint, tires etc., but choose that item from a drop down combo box.
So EVERY single example on the internet, every book, and every article that explains how to relate a master table to a child table is in fact 100% relevant and is how you HAVE to approach this problem.
Relational databases do not support creating of a whole new table for “one” new set of data, because such an approach cannot be used in reports nor does the query language support such a design.
I have 3 tables:
Customers Table
Transactions Table
Delivery Table
In the customers tables every customer has a delivery rate (based on their location).
What I am trying to accomplish is when I add an order to the transactions table, if the checkbox is checked it should automatically add new a record in the Delivery Table filling out the customerID, & Date, based on current transaction name & date & DeliveryCharge based on the delivery rate this customer has.
How do I accomplish that? Please Help!
NOTE: I am not sure if by making a separate Delivery Table like I did is the way to go in general. If you have a different/better way to add optional shipping charge with query, etc. Please let me know.
First, a discussion about your table structure. Your Transactions table is using CustomerName instead of CustomerID. That will give you problems. In this case, it doesn't appear there is much difference between the Transactions and Delivery tables. Therefore I would recommend combining them. The only reason I would not is if you intend to split transactions into multiple deliveries. Finally, your Transactions table should not include the total price. Make another table like TransactionDetails that tracks the price of each product purchased and associates it with a single transaction number.
As for the rest of your question, you have a pretty broad approach question so I will give you a broad answer. One way you can do this is to use a form. VBA is absolutely capable of running the SQL queries you need, storing the values in variables, and then reusing them in an INSERT query.
I would recommend implementing it with a form that gets your user input and has a button to click that runs the required queries. Without more specific coding, I'm afraid you're not going to get much more feedback.
Here's a fairly straightforward many-to-many mapping of Nerf gun toys to the price range that they fall under. The Zombie Strike and Elite Retaliator are pricey, while both the Jolt Blaster and Elite Triad are cheaper (in the $5.00-$9.99) range.
So far so good. But what happens when I want to start tracking the prices of other items? These other items have different columns, but still need PRICE_RANGES mappings. So I can potentially still use the PRICE_RANGES table, but I need other tables for the other items.
Let's add board games. How should I model this new table, and others like it?
Should I add multiple many-to-many tables, one for each new type of item I'm tracking?
Or should I denormalize PRICE_RANGES, get rid of the mapping tables altogether, and just duplicate PRICE_RANGES tables for every item type?
The second solution has the advantage of being much similar, but at the cost of duplicating all the ranges in PRICE_RANGES. (and there may be many thousands of PRICE_RANGES, depending on how small the increments are). Is that denormalization still a valid solution?
Or maybe there's a third way that's considered better than these two?
Thanks for the help!
Why do you have a "price ranges" table at all? That would make it highly restrictive. Unless there is a really compelling reason I am missing... Here is what I would consider.
Drop the mapping tables
Drop the price ranges tables
Add a min price and max price to each table you want to track price ranges. If there is no range, you can either allow max price to be null, or make both be the same price. Then you can just query the tables to find items within whatever range you want.
Another thought I would consider... how many different types of products are you trying to track? If you are going to make a separate table for every single kind of product... that will quickly become unmanageable if you expect to have hundreds or thousands of items. Consider having a "Product" table that has columns that share attributes, such as price, across all the products. It would have a ProductType column that either references a lookup table or just puts the types directly in the column. Then have either a separate key/value table to cover other random things like bolt capacity. Or even consider putting that in an xml/json/blob column to cover all the extra bits of info.
We are currently developing a online advert site for people to buy and sell (similar to gumtree) difference being this will be used for employees who work for the company, it wont be reachable from people outside the company.
Now we have 15 categories which have sub categories and those sub categories have child categories.
We have a main table called Adverts which consists on ItemId, Title, SubTitle, Description, CreatedBy, BroughtBy, StartDate, EndDate and ParentCategoryId, SubCategoryId and ChildCategoryId etc
Now instead of having one massive tables which consists of all the details for the item they are selling we were going to create separate table(s) per category for the details of the item.
So we would have Advert.Vehicle_Spec which would have all the details about a car they were selling i.e
ItemId (which will be a FK to the main Advert table), Make, Model, Colour, Mot, Tax etc
That way when we query the main table Advert we can join onto the relevant Spec table which in a way would keep the tables clean and tidy now my question would be to you is this a good approach? Would there be any performance issues with this approach? I will create all the relevant FK where needed to help with queries etc.
I did ask this question on an SQL Server forum and one individual suggested using XML - each category gets an XML schema and the XML tags and values are held in a single field but the data varies depending on what type of item is being sold. This requires more setup but probably has the best overall balance of performance and flexibility, I Personally have never worked with XML within SQL so I can't comment on this being a good approach or not?
Each category can have many different status's we have a variety of tables already which hold the description of each status, the queries we will be performing will vary from select, delete, insert, update some queries will have multiple joins on to the Status/User table, we will also be implementing a "Suggested" form which will show all records suggested for a user depending on what they search for.
Is XML right for this in regards to flexibility and performance?
XML seems to be a good approach for this, you can directly write stored procedures that queries the specific categories you want and organize them into tables and display them. You will then possibly want to use something like XSLT to extract the XML data and display them in a table.
I want to store some product data in my database. At first I thought having a product table and product info table but not sure if I should just merge it all into one table.
Example
Coke - 355 ml
Product.Name = Coke
ProductInfo.Size = 355
ProductInfo.UnitType = ml
Coke - 1 Liter
Product.Name = Coke (would not be duplicated...just for illustration purposes)
ProductInfo.Size = 1
ProductInfo.UnitType = L
if I did this of then of course I would not be duplicating the "Name" twice. My plan then was I could find all sizes of the same product very easily as all I would have to do is look at the many side of the relationship for any given item.
Here is the problem though, all the data will be user driven and entered. Someone might write "Coke a Cola" instead of "Coke" and now that would be treated as 2 different products as when I go to look if a product has been entered called "Coke a Cola" but it won't know to check for "Coke" as well.
This leads me to having to do like partial matches to maybe try to find it but what happens if someone has some generic brand what would be "Cola" and that would get matched as well.
This gets me to think maybe there is no point to keep the data separate as to me it seems like a good chance everything will end up to be it's own product anyways.
There's merit in both approaches. Keeping them separate, the table you're calling "Product", I'd call "Brand" instead, and "ProductInfo" is your actual "Product" table, containing the information about the actual sellable item of that brand (a 12oz can or liter bottle of Coke).
Alternately, you could further normalize it into Brand, Product (here being Coke Classic as maybe opposed to Diet Coke or Caffeine Free Coke) and UnitSize (can or bottle; these would apply not only to Coke Classic, but Diet Coke, Pepsi or Dr Pepper).
If you denormalize this this data, you aren't duplicating much on the naming side of things, but you are duplicating quite a bit of unit of measure data. The question is whether it's more useful to ensure consistent branding of your product records (denormalizing means you'll need some other means to ensure your products have the same brand), or to avoid the joins between the two tables (there is a cost to joining, though it's typically small if you can join between indexed fields).
The only compelling reason to make a Header-Detail arrangement, with two tables, would be if Coke has attributes that are the same no matter the packaging. Right now, I don't see any attributes like that; so one table covers it. You might say, "But I might think of something in the future like that." That may be a reason to make two tables; but (unlike many kinds of change to a database schema) this may not be too difficult to break into two tables later, when you know there is a need.
I see the point about mistakes that result in nearly-matching records. I think that's not a consideration at this table level and you should address it as a part of record editing.
The best way to do this would be to have your product or item table in its own table with fields like ID, SKU number, short description, active, and so on… Then you have your “many” table hold the other item attributes which can be joined on ID; a one to many relationship. And to solve the user input issue, you have a combo box which is tied to inventory choices or item choices. This way you enforce data integrity. Well, that is how I have done it.
This post has some helpful links on DB design