I need a little help designing a database that a bar would use for drinks. My app handles drink orders in 2 ways: A customer can order drinks and pay right away, or they can start a tab. This is my table relationship so far:
Table Order: Table Tabs:
------------ ------------
[PK] OrderId - 1 [PK] TabId
ItemName / TabName
QtyOrdered / Total
TabId *- PaymentType
Archive
Its setup so 1 tab can have many drinks on it. Thats great for tabs, but customers can choose not to setup a tab. My question is, how can i modify these two tables to support that? Or do I have to create a new table?
Thanks in advance.
Your "item" is the order line-item.
"My brother and I will each have a Guiness and his wife would like a gin-and-tonic."
There are three (EDIT: items, but two) line-items on that order. To identify them as part of the same order [if you should need to do so], you would need two tables:
the OrderHeader
(orderheaderid, orderdatetime, customerid)
and
the OrderDetail
(id, orderheaderid, drinkid, howmany, extendedprice, paymentamountapplied).
If you do not need to identify the drinks as belonging to the same order, you could abandon the two-table structure, but then you could have only one kind of drink per order.
ORDER
orderid, orderdatetime, customerid, drinkid, howmany, extendedprice, paymentapplied.
Extended price is howmany * the drink's price at time of the order. You store this value in your order table so you can change the price of the drink in the DRINKS table without affecting the tab amount owed (in case the tab lifetime is longer than a day -- i.e. customers can run a monthly or quarterly tab).
HowMany can default to 1. The amount owed on a drink line-item is (extendedprice - paymentamountapplied). PaymentAmountApplied defaults to 0 (i.e. default is to run a tab).
If you do not need to track the kind of drink being ordered (i.e. you don't care to use your database to discover that on Tuesday nights you sell a lot more gins-and-tonic than Guinesses, for some reason):
ORDER
orderid, orderdatetime, customerid, ordertotal, paymentapplied.
Your barkeep would simply enter the total amount of the order, calculated outside your system, without reference to a DRINKS table in the database -- maybe the barkeep would look at a chalkboard on the wall.
You need a CUSTOMERS table, a DRINKS table, an ORDERSHEADER table, an ORDERDETAIL table (each drink on the tab is a line-item). You could/should have a separate PAYMENTS table. And you would allocate payments to the line-items of the ORDERDETAIL (your tab). The "tab" is the set of all line-items on the order(s) that have no payment applied to them.
Related
I have analyzed my as below and I have two point I am confused about
1- currently when I insert an items within orders I give order_ID as a PK
so each item within the order as its own PK... and same customer_id (FK) for all Item within the order so ... in that case the invoice number is same as the customer_ID
Is that what should think goes on or there is something wrong with this work flow ?
2-in some cases I don't need to record the customer information I just want to
insert the orders without their customer info.. I don't have clear idea about how think should happen :S
3- IF I want to apply a discount on some customer orders where the discount should I allow user to able to apply on the item per orders level ?
or on the whole order ? and where the discount column should be stored
1 - This design seems fine for the problem. You are stating that for every product ordered, this is the customer line. You can pick the ID, name, tax/fiscal number, address, etc.
2 - If you don't need any kind of customer information, make the customer_id on the Orders table accept NULL. It is the cleanest way to do it.
If for some reason NULLs are not an option or you want to keep on the database some basic anonymous customer data, you can create a line on customers for anonymous users (Ex.: ID: 1 / Name: ANONYMOUS ...) and place that ID on the order line.
3 - Placing the discount per product ordered might be the better idea.
If you want to apply a discount for the complete order, you just need to place that discount on every single order line.
If you want to apply a discount for a single product, you just need to place that discount on that product line.
If you want to apply a discount for a single product with a limited ammount of quantity (Ex.: Discount of 50% but limited to 1 purchase), and the customers buys more than that limit, you just need to place 2 orders for the same product. One with the discount and max quantity and the other without discount and the rest of the quantity.
Placing this on the order level wouldn't work for single product discounts.
This were answers to your questions. I would also question your design in points like:
If the customer changes address, is your order supposed to change too? If not, you should use the normal approach for orders, which is to have a order header table, with fixed information, like the address and the foreign key to the customer, and a order line table, like your orders line, but with a foreign key to the order header. That also avoids repetition.
Are you expecting up to 2 phone numbers? If you do, the design is ok. If you don't know how many phone numbers to expect, maybe a table with phone numbers, with foreign keys to the customer might be a better approach.
I am creating a sports collection database of different sports and i am confused of some sort on what tables and primary keys/foreign key combo to use the requirement is as follows:
Should be in a 3rd Normal Form or at least in 3NF.
Here is the Full Description on what I want to do:
Design a database for a sports collection of cards.
You only purchase cards with current market value( at the time of purchase) that are at least $100.00. Your collection about 1000 cards
You collect all kinds of sports cards, from football, basketball, hockey and etc
These cards you collect are produced by different vendors such as ?Topps, Upper Deck, Leaf and Panini.
The collection spans many years of collection, some cards even date back to early 1900s, but there are cards made even before this
The condition of your cards vary too and are grade according to the 10-point PSA grading standards. (Grading table)
Everytime you purchase a card, you must know the date of purchase, cost of purchase, the market value of that purchase, whom you purchased it from, sport, the individual on the cards, card number and etc.
After completion of purchase, you send the card out for grading about a week later, you want to be able to keep track on when the card was sent out for grading, status of the grading, graded assigned to the card , when it was return by the grading company and receipt of the returned card. for tax purposes, you also want to know the fee paid for the grading service (grade table)
you do buy and sell cards, so you also want to know how much you sold the card for for, when it was sold, to whom it was sold, shipping fee if applicable and any relevant data pertinent to sale transaction. You are free to include any additional data that you believe is important to the table.
Here is my current database so far... I feel like i am missing something and I did not follow the requirements properly
It looks like a pretty good start. I have the following observations about your tables/structure:
CardSellers: should only store info about the CardSeller; the only values it should have are SellerID and SellerName
Vendor: should not have CardId
Grade: SellerID doesn't belong here
Card: looks good
CardBuyers should not have DateOfPurchase or CostOfCard or Shipping Fee; those three members belong in CardTransaction. In fact, "DateOfPurchase" should be "DateOfTransaction"
Also, since the Vendor table should only store Vendor data, and the Card table should only store card data, you also need a M2M (many-to-many) table to connect the two; this should have three members: ID (PK), CardId (FK), and VendorId (FK)
UPDATE
Remember two things about table design:
(0) A table should only contain data about the object its named for and only references to other tables (via a FK - see below)
(1) DRY (Don't Repeat Yourself - IOW, don't store the same data in multiple places; instead, store a link to it, where needed, via FK (Foreign Key) fields referencing PK (Primary Key) fields).
As far as the actual design of the tables, this makes sense to me:
CARDS
-----
CardId (PK)
VendorId (FK)
CardFirstName
CardLastName
CardType
CardYear
MarketValue
Rarity
CollectionNumber
COLLECTORS (Buyers and/or Sellers; no need to have separate tables for them)
---------
CollectorId (PK)
CollectorName
CollectorAddress
TRANSACTIONS
------------
TransId (PK)
CardId (FK)
BuyerId (FK) <= CollectorId in the Collectors table
SellerId (FK) <= CollectorId in the Collectors table
TransactionDate
Price (if it may differ from CARDS.MarketValue)
GRADE
-----
GradeId (PK)
CardId (FK)
Points
AssignedGrade
Qualifiers
Status
CardFee
GradedDate
ReturnedDate
VENDORSLU ("LU" stands for "Lookup")
---------
VendorId (PK)
VendorName
CARDTYPESLU
-----------
CardTypeID (PK)
CardTypeDescription
RARITYLU
-----------
RarityID (PK)
RarityDescription
You may find there are other fields you need to add, too, but that should be close. You might even want additional lookup tables, such as for "Qualifiers" and "Status" in the GradeTable.
You might also want a SPORTSLU table, and then add a SportId FK to the CARDS table (where if SportId == 1, it's a football card, if it's 2, it's a basketball card, &c).
Note, though, that as prevalent and historically significant as Relational Databases are, there is another animal called "Non-SQL" databases (such as MongoDB) which are more free-form/loosey-goosey/I'm okay-you're okay/anarchistic, which allow you to have records, or "documents" that can omit or add whatever members it wants on the fly. Relational Databases can be compared to Classical music (Bach, Mozart, &c) whereas Non-SQL are more like Jazz (free-flowing, improvisational).
And BTW, why no mention of Tiddlywinks? Football, Baseball, etc., are fine, but no Tiddlywinks (or Bocci Ball, for that matter)?!?
I am designing an e-commerce website that has the following scenario:
A customer can purchase items and create an order.
The order may have unknown fee that will be added after the customer
pays the total amount of the items. That is, the customer pays
certain amount first. The order adds some fee and changes the total.
And the customer pays again for the difference. But the two (or
more) payments are associated with the same order.
(Optional) The customer can submit a single payment for multiple
orders.
Currently, I have an Order table and each order may consist of multiple OrderLineItems (simplified schema):
Order
=====
customer
line_items
total
status
OrderLineItem
=============
price
quantity
order
product
A payment is associated with an order (simplified schema):
Payment
=======
order
payment_account
total
result
It seems to be very hard to support the multiple payments for a single order scenario in the current implementation. I reckon that I have to introduce immutable invoices in the system, and the payment should be associated with an invoice instead of an order. However, I would need some help with the order/invoice/payment modeling for the above scenario. Some specific questions I have:
An order and an invoice look very similar to me (e.g. both have
items and totals). What is the major difference in typical
e-commerce systems?
How should I model invoices for my scenario? Should I have
OrderLineItems for an Order AND InvoiceLineItems for an Invoice?
Some preliminary thoughts: I will have multiple invoices associated
with a certain order. Whenever the order changes the total, I have
to somehow calculate the difference and send a new/immutable invoice
to the customer. Then, the customer can pay and the payment will be
associated with the invoice.
Would love to hear some advice. Much appreciated. Thanks!
There are a lot of questions here, I'll try to address as many as I can. A lot of the issues are the business model rather than the data model.
Firstly, you are right that you need an immutable invoice. Once an invoice is created you cannot alter it, the standard way of handling a change in invoice is to issue a credit note and a new invoice.
Think about the relations between the tables: the Order does not need to hold the lineItems as these are referenced the other way, i.e.
Order
=====
orderId
customerId
status
OrderLineItem
=============
orderLineItemId
orderId
product
price
quantity
So to view the order you join the tables on orderId. There's also no need to store the total as that is calculated from the join.
Try not to duplicate your data: your invoice will reference orderLineItems, but not necessarily the same ones in the order. For example, the customer orders an A and a B, but B is out of stock. You ship A and create an invoice that references orderLineItemId for A. So your invoice tables might look like:
invoice
=======
invoiceId
status
invoiceLineItem
===============
invoiceId
orderLineItemId
quantity
In other words there's no need to have the details of the item. You may be wondering why you don't just add an invoiceId to the orderLineItem table - the reason is the customer might order 10 of item A, but you only ship 8 of them, the other two will go on a subsequent invoice.
Payments are not made against orders, they are against invoices. So your payments table should reference the invoiceId.
Then you touch on reconciliation. If everything was perfect, the customer would make a payment against a particular invoice, even if a partial payment. In reality this is going to be your biggest headache. Suppose the customer has several outstanding invoices for amounts x, y and z. If they make a payment of p, which do you allocate it against? Perhaps in date order, so that if p>x the remainder is allocated against y. What if p=z? Perhaps the customer is intending to pay z now but is disputing y and has mislaid x? How you deal with these sorts of things is up to you, but I can say that most invoicing systems do it very badly indeed.
I am building a new business application for my personal business which has close to ~100 transactions of sale and purchase per day. I am thinking of having Separate tables to record the sale and purchase with another linked table for Items that were sold and a seperate linked table with items that were purchased.
Example:
**SaleTable**
InvoiceNo
TotalAmt
**SaleTableDetail**
LinkedInvNo
ProductID
Quantity
Amount
etc.,
would this design be better or would it be more efficient to have one transactiontable with a column stating sale or purchase?
-From an App/Database/Query/Reporting Perspective
An invoice is not the same as a sales order. An invoice is a request for payment. A sales order is an agreement to sell products to a party at a price on a date.
A sales order is almost exactly the same as a purchase order, except you are the customer, and a sales order line item can reference a purchase order line item. You can put them in separate tables, but you should probably use Table Inheritance (CTI, extending from an abstract Order). Putting them in the same table with a "type" column is called Single Table Inheritance and is nice and simple.
Don't store totals in your operational db. You can put them in your analytic db though (warehouse).
You are starting small, thats a quick way to do. But, I am sure, very shortly you will run into differences between sale and purchase transactions, some fields will describe only a sale and some fields that will be applicable only for purchases.
In due course, you may want to keep track of modifications or a modification audit. Then you start having multiple rows for the same transaction with fields indicating obsoletion or you have to move history records to another table.
Also, consider the code-style-overhead in all your queries, you got to mention the Transaction Type as sale or purchase for simple queries.
It would be better to design your database with a model that maps business reality closest. At the highest level, everything may abstract to a "transaction", with date, amount and some kind of tag to indicate amount is paid or received against what context. That shouldn't mean we can have a table with Tag, Date, Amount, PayOrReceive to handle all the diverse transactions.
I have problem with two parts of database diagram and I need your guidance:)
database has a lot of tables that one of them is about Employee ,the other is about Customer and ... ! I have problem with two tables (Product and OrderDetail) my Product table has 3 columns (ProductID,Name,Cost) and the Other table is OrderDetail that has these columns(OrderDetailID,Cost,Quantity) I have not created this database myself I have found it like a sample database in the internet but I have problem about these two Cost which is in OrderDetail and Product tables ,what is the difference between these Cost? they are the same or not?
thanks
EDITED: sorry all I had a mistake ,the ID for the ordeDetail table is the composite of primary key of Product table and Order table which is Product ID and OrderID and the OrdeDeatil table is a weak entity. SO
OrderDeatil((ProductID,OrderID),Cost,Quantity)
I suppost that the cost in the products table is the current price of the product. On the other hand, the cost in the order details table is the price that was paid for the product for that particular order.
Product prices can go up or down, or discounts might have been given for particular orders. The field in the order details table would store this information.
UPDATE: Further to your updated question, that makes sense. It implies that each order can only list the same product once. The order details table is storing how many items of that product were ordered (quantity) and I would say that cost is the price paid for one item. It could be the total (price * quantity) but that's not a common for such table structures.
Without knowing exactly what this database is meant to capture, I couldn't say for sure, but as a rough guess I would expect that the Product tables Cost column is the cost for a single unit of that product, and the OrderDetail tables Cost column is the cost for an order of some quantity of 'something' - most likely a certain quantity of a product. Note as an interesting aside that there is nothing linking the OrderDetail table to the Product table - if these two tables are meant to be linked you would normally expect a Foreign Key in the OrderDetail table linking it to the Product table. At the moment, there is no way to match OrderDetails to Products.