Changes between Version 2 and Version 3 of Normalization


Ignore:
Timestamp:
08/13/25 20:56:31 (5 days ago)
Author:
226030
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Normalization

    v2 v3  
    124124- ca_id -> ca_name, ca_is_available
    125125
    126 There isn’t one attribute that is a candidate for primary key so BCNF is violated.
    127 
    128 Step 1: Decompose R by Order_id
    129 
    130   {order_id}* = {employee_id, o_timestamp, o_status, table_number, seat_capacity delivery_address, customer_id}
    131 
    132   R1 = {order_id, employee_id, o_timestamp, o_status, table_number, seat_capacity delivery_address, customer_id}
    133 
    134   R2 = {order_id, tip_amount, p_id, p_timestamp, payment_type, amount, oi_id, oi_timestamp, oi_is_processed, oi_price, oi_quantity, pr_id, pr_description, tax_class, pr_price, pr_name, manage_inventory, ca_id, ca_name, ca_is_available, i_quantity, i_restock_level}
    135 
    136 Step 2: Decompose R1 by table_number
    137 
    138   {table_number}*= {table_number, seat_capacity}
    139 
    140   R3={table_number,seat_capacity}
    141 
    142   R4= {order_id, employee_id, o_timestamp, o_status, table_number, delivery_address, customer_id}
    143 
    144   Due to the issue that when there is a TabOrder the delivery_address and customer_id will always be NULL values and when there is an OnlineOrder table_number will always have NULL value we split R4 into
    145 
    146   R5= {order_id, employee_id, o_timestamp, o_status}
    147 
    148   R6= {order_id, table_number}
    149 
    150   R7= {order_id, delivery_address, customer_id}
    151 
    152 Step3: Decompose R2 by p_id
    153 
    154   {p_id}I* = { order_id, tip_amount, p_id, p_timestamp, payment_type, amount}
    155 
    156   R8 = {order_id, tip_amount, p_id, p_timestamp, payment_type, amount}
    157 
    158   Because we have order_id in R8 we don’t need to keep p_id in R9.
    159 
    160   R9 = {order_id, oi_id, oi_timestamp, oi_is_processed, oi_price, oi_quantity, pr_id, pr_description, tax_class, pr_price, pr_name, manage_inventory, ca_id, ca_name, ca_is_available, i_quantity,    i_restock_level
    161 
    162 Step 4: Decompose R9 by pr_id
    163   {pr_id}* = {pr_id, pr_description, tax_class, pr_price, pr_name, manage_inventory, ca_id, ca_name, ca_is_available, i_quantity, i_restock_level}
    164 
    165   R10 = {pr_id, pr_description, tax_class, pr_price, pr_name, manage_inventory, ca_id, ca_name, ca_is_available, i_quantity, i_restock_level}
    166   R11 = { order_id, oi_id, oi_timestamp, oi_is_processed, oi_price, oi_quantity, pr_id}
    167 Step 5: Decompose R10 by ca_id
    168   {ca_id}* = {ca_id, ca_name, ca_is_available}
    169 
    170   R12= {ca_id, ca_name, ca_is_available}
    171 
    172   R13 = {pr_id, pr_description, tax_class, pr_price, pr_name, manage_inventory, ca_id,i_quantity,i_restock_level}
    173 
    174 Step 6: Decompose Inventory from R13
    175 
    176   {i_quantity, i_restock_level} are functionally dependent on pr_id only when manage_inventory is true. If manage_inventory is false it leads to NULL values in our table so we decompose R13 to
    177 
    178   R14 = {pr_id, pr_description, tax_class, pr_price, pr_name, manage_inventory, ca_id}
    179 
    180   And
    181 
    182   R15= {pr_id, i_quantity,i_restock_level}
    183 
    184 Final BCNF Realtions:
    185   R3(Tables), R5(Orders), R6(TabOrders), R7(OnlineOrders), R8(Payments), R11(OrderItems), R14(Products), R15(Inventory)
    186 
    187 == Conclusion
    188 Ultimately, the process of normalization validated our initial design. The final tables derived through formal decomposition were a perfect match for the original tables represented in the ER diagram, confirming the correctness of the schema.
     126Left only: oi_id, p_id,
     127
     128Left and right: table_number, order_id, pr_id, ca_id,
     129
     130Right only: employee_id, o_timestamp, o_status, delivery_address, customer_id, seat_capacity, p_timestamp, payment_type, amount, tip_amount, oi_timestamp, oi_is_processed, oi_price, oi_quantity, i_quantity, i_restock_level, ca_name, ca_is_available, manage_inventory, pr_description, tax_class, pr_price, pr_name
     131
     132From our analysis we will try {oi_id, p_id} as a candidate key:
     133
     134{oi_id, p_id}+= { oi_timestamp, oi_is_processed, oi_price, pr_id, order_id, oi_quantity, pr_description, tax_class, pr_price, pr_name, manage_inventory, i_quantity, i_restock_level, ca_id, ca_name, ca_is_available, -> p_timestamp, payment_type, amount, tip_amount, employee_id, o_timestamp, o_status, table_number, delivery_address, customer_id, seat_capacity}
     135
     136{oi_id, p_id} is the only candidate key and primary key.
     137
     138There are no multi-valued dependencies in our relation, and therefore it satisfies the first normal form.
     139
     140But our previous defined relation isn’t in 2NF because there is a partial dependency:
     141
     142p_id -> p_timestamp, payment_type, amount, tip_amount, order_id
     143
     144{p_id}+= {p_id, p_timestamp, payment_type, amount, tip_amount, order_id, employee_id, o_timestamp, o_status, table_number, delivery_address, customer_id, seat_capacity}
     145
     146Step 1: Decompose R by p_id
     147  R1 = {p_id, p_timestamp, payment_type, amount, tip_amount, order_id, employee_id, o_timestamp, o_status, table_number, delivery_address, customer_id, seat_capacity}
     148
     149  R2 = {oi_id, oi_timestamp, oi_is_processed, oi_price, order_id, pr_id, oi_quantity, pr_description, tax_class, pr_price, pr_name, manage_inventory, i_quantity, i_restock_level, ca_id, ca_name, ca_is_available}
     150
     151Step 2. Decompose R1 by order_id
     152  Functional dependencies in R1:
     153
     154  p_id -> p_timestamp, payment_type, amount, tip_amount, order_id
     155
     156  order_id -> employee_id, o_timestamp, o_status, table_number, delivery_address, customer_id
     157  table_number -> seat_capacity
     158
     159  R1 is not in BCNF because of transitive dependencies
     160  {order_id}+ = {order_id, employee_id, o_timestamp, o_status, table_number, delivery_address, customer_id, seat_capacity}
     161
     162  R3 = {order_id, employee_id, o_timestamp, o_status, table_number, delivery_address, customer_id, seat_capacity}
     163 
     164  R4 = {p_id, p_timestamp, payment_type, amount, tip_amount, order_id}
     165Step 3. Decompose R3 by table_number
     166  R3 is still not in BCNF because of transitive dependency
     167 
     168  order_id -> employee_id, o_timestamp, o_status, table_number, delivery_address, customer_id
     169  table_number -> seat_capacity
     170
     171  {table_number}+ = {table_number, seat_capacity}
     172
     173  R5 = {table_number, seat_capacity}
     174
     175  R6 = {order_id, employee_id, o_timestamp, o_status, table_number, delivery_address, customer_id}
     176
     177Step 4. Decompose R2 by pr_id
     178
     179  R2 is not in BCNF because of transitive dependencies
     180
     181  oi_id -> oi_timestamp, oi_is_processed, oi_price, pr_id, order_id, oi_quantity
     182
     183  pr_id -> pr_description, tax_class, pr_price, pr_name, manage_inventory, i_quantity, i_restock_level, ca_id
     184
     185  ca_id -> ca_name, ca_is_available
     186
     187  {pr_id}+ = {pr_id, pr_description, tax_class, pr_price, pr_name, manage_inventory, i_quantity, i_restock_level, ca_id}
     188
     189  R7 = {pr_id, pr_description, tax_class, pr_price, pr_name, manage_inventory, i_quantity, i_restock_level, ca_id, ca_name, ca_is_available}
     190
     191  R8 = {oi_id, oi_timestamp, oi_is_processed, oi_price, pr_id, order_id, oi_quantity}
     192
     193  In R8, I exclude attributes that are functionally dependent on order_id, as these dependencies have already been addressed in the decompositions from Steps 2 and 3 to avoid redundancy.
     194
     195Step 5. Decomposing R7 by ca_id
     196  R7 is not in BCNF due to transitive dependencies
     197
     198  pr_id -> pr_description, tax_class, pr_price, pr_name, manage_inventory, i_quantity, i_restock_level, ca_id
     199
     200  ca_id -> ca_name, ca_is_available
     201
     202  {ca_id}+ = {ca_id, ca_name, ca_is_available}
     203
     204  R9 = {ca_id, ca_name, ca_is_available}
     205
     206  R10 = {pr_id, pr_description, tax_class, pr_price, pr_name, manage_inventory, i_quantity, i_restock_level, ca_id}
     207
     208From the normalization steps, we obtain the relations R4 (Payments), R5 (Tables), R6 (Orders), R8 (OrderItems), R9 (Categories), and R10 (Products). These do not exactly match our initial database design. The difference comes from our goal to minimize NULL values and improve data organization. We chose to decompose the Orders table into TabOrders and OnlineOrders to separate dine-in and delivery-specific attributes. We also store inventory data in a separate Inventory table, where the primary key is product_id, because we give the user the option to store inventory information only for products they wish to track. This way, products without inventory data do not require NULL values in the main Products table.