Creating a 'basket' for a stock management program? - database

When you buy things online, you add them to your basket and when you've done adding things to your basket, you create an order. Essentially, I am trying to think of the best way to allow multiple items to be put into one order. This is more a case of not knowing how to store the data in a database in Access. I can't figure out what the fields should be called. My current attempt is this:
tblOrders
OrderID (Primary Key)
CustomerID (Foreign Key)
OrderDetailsID
tblOrderDetails
OrderDetailsID
PartID (Foreign Key)
Quantity
This is an image of the first table with example data and this is an example of the second table. It's very likely that I've missed something blindingly obvious.
Thankyou in advance.

I'd structure it like this:
OrderHeader
ID (Primary Key)
CustomerID (Foreign Key)
OrderDetail
ID (Primary Key)
OrderHeaderID (Foreign Key)
PartID (Foreign Key)
Quantity
Read up on Hungarian Notation as a naming convention, and consider dropping your tbl prefixes. This is just a preference you may choose to ignore.
OrderDetailID on the OrderHeader won't work because you won't be able to produce the necessary 1:M relationship where an order can have multiple detail lines.
Use surrogate ID fields for your primary keys. They make working with JOIN a lot easier. If you want to enforce a condition that an order can only use a part once, then you should do so with a unique database constraint on columns OrderHeaderID and PartID.
Here's a sample query for your comment...
SELECT H.ID OrderID, D.PartID, D.Quantity
FROM OrderHeader AS H INNER JOIN
OrderDetail AS D ON H.ID = D.OrderHeaderID
WHERE H.ID = 1234;

Related

How store order and products in a database?

I have an order with details such customer id, order date, order type etc...
The order then contains a list of products on that order
Do I create one table for the order and then another table for the products?
If so, should there then be foreign keys between the 2 tables?
Here's how I'd model it:
Customer can have many Orders; an Order belongs to one Customer.
An Item refers to one Product
An Order can have many Items; an Item belongs to one Order.
One-to-many foreign keys always belong in the "many" table and refer back to their "one" table.
If you have many to many relationships you need a JOIN table, which has two one-to-many foreign keys.
You current condition may works if the product is not belong to your store/source , you are getting products from different source and client order the product so you can maintain the order with the require details.
if the product came from your source/store then you must need the product and order
Your table structure should look like below. In your product table create a reference to order_id in order table by means of foriegn key. Thatway, each order will be associated
with one or more products and you can find out the same using a JOIN in your SELECT query.
Table: Order(order_id Primary key,customer id, order date, order type)
Table: Products(product_id primary key, order_id foriegn key,col1, col2);
Explanation:
A product may not be associated with a order at all time but a order must be associated with a product (Obhious reason, we can't have a blank order).

about indexes created on primary keys referenced as foreign keys in a different table (SQLite3)

Scenario for my database design is as follows: people visit matchmakers who network with each other and propose matches. For example, person A visits matchmaker X, and person B visits matchmaker Y, where A not equals B and no constraint on X, Y i.e. they can be the same or different.
create table matchmaker ( id TEXT primary key, address TEXT );
create table people ( id TEXT primary key, name TEXT, gender TEXT, matchmaker_id TEXT,
foreign key(matchmaker_id) references matchmaker(id));
create table married_couples ( id1 TEXT, id2 TEXT,
foreign key (id1) references people(id),
foreign key (id2) reference people(id));
Then, for faster database access:
create index matchmaker_index on matchmaker(id);
create index people_index on people(id);
My question is based on the following query to generate tuples of matchmaker pairs with people they've paired.
select a.id, b.id, e.id1, e.id2
from matchmaker as a, matchmaker as b,
people as c, people as d,
married_couples as e
where e.id1 = c.id and c.id = a.id and
e.id2 = d.id and d.id = b.id;
For the query above, will the two matchmaker_index and people_index suffice or,
is there a need for two more (other) indexes as below?
create index matchmaker_people_index on people(id, matchmaker_id);
create index married_couples_index on married_couples(id1, id2);
additional info:
1) matchmaker has 20074 unique entries;
2) people has 20494819 unique entries;
3) married_couples ?? (i don't have this information yet, but it's going to be big)
Also, it's possible that married_couples will have duplicate entries. So,
after creating the relevant indexes, will run query to delete duplicates as below:
delete from married_couples
where rowid not in ( select min(rowid)
from married_couples
group by id1, id2);
SQLite generates indexes automatically for columns declared primary key or unique. FAQ, see question 7. So these two indexes
create index matchmaker_index on matchmaker(id);
create index people_index on people(id);
are duplicates. Drop them.
This index
create index matchmaker_people_index on people(id, matchmaker_id);
might help.
Also, it's possible that married_couples will have duplicate entries.
Remove that possibility. Add a primary key and a CHECK constraint.
create table married_couples (
id1 TEXT, id2 TEXT,
foreign key (id1) references people(id),
foreign key (id2) references people(id),
primary key (id1, id2),
check (id1 < id2)
);
The primary key provides an index, too.
When you're talking about marriages, a marriage between Mike and Mindy is a duplicate of a marriage between Mindy and Mike. The CHECK constraint prevents that kind of subtle duplication. It also prevents people from marrying themselves.
I'm not sure what you might want to do about the woman who married the Eiffel Tower.
You can simplify the original query quite a lot. Learning ANSI joins is a good idea.
select id1, id2, c.matchmaker_id m_id1, d.matchmaker_id m_id2
from married_couples a
inner join people c
on c.id = a.id1
inner join people d
on d.id = a.id1;

Oracle primary key affecting indexes

I had an index working really nicely last night, low I/O all that good stuff. Now this morning I added a primary key to the table and the performance has dropped and the optimizer ignores the index even with hints.. Any advice? Thankyou
Schema structure..
Product
ID PK
Name
Price
Order_Line
Order_ID FK
Product_ID FK
Qty
Orders
ID PK
O_Date date
CustID
Query...
SELECT SUM(OL.QTY) FROM PRODUCT P,ORDERS O, ORDER_LINE OL
WHERE
P.NAME = 'APRICOT JAM'
AND
P.ID = OL.PRODUCT_ID
AND
O.O_DATE = '03-MAR-2014'
AND
OL.ORDER_ID= O.ID
;
The index which it isn't using is a composite index on product which is (name,ID), instead its using products primary key to do an index range scan Thanks!
Product Table
ID PK
Name INDEX01
Price
I would structure your table this way.
Your query is going to range scan because it is going to scan the table for the P.NAME = 'APRICOT JAM' clause in your query.

SQL server constraint - unique key or index?

I have a table that contains all products. There are 3 distinct types of products so these have their own tables, lets say ProductType1, ProductType2, ProductType3.
There is a 1-1 relationship between Products and ProductType(n) on ProductId, but to further constraint the child tables there is an additional relationship using a ProductId, ProductTypeId in Products, and a ProductId, ComputedProductTypeId in each of the other tables.
This ensures that a product can only be added to a single matching ProductType table.
The question is this. As there is already a relationship between the 2 tables on ProductId, rather than using an index for the FK, can I get away with a unique key to constrain the relationship, or will this cause performance issues?
Products
PK ProductId
FK ProductId, ProductTypeId
^
*Add an index for this or unique key constraint?*
ProductType(n)
PK ProductId
FK ProductID, ComputedProductTypeId (fixed int)
Creating an index will be better approach.
If you want to delete entries from your master table, SQL server looks for FK relations if any exists. So Creating Index on your composite key (which includes FK) will speed up the process.

Linking ID from one table to data in another table

I have an assignment where I am to create two tables within a database. The tables looks like this;
ContactPerson (ID, Forename, Surname, Email, PhoneNumber)
Company (ID, CompanyName)
Now my problem is that I have to link a ContactPerson to a specific company, but I can't have them in the same table.
I understand that I can use the join statement to show both tables in one query but I need the database to know which person is linked to which company when I implement this databse into my asp.net project.
How do I do this?
You did say "specific" company so I'm assuming you have one company per person.
Put a column in the user table called CompanyID...
ALTER TABLE ContactPerson
ADD CompanyID int
(assuming your ids are ints)
and then create the following foreign key:
ALTER TABLE [dbo].ContactPerson
ADD CONSTRAINT [FK_ContactPerson_Company]
FOREIGN KEY (CompanyID)
REFERENCES Company (ID)
Shark is correct if you want a many to many relationship.
To get all people in a company:
SELECT
*
FROM
ContactPerson
WHERE
CompanyID = x
You don't HAVE to apply the foreign key constraint, but if you don't, you can accidentally put invalid data in. All a "Constraint" does is enforce a rule for you, in other words "making sure sql knows which people are in which company" as your question suggests you need to do.
The above query would work without the Foreign key constraint, but then your database doesn't "know" about the relationship.
..and if I try and insert a person with a companyid that doesn't exist, SQL will throw an error (this is a good thing).
Since this is a one-to-many relationship, I would typically put that data into the ContactPerson table. But because you explicitly say you cannot, then just create a join table:
create table ContactPersonCompany
(
ContactPersonID int not null foreign key references ContactPerson(ID),
CompanyID int not null foreign key references Company(ID)
)
Now you have a relationship between ContactPerson and Company.
Example: select all people from a particular company
select
cp.Surname,
cp.Forename
from ContactPerson cp
inner join ContactPersonCompany cpc
on cp.ID = cpc.ContactPersonID
inner join Company c
on cpc.CompanyID = c.ID
where c.CompanyName = 'Some Company'

Resources