Separate tables for online and in-store purchases? - database

I'm developing a system for a retailer and I've hit a bit of a conundrum when it comes to deciding how to represent the orders in the database. The schema for my Order table so far is as follows:
Id - PK
AccountId - FK (Nullable)
ShippingAddressId - FK (Nullable)
BillingAddressId - FK (Nullable)
ShippingMethod - (Nullable)
Type - (Nullable)
Status
Date
SubTotal
Tax
Total
My problem is I'm not sure whether I should represent online purchases and in-store purcahses in separate tables or not. If I were to store them in the same table, all non-nullable fields would be the only ones applicable for in-store purchases.
Another design pattern that crossed my mind is something like this:
Online order table:
PurchaseId - PK, FK
AccountId - FK
ShippingAddressId - FK
BillingAddressId - FK
ShippingMethod
Type
Purchase table:
Id - PK
Status
Date
SubTotal
Tax
Total
And for in-store purchases, there would simply be no reference from the online orders table.
Thoughts?

I would make a second table for location, with a primary key and location information. That could be online as well. Then use a foriegn key in your main table. You would then just fill the fields require for the application you are doing(in store, or online). This would also allow For the business to grow to more locations just by simply adding it into the location table.

I'm going with the original design. Likely more maintainable and efficient as well.

Your second design is very close to an Entity Sub-typing pattern. If the primary key of your online order table was the foreign key to your purchase table then you would have entity sub-typing.
Your original design is a practical design for the physical implementation of your database because it is simple to use. Entity sub-typing would be the preferred design at the logical level because it clearly represents your rules about which predicates (columns) belong to which logical tables.
Some people would also use the entity sub-typing pattern for their physical model too because they have an aversion to nulls.

Related

Database - table contain only primary and foreign keys

Can a table contain only a primary key and 1 or more foreign keys? Or it will violate the normalization design?
For example:
PK: SKILL_NAME
FK: SKILL_ID
FK: EMPL_ID
Yes. This would be the typical structure, for instance, for an association/junction table that implements a n-m relationship between two entities.
That said, almost all tables I create also have:
createdAt -- insertion time for the record
createdBy -- who inserted the record
And sometimes:
createdOn -- the system/database where the record was created
Your example may not be a good one because i don't understand the scenario that skill_name is the PK, instead of skill_id.
What you mentioned is actually similar to EAV data model, i see some open source produce (magento) using it. But it's too normalized and need denormalized caching table for the performance.

Normalising image album database

Above is my normalised database structure for my app. I am going to store Users, and their favorited Images. Images might be alone (hosted on reddit) or in albums (hosted on imgur), and they always have a title.
Question is - is the database set up correctly? I have this feeling that i have something wrong with ImageAlbum and Image table relationship.
EDIT: This might work?
The main issue with the original design is that the intended relationship between a user and an image would not be possible, as the two tables are not connected.
As a general rule of thumb, if there's a 1-1 or a 1-many relationship between tables, you can rely on constraints. I.e. 1 customer can place many orders. You have a Customer table with a CustomerID PK column, and an Order table containing an OrderID PK column, and a Foreign Key constraint to the CustomerID column of the Customer table. That establishes the relationship, and ensures that you cannot place an order if you are not a customer.
An order typically consists of one or more products, and a product typically can be purchases in multiple orders. In cases like this, you cannot set up this relationship the same way. A common workaround for that is to do so using an intermediate table that establishes the many-to-many relationship.
So building on the earlier tables, we also have a Product table, with a ProductID column as a PK. To set up the relationship between Order and Product, you would then credit an OrderProduct table, with FKs pointing to the OrderID and ProductID in question (and probably also something indicating quantity of products for this particular order, and perhaps something like a FK to a Discount or campaign table, and whatnot).
So in your scenario, I would establish the relationship between Image and User using a similar approach, and simply adding a UserImage table to allow for the many-to-many relationship. You then also add an AlbumImage table to determine the many-to-many relationship between images and albums.
As indicated in the comments, there's no need to have an AlbumTitle table, really. It would naturally belong to the Album table. The ImageTitle would belong in the UserImage table, because every user can add their own title to an image.

How to identify a transaction table?

i have database that has master tables prefixed with mt_ and transactions tables prefixed with tr_ . But when i go through the database i started to wonder what is the actual definition of a transaction table and master table. To my understanding transaction table should have a composite primary key (primary key made from two or many PKs of other tables). But when i looked at the transaction tables in database, there are tables that have the composite key as mentioned previously also it has tables tagged as tr_ but have only one key tagged as PK and they also have PK keys that belongs to other tables but they weren't even tagged as FK...
So could any one here explain the difference between a master table and a transaction table and how to identify them in DB?
Updated
Here is an examtple of my db
tr_orders
OrderId int PK
CustomerId int Fk
OrderDate datetime etc
tr_reciept
RecieptId int PK
OrderId int **(but not FK)**
PaindAmount money
recieptDate datetime
Here are the table structure of the complete two tables:
tr_orders
tr_reciept
i dont understand why these tables are tr tables?
Why you don't always put a Primary Key on all the Foreign Keys
When something 'happens' it goes into a transaction. Someone buys a toy at a shop. A row is created recording that it was a toy and the datetime it happened and how much it cost.
The someone else buys a toy ten minutes later
We have two records in our transaction table:
Date Time Product_Key Shop_Key Amount
--------------------------------------------------------------------------
18 Dec 2015 13:05 7 12 10
18 Dec 2015 13:15 7 12 10
Here we have two foreign keys: Product_Key and Shop_Key
We can't create a PK on just those two foreign keys because then one shop could only ever sell one toy.
So the PK does not automatically go on all the FK's
But really the thing to take away is that your data model (tables, fields, keys, datatypes) reflects what your business does. If a shop could truly only ever sell one toy, it would be a valid data model to have a PK on those two fields.
Some characteristics of 'transactional vs master tables
"Transactional" and "master" tables generally have a many to one relationship, meaning many transactions match one master record. Many purchase records match the same single toy record. A FK is a dead giveaway to this kind of relationship although "master" tables also have FK's
"Transactional" tables usually have a date or some kind of event id and are often 'aggregated' when reporting. This could be a record count or a sum of an amount.
Some characteristics of real world systems
It's entirely likely that someone forgot to put on a FK or PK, or it could be that there is a unique key (not a PK) enforcing what you are expectig to see.
I've seen live systems where the keys were clearly incorrect, or there were no keys at all.
Master - - - - - - - - - - - - - - - - - - - - - - Transaction
Country .... Employeee ...... Customer ........... Order
Master & Lookup tables exist in a Range, not a Binary On/Off State, and reflects the expectation of the amount of activity the table will experience
Lookup/Reference tables like State, Currency, Country, etc. RARELY have new records or changes -- Very "Master"
Employees add or change records occasionally, but not often (hopefully) so more "Master" than "Transaction"
Customers add or change records more often than Employees (also hopefully) so still a measure of "Master" but also with "Transaction" qualities
Orders are added and changed ALL the time (hopefully) and are Very "Transaction,"
Same with Reciepts
If a table has No FK fields, it's likely very "Master"
Tables with FKs have some amount of "Transaction" to them, the more you expect new records - the more "Transaction" the table could be.
Keys:
in my opinion, every table should have a surrogate PK, not related to FKs or any Natural keys. Lots of reasons for this opinion, but whatever works for you is cool, too.
Often, if there is an obvious Natural key, then a table needs a Unique constraint for that key, in addition to the PK

How to add column in table 1 to be type of table 2?

I define table 1.
Now i want to add new table - and one of the column of the second table need to be the first table -
How can i do it ?
If you want one column of a table to reference another table, then your best bet is probably to go read up on the concept of keys, primary keys, and foreign keys in database design.
For example, in a database of companies and employees, you might have 2 tables like this:
Company (c_id, name, city)
Employee (e_id, c_id, name)
In the Company table, c_id would be a primary key. In the Employee table, c_id would be a foreign key referencing Company. This would allow you to do queries like
SELECT E.name
FROM Employee as E, Company as C
WHERE E.c_id = C.c_id AND C.name = "IBM"
which would return the names of employees who work at IBM.
Links:
http://en.wikipedia.org/wiki/Primary_key
http://en.wikipedia.org/wiki/Foreign_key
Why cant you go for a foreign relationship.
for eg : Table1 (ID,ForeignKeyId, other columns)
Table2 (ID,other columns)
ForigenKeyId will be the primary key of Table2
If you really need table as a column, you should read http://msdn.microsoft.com/en-us/library/ms175010.aspx for a solution. However, this is highly unlikely that you really need table column datatype, as it is primarily used for temporary storage.
If you don't know primary-foreign keys relationships stuff, you should take some time learning relational databases or have someone design a database schema for you based on business entities and your application needs. Otherwise you will end up with a design which is completely unmaintainable and mid term it will backfire on you.
If you need a quick reading on PK/FK topic, please read http://www.functionx.com/sqlserver2005/Lesson13.htm. It should give you a knowledge required to tackle with this particular issue.

Do I need to define a new primary key field for each table?

I have a few database tables that really only require a unique id that references another table e.g.
Customer Holiday
******** *******
ID (PK) ---> CustomerID (PK)
Forename From
Surname To
....
These tables such as Holiday, only really exist to hold information regarding a Customer. Therefore, do I need to specify a separate field to hold the ID for the holiday? i.e.
Holiday
*******
ID (PK)
CustomerID (FK)
...
Or would I be ok, in this instance, to just set the CustomerID as the primary key in the table?
Regards,
James.
This really depends on what you are doing.
if each customer can have only 1 holiday, then yes, you could make the customerid the primary key.
If each customer can have multiple holidays, then no, you would want to add a new id column, make it the primary. This allows you to select holidays by each customer AND to select individual records by their unique id.
Additionally if each customer can only have 1 holiday, I'd just add the holiday information to the table, as a one-to-one relationship is typically un-necessary.
If I understand your question correctly, you could only use the Customer table as a primary key in Holiday if there will never be any other holiday for that customer in the table. In other words, two holidays for one customer breaks using the Customer id as a primary key.
If there will ever be an object-oriented program associated with this database, each entity (each row) must have a unique key.
Your second design assures that each instance of Holiday can be uniquely identified and processed by an OO application using a simple Object-Relational Mapping.
Generally, it's best to assure that every entity in the database has a unique, immutable, system-assigned ("surrogate") key. Other "natural" keys can have unique indexes, constraints, etc., to fit the business logic.
Previous answer correct, but also remember, you could have 2 seperate primary keys in each table, and the "holiday" table would have the foreign key to CustomerId.
Then you could manage the assignment of holidays to customers in your code, to make sure that only one holiday can be assigned to a customer, but this brings in the problem concurrency, being 2 people adding a holiday to a customer at the same time will most probably result in a customer having 2 holidays.
You could even place holiday fields in the customer table if a customer can only be created with a holiday, but this design is messy, and not really advised
So once again, option in your question 2 still the best way to go, just giving you your options.
In practice I've found that every table should have a unique primary key identifying the records in those tables. All relationships with other tables should be explicitly declared.
This helps others understand the relationships better, especially if they use a tool to reverse-engineer the schema into a visual representation.
In addition, it gives you more flexibility to expand your solution in the future. You may only have one holiday per customer now, but this is much more difficult to change if you make customer ID the primary key.
If you want to mandate the uniqueness of customer in the holiday table, create a unique index on that foreign key. In fact, this could improve performance when querying on customer ID (although I'm guessing you won't see enough records to notice this improvement).

Resources