Database Modelling, Structures, and Relationships - database

Currently I'm designing a database model that would serve as a database for an inventory system. However, I'm facing difficulties in the database structures particularly on whether I would add an extra column for the parent table for it's child ID.
Presented in the figure below is a part of the database that I'm currently working on. I'm working on the Normalization forms that's why it already has multiple tables. However, in the Shipment Table (highlighted in blue) in this case the parent table of Shipment Details (highlighted in red) I don't know if I should include an extra column for the shipment table for it to identify or connect to the Shipment Detail table.
I already included a foreign key for the Shipment Detail for it to identify which Shipment it relates to I just don't know if I should add another ID column for the details in the Shipment table. To be more specific, should I add a "Shipment Detail ID" column for the Shipment table? I worry it might result to redundancies if I include it.

If each shipment has exactly one shipment detail
shipment {SHIPMENT_ID, ...}
PK {SHIPMENT_ID}
shipment_detail {SHIPMENT_ID, ...}
PK {SHIPMENT_ID}
FK {SHIPMENT_ID} REFERENCES
shipment {SHIPMENT_ID}
If each shipment can have more than one shipment detail
shipment {SHIPMENT_ID, ...}
PK {SHIPMENT_ID}
shipment_detail {SHIPMENT_ID, SHP_DET_NO, ... }
PK {SHIPMENT_ID, SHP_DET_NO}
FK {SHIPMENT_ID} REFERENCES
shipment {SHIPMENT_ID}
Notes:
All attributes (columns) NOT NULL
PK = Primary Key
AK = Alternate Key (Unique)
FK = Foreign Key

It depends. If you want a Shipment to have many ShipmentDetails then no, because you're going to repeat ShipmentDetailId in the Shipment table for every child it has, an thus violating 1FN.
If you have a "1 to 1" relationship, having two tables might not be necessary because you can have everything in just the Shipment table.
I've seen tables that became too large in columns amount let's say, but I've never seen a performance boost for separating the columns in different tables.
Hope this helps!

Related

Can a 3NF table have a PK with repeating values but all nonkeys are dependent on the PK (no transitive dependency)?

I know that PK have to have unique values. I also know that for a table to be in 3NF, there can be no non-key depending on another non-key.
I'm trying to create a table with these requirements: The data reflect that a professor can have multiple advisees, can serve on multiple committees, and can edit more than one journal.
I have a Professor table with these attributes (all dependent on PK):
EMP_NUM (FK) (PK)
PROF_RANK
PROF_OFFICE
COMMITTEE_CODE (FK)
JOURNAL_CODE (FK)
ADVISEE_CODE (FK)
Professor A has 5 COMMITTEE_CODE, so I put different COMMITTEE_CODE on different rows (to make each box atomic), but that means I'll have to repeat the EMP_NUM, PROF_RANK and PROF_OFFICE 5 times. So now idk if EMP_NUM can be considered the PK anymore.
I saw examples on some websites that have repeating values for the PK in a 3NF table. But idk, isn't PK supposed to have only unique values?
If I separate the EMP_NUM and COMMITTEE_CODE to a new table, I'll still have to repeat the same EMP_NUM 5 times for 5 different COMMITTEE_CODE.
As I understand Professor-Commitee is a many-to-many relation. In this case you should create a join table PROF_COMM_REL table where it would have
SURROGATE ID
EMP_NUM (FK)
COMMITTEE_CODE(FK)
The Professor table should not have any COMMITTEE_CODE as the relation is stored in the join table.
I would also recommend using surrogate keys - ids that do not have any meaning like anything that can change over time. For example, the name must not be PK as the name of a person can change and it would implicate to update whole db structure

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.

Separate tables for online and in-store purchases?

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.

Another many-to-many relationship question

My database includes a Customer and a Subcategories table.
Customers can belong to one-or-more Subcategories (and of course there are one-or-more Customers for any Subcategory).
I wonder which is the best solution to link these tables that share a many-to-many relationship:
A "standard" junction CustomerSubcategory table that includes just two fields: CustomerID (PK, FK) and SubcategoryID (PK, FK), or
A CustomerSubcategoryDetail table that would also include a CustomerSubcategoryDetailID (PK), as well as the SubcategoryID (PK, FK) and CustomerID (FK) fields.
Any advice?
Cheers, Corbex
I don't think the additional PK on the junction table adds any value. Will you ever have to look up the value(s) in that table without being able to identify them by Customer and/or SubCategoryID? Will the CustomerSubCategoryDetailID value be used anywhere else?
An interesting discussion ensued on my blog when I complained about folks knee-jerking an IDENTITY column onto every single table. Some folks made some good arguments for having an OrderDetailID column on the OrderDetails table. Do any of these situations apply to you?
I don't see the need for a third column with a customersubcategoryid; therefore, I would go with the first option. The extra column is not going to give you any advantage in any of your joins. You won't even use it.
Go with your first choice. Make sure that you create a key that includes both columns and enforces uniqueness. That way you'll never need a separate primary key to distinguish between otherwise identical rows.
There is a additional benefit in having both columns in the unique key. Queries that need to perform a lookup by the first column can use the index, but they never need to read the data rows because the index already contains the second column.

How to insert multiple rows for a single primary key?

I have a table named 'Patient_detail'. There are 4 columns in this table. They are:
patient_id primary key(not null)
visit_serial_ID primary key(not null)
examination
plan
Now, how can I insert multiple records in 'examination' and 'plan' column against the single primary key 'patient_id' and 'visit_serial_ID' of the table 'Patient_detail'?
The datatypes of the fields are as follows:
patient_id: number(11)
visit_serial_ID: number(5)
examination: varchar2(50)
plan: varchar2(50)
You can't (that's the whole point of a primary key - you have one row per value). You need to split this into a couple of tables, one for visits and one for patients. The visit table would have a foreign key relationship to the patient table's primary key column.
EDIT
You need to think about what actual real-life things you are representing, and how they interrelate. For each separate real-life thing, you would usually have a separate table. This allows the one-to-one, many-to-one, many-to-many relationships that you are after. For instance, you are representing a patient who has a visit, during which there are a number of examinations, each of which has a corresponding plan (is this correct?). You should therefore have a patient table containing patient data, a visit table, containing visit data, and an examination table containing examination data, and maybe even a plan table containing plan data.
The visit table has a many-to-one relationship with the patient table (a patient can visit a number of time). To achieve this, it should have a foreign key to the patient_id column. Similarly, the examination table has a many-to-one relationship with the visit table, so, again, it should have a foreign key to the visit table's primary key.
There are further ways that the can be separated. As Sascha said, look up normalisation.
You can do this but your primary key would cease to be a primary key and you data would be denormalized. The best way to do this would be to split this table into two separate tables like this:
Patients
----------
PatientId
Visits
----------
VisitSerialId
Examination
Pland
PatientId
Notice that the Visits table has a foreign key realtionship to the Patients table. This will allow you to have the 1:M relationship you are looking for.
You can't. That's what a primary key is - something that is unique to every row. You would need a separate table with its own primary key, and with a foreign key relationship to this table, in order to store multiple entries. This would then be a straightforward one-to-many relationship.
As darasd said you can't. What you're looking for is call normalization.

Resources