Changes between Version 7 and Version 8 of Normalization


Ignore:
Timestamp:
02/01/26 19:54:20 (7 days ago)
Author:
233144
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Normalization

    v7 v8  
    11= Normalization
    2 
    3 == Initial de-normalized relation (R) and functional dependencies
    4 
    5 R(
    6   user_id, username, password, email,
    7   component_id, component_name, brand, price, component_type, img_url,
    8   cpu_socket, cpu_cores, cpu_threads, cpu_base_clock, cpu_boost_clock, cpu_tdp,
    9   gpu_vram, gpu_tdp, gpu_base_clock, gpu_boost_clock, gpu_chipset, gpu_length,
    10   memory_type, memory_speed, memory_capacity, memory_modules,
    11   storage_type, storage_capacity, storage_form_factor,
    12   psu_type, psu_wattage, psu_form_factor,
    13   motherboard_socket, motherboard_chipset, motherboard_form_factor,
    14   ram_type, num_ram_slots, max_ram_capacity, pci_express_slots,
    15   case_cooler_max_height, case_gpu_max_length,
    16   case_storage_form_factor, case_storage_slots,
    17   case_ps_form_factor,
    18   case_mobo_form_factor,
    19   cooler_type, cooler_height, cooler_max_tdp,
    20   cooler_socket,
    21   memory_card_slots, memory_card_interface,
    22   optical_form_factor, optical_type, optical_interface,
    23   optical_write_speed, optical_read_speed,
    24   sound_sample_rate, sound_bit_depth, sound_chipset, sound_interface, sound_channel,
    25   cable_length, cable_type,
    26   net_adapter_wifi, net_adapter_interface, net_adapter_antennas,
    27   net_card_ports, net_card_speed, net_card_interface,
    28   build_id, build_name, build_created_at, build_description,
    29   build_total_price, build_is_approved,
    30   build_component_id,
    31   rating_value, review_content, review_created_at,
    32   suggestion_id, suggestion_link, suggestion_description,
    33   suggestion_status, suggestion_admin_comment, suggestion_component_type
    34 )
    35 
    36 Functional dependencies:
    37 
    38 user_id → username, password, email
    39 
    40 component_id → name, brand, price, component_type, img_url
    41 
    42 component_id → cpu_socket, cpu_cores, cpu_threads, cpu_base_clock, cpu_boost_clock, cpu_tdp
    43 
    44 component_id → gpu_vram, gpu_tdp, gpu_base_clock, gpu_boost_clock, gpu_chipset, gpu_length
    45 
    46 component_id → memory_type, memory_speed, memory_capacity, memory_modules
    47 
    48 component_id → storage_type, storage_capacity, storage_form_factor
    49 
    50 component_id → psu_type, psu_wattage, psu_form_factor
    51 
    52 component_id → motherboard_socket, motherboard_chipset, motherboard_form_factor, ram_type, num_ram_slots, max_ram_capacity, pci_express_slots
    53 
    54 component_id → case_cooler_max_height, case_gpu_max_length
    55 
    56 component_id → cooler_type, cooler_height, cooler_max_tdp
    57 
    58 component_id → memory_card_slots, memory_card_interface
    59 
    60 component_id → optical_form_factor, optical_type, optical_interface, optical_write_speed, optical_read_speed
    61 
    62 component_id → sound_sample_rate, sound_bit_depth, sound_chipset, sound_interface, sound_channel
    63 
    64 component_id → cable_length, cable_type
    65 
    66 component_id → net_adapter_wifi, net_adapter_interface, net_adapter_antennas
    67 
    68 component_id → net_card_ports, net_card_speed, net_card_interface
    69  
    70 (component_id, form_factor) → /, for case motherboard and power supply form factors
    71 
    72 (component_id, form_factor) → num_slots, for case storage form factors
    73 
    74 (component_id, socket) → /, for cooler cpu sockets
    75 
    76 build_id → user_id, build_name, build_created_at, build_description, build_total_price, build_is_approved
    77 
    78 build_component_id → build_id, user_id
    79 
    80 (build_id, user_id) → rating_value
    81 
    82 review_id → build_id, user_id, review_content, review_created_at
    83 
    84 suggestion_id → user_id, admin_id, link, description, status, admin_comment, component_type
    85 
    86 The de-normalized relation violates 1NF because it contains multi-valued attributes.
    87 
    88 == Candidate keys of the de-normalized relation
    89 
    90 Because the universal relation combines users, builds, components, reviews, and suggestions, a minimal key must uniquely identify all of them.
    91 
    92 The artifical candidate key is {user_id, build_id, component_id, review_id, suggestion_id, build_component_id}
    93 
    94 Universal relation primary key = {user_id, build_id, component_id, review_id, suggestion_id, build_component_id}
     2== Initial de-normalized relation and functional dependencies
     3Attributes with identical names originating from different relations were renamed using entity-based prefixes in order to avoid duplicate attribute names in the universal relation.
     4
     5R(user_id, username, password, email,
     6component_id, component_name, brand, component_price, component_type,
     7cpu_socket, cpu_cores, cpu_threads, cpu_base_clock, cpu_boost_clock, cpu_tdp,
     8gpu_vram, gpu_tdp, gpu_base_clock, gpu¬_boost_clock, gpu_chipset, gpu_length,
     9memory_type, memory_speed, memory_capacity, memory_modules,
     10storage_type, storage_capacity, storage_form_factor,
     11power_supply_type, power_supply_capacity, power_supply_form_factor,
     12motherboard_socket, motherboard_chipset, motherboard_form_factor, motherboard_ram_type, motherboard_num_ram_slots, motherboard_max_ram_capacity, motherboard_pci_express_slots,
     13pc_case_coooler_max_height, pc_case_gpu_max_length,
     14pc_case_storage_form_factor, num_slots
     15pc_case_ps_form_factor,
     16pc_case_mobo_form_factor,
     17cooler_type, cooler_height, cooler_max_tdp_supported,
     18cooler_cpu_socket,
     19memory_card_num_slots, memory_card_interface,
     20optical_drive_form_factor, optical_drive_type, optical_drive_interface, optical_drive_write_speed, optical_drive_read_speed,
     21sound_card_sample_rate, sound_card_bit_depth, sound_card_chipset, sound_card_interface, sound_card_channel,
     22cables_length_cm, cables_type,
     23network_adapter_wifi_version, network_adapter_interface, network_adapter_num_antennas,
     24network_card_num_ports, network_card_speed, network_card_interface,
     25build_id, build_name, build_created_at, build_description, build_total_price, build_is_approved,
     26num_components,
     27rating_build_value,
     28review_id, review_content, review_created_at,
     29suggestion_id, suggestion_admin_id, suggestion_link, suggestion_admin_comment, suggestion_description, suggestion_status, suggestion_component_type
     30
     31Before anything else, we need to note that pc_case_storage_form_factor (composite attribute with num_slots), pc_case_ps_form_factor, pc_case_mobo_form_factor and cooler_cpu_socket are multivalued attributes.
     32
     33Now we will list the functional dependencies(the primary/composite keys are on the left side). For component_id the name of the proper subclass will be shown in parenthesis for better presentation.
     34
     35FD1: user_id -> username, password, email
     36
     37FD2: component_id -> component_name, brand, component_price, component_type, img_url
     38
     39FD3: component_id(cpu) -> cpu_socket, cpu_cores, cpu_threads, cpu_base_clock, cpu_boost_clock, cpu_tdp
     40
     41FD4: component_id(gpu) -> gpu_vram, gpu_tdp, gpu_base_clock, gpu¬_boost_clock, gpu_chipset, gpu_length
     42
     43FD5: component_id(memory) -> memory_type, memory_speed, memory_capacity, memory_modules
     44
     45FD6: component_id(storage) -> storage_type, storage_capacity, storage_form_factor
     46
     47FD7: component_id (power_supply) -> power_supply_type, power_supply_capacity, power_supply_form_factor
     48
     49FD8: component_id(motherboard) -> motherboard_socket, motherboard_chipset, motherboard_form_factor, motherboard_ram_type, motherboard_num_ram_slots, motherboard_max_ram_capacity, motherboard_pci_express_slots
     50
     51FD9: component_id(pc_case) -> pc_case_coooler_max_height, pc_case_gpu_max_length
     52
     53FD10: component_id(cooler) -> cooler_type, cooler_height, cooler_max_tdp_supported
     54
     55FD11: component_id(memory_card) -> memory_card_num_slots, memory_card_interface
     56
     57FD12: component_id(optical_drive) -> optical_drive_form_factor, optical_drive_type, optical_drive_interface, optical_drive_write_speed, optical_drive_read_speed
     58
     59FD13: component_id(sound_card) -> sound_card_sample_rate, sound_card_bit_depth, sound_card_chipset, sound_card_interface, sound_card_channel
     60
     61FD14: component_id(cables) -> cables_length_cm, cables_type
     62
     63FD15: component_id(network_adapter) -> network_adapter_wifi_version, network_adapter_interface, network_adapter_num_antennas
     64
     65FD16: component_id(network_card) -> network_card_num_ports, network_card_speed, network_card_interface
     66
     67FD17: build_id -> user_id, build_name, build_created_at, build_description, build_total_price, build_is_approved
     68
     69FD18: build_id, component_id -> num_components
     70
     71FD19: build_id, user_id -> /
     72
     73FD20: build_id, user_id -> rating_build_value
     74
     75FD21: review_id -> build_id, user_id, review_content, review_created_at
     76
     77FD22: suggestion_id -> user_id, suggestion_admin_id, suggestion_link, suggestion_admin_comment, suggestion_description, suggestion_status, suggestion_component_type
     78
     79Left: user_id, component_id, build_id, review_id, suggestion_id
     80
     81Left and right: build_id, user_id
     82
     83Right:
     84username, password, email, component_name, brand, component_price, component_type, img_url, cpu_socket, cpu_cores, cpu_threads, cpu_base_clock, cpu_boost_clock, cpu_tdp, gpu_vram, gpu_tdp, gpu_base_clock, gpu¬_boost_clock, gpu_chipset, gpu_length, memory_type, memory_speed, memory_capacity, memory_modules, storage_type, storage_capacity, storage_form_factor, power_supply_type, power_supply_capacity, power_supply_form_factor, motherboard_socket, motherboard_chipset, motherboard_form_factor, motherboard_ram_type, motherboard_num_ram_slots, motherboard_max_ram_capacity, motherboard_pci_express_slots, pc_case_coooler_max_height, pc_case_gpu_max_length, num_slots, pc_case_storage_form_factor, pc_case_ps_form_factor, pc_case_mobo_form_factor, cooler_cpu_socket, cooler_type, cooler_height, cooler_max_tdp_supported, memory_card_num_slots, memory_card_interface, optical_drive_form_factor, optical_drive_type, optical_drive_interface, optical_drive_write_speed, optical_drive_read_speed, sound_card_sample_rate, sound_card_bit_depth, sound_card_chipset, sound_card_interface, sound_card_channel, cables_length_cm, cables_type, network_adapter_wifi_version, network_adapter_interface, network_adapter_num_antennas, network_card_num_ports, network_card_speed, network_card_interface, build_name, build_created_at, build_description, build_total_price, build_is_approved, rating_build_value, review_content, review_created_at, suggestion_admin_id, suggestion_link, suggestion_admin_comment, suggestion_description, suggestion_status, suggestion_component_type
     85
     86Attributes that never appear on the right side(only left) are component_id, review_id, suggestion_id. This means that they must be a part of the candidate key because nothing else can determine them.
     87
     88Let K = { component_id, review_id, suggestion_id }
     89
     90We now compute the closure K+
     91
     92Start with K+ = { component_id, review_id, suggestion_id }
     93
     94By applying FD2 – FD16, we add:
     95component_name, brand, component_price, component_type,
     96cpu_socket, cpu_cores, cpu_threads, cpu_base_clock, cpu_boost_clock, cpu_tdp,
     97gpu_vram, gpu_tdp, gpu_base_clock, gpu¬_boost_clock, gpu_chipset, gpu_length,
     98memory_type, memory_speed, memory_capacity, memory_modules,
     99storage_type, storage_capacity, storage_form_factor,
     100power_supply_type, power_supply_capacity, power_supply_form_factor,
     101motherboard_socket, motherboard_chipset, motherboard_form_factor, motherboard_ram_type, motherboard_num_ram_slots, motherboard_max_ram_capacity, motherboard_pci_express_slots,
     102pc_case_coooler_max_height, pc_case_gpu_max_length,
     103cooler_type, cooler_height, cooler_max_tdp_supported,
     104memory_card_num_slots, memory_card_interface,
     105optical_drive_form_factor, optical_drive_type, optical_drive_interface, optical_drive_write_speed, optical_drive_read_speed,
     106sound_card_sample_rate, sound_card_bit_depth, sound_card_chipset, sound_card_interface, sound_card_channel,
     107cables_length_cm, cables_type,
     108network_adapter_wifi_version, network_adapter_interface, network_adapter_num_antennas,
     109network_card_num_ports, network_card_speed, network_card_interface
     110
     111By applying FD21, we add:
     112build_id, user_id, review_content, review_created_at
     113
     114By applying FD17, we add:
     115build_name, build_created_at, build_description, build_total_price, build_is_approved
     116
     117By applying FD1, we add:
     118username, password, email
     119
     120By applying FD22, we  add:
     121suggestion_admin_id, suggestion_link, suggestion_admin_comment, suggestion_description, suggestion_status, suggestion_component_type
     122
     123By applying FD18 and FD20, we add:
     124num_components, rating_build_value
     125
     126After excluding multivalued attributes which we handle separatelu in 1NF, K+ contains all attributes of R, which means that K is a superkey.
     127
     128The universal relation violates 1NF because the attributes case_storage_form_factor, case_ps_form_factor, case_mobo_form_factor, and cooler_cpu_socket represent multivalued attributes, and can contain multiple values for a single component_id. This will be resolved by decomposing them into separate relations.
    95129
    96130== 1NF Decomposition
    97 
    98 Here we have to separate the multi-valued attributes into individual relations. This will ensure that all values are atomic.
    99 
    100 case_storage_form_factors(case_id, form_factor, num_slots)
    101 
    102 case_ps_form_factors(case_id, form_factor)
    103 
    104 case_mobo_form_factors(case_id, form_factor)
    105 
    106 cooler_cpu_sockets(cooler_id, socket)
    107 
    108 
    109 We separate obvious entities in individual relations:
    110 
    111 users(user_id, username, password, email)
    112 
    113 admins(user_id)
    114 
    115 components(component_id, name, brand, price, component_type, img_url)
    116 
    117 cpu(component_id, cpu_socket, cpu_cores, cpu_threads, cpu_base_clock, cpu_boost_clock, cpu_tdp)
    118 
    119 gpu(component_id, gpu_vram, gpu_tdp, gpu_base_clock, gpu_boost_clock, gpu_chipset, gpu_length)
    120 
    121 memory(component_id, memory_type, memory_speed, memory_capacity, memory_modules)
    122 
    123 storage(component_id, storage_type, storage_capacity, storage_form_factor)
    124 
    125 power_supply(component_id, psu_type, psu_wattage, psu_form_factor)
    126 
    127 motherboard(component_id, motherboard_socket, motherboard_chipset, motherboard_form_factor, ram_type, num_ram_slots, max_ram_capacity, pci_express_slots)
    128 
    129 pc_case(component_id, case_cooler_max_height, case_gpu_max_length)
    130 
    131 cooler(component_id, cooler_type, cooler_height, cooler_max_tdp)
    132 
    133 memory_card(component_id, memory_card_slots, memory_card_interface)
    134 
    135 optical_drive(component_id, optical_form_factor, optical_type, optical_interface, optical_write_speed, optical_read_speed)
    136 
    137 sound_card(component_id, sound_sample_rate, sound_bit_depth, sound_chipset, sound_interface, sound_channel)
    138 
    139 cables(component_id, cable_length, cable_type)
    140 
    141 network_adapter(component_id, net_adapter_wifi, net_adapter_interface, net_adapter_antennas)
    142 
    143 network_card(component_id, net_card_ports, net_card_speed, net_card_interface)
    144 
    145 build(build_id, user_id, build_name, build_created_at, build_description, build_total_price, build_is_approved)
    146 
    147 build_component(build_component_id, build_id, component_id)
    148 
    149 review(review_id, build_id, user_id, review_content, review_created_at)
    150 
    151 rating_build(build_id, user_id, rating_value)
    152 
    153 suggestions(suggestion_id, user_id, admin_id, link, description, status, admin_comment, component_type)
    154 
    155 all of which satisfy 1NF.
    156 
    157 
    158 Candidate keys & primary keys:
    159 
    160 users → user_id
    161 
    162 admins → user_id
    163 
    164 components → component_id
    165 
    166 component subclasses (like cpu, gpu etc.) → component_id
    167 
    168 build → build_id
    169 
    170 build_component → build_component_id
    171 
    172 review → review_id
    173 
    174 rating_build → (build_id, user_id)
    175 
    176 favorite_build → (build_id, user_id)
    177 
    178 suggestions → suggestion_id
    179 
    180 == Second Normal Form (2NF)
    181 
    182 2NF focuses on partial dependencies, which can only occur when a relation has a composite primary key and a non-key attribute depends on only part of that key. Relations with a single-attribute primary key were considered to be automatically in 2NF. Most of the relations obtained after 1NF like users, components, build, review and suggestions, have single-attribute primary keys so partial dependencies cannot exist in these relations. The remaining relations that have composite primary keys favorite_build and rating_build were analyzed separately.
    183 
    184 favorite_build(build_id, user_id) - doesn't have non-key attributes so it is already 2NF
    185 
    186 rating_build(build_id, user_id, rating_value) - rating_value depends on full key so it is 2NF
    187 
    188 In the case of associative tables like build_component and favorite_build no non-key attributes are present so partial dependencies are not possible. For rating_build the non-key attribute depend on the full composite key (a rating is uniquely determined by both the user and the build). Since no non-key attribute was found to be partially dependent all relations satisfy 2NF.
    189 
    190 == Third normal Form (3NF)
    191 
    192 users(user_id, username, password, email) - all attributes depend directly on user_id so 3NF is satisfied
    193 
    194 components(component_id, name, brand, price, component_type, img_url) - all attributes depend directly on component_id so this is 3NF
    195 
    196 build(build_id, user_id, build_name, build_created_at, build_description, build_total_price, build_is_approved) - all attributes depend on build_id which means that 3NF is satisfied
    197 
    198 component subclasses (like cpu, gpu, memory etc.) - all attributes depend directly on component_id so 3NF is satisfied
    199 
    200 review(review_id, build_id, user_id, review_content, review_created_at) - attributes depend on review_id, 3NF is satisfied
    201 
    202 rating_build(build_id, user_id, rating_value) → rating_value depends on (build_id, user_id), 3NF is satisfied
    203 
    204 favorite_build(build_id, user_id) - no non-key attributes so this automatically satisfies 3NF
    205 
    206 suggestions(suggestion_id, user_id, admin_id, link, description, status, admin_comment, component_type) - attributes depend on suggestion_id, 3NF is satisfied
    207 
    208 case_storage_form_factors(case_id, form_factor, num_slots) - no transitive dependencies, 3NF is satisfied
    209 
    210 case_ps_form_factors(case_id, form_factor) - no transitive dependencies, 3NF is satisfied
    211 
    212 case_mobo_form_factors(case_id, form_factor) - no transitive dependencies, 3NF is satisfied
    213 
    214 cooler_cpu_sockets(cooler_id, socket) - no transitive dependencies, 3NF is satisfied
    215 
    216 build_component(build_component_id, build_id, component_id) - no transitive dependencies because all attributes depend on build_component_id, therefore 3NF is satisfied.
    217 
    218 == BCNF decomposition
    219 
    220 BCNF checks if every determinant is a super-key so we need to analyze all 3NF relations.
    221 
    222 users(user_id, username, password, email):
    223 
    224  FD: user_id → username, password, email
    225 
    226  Determinant user_id is the primary key (superkey), BCNF
    227 
    228 
    229 admins(user_id):
    230 
    231  Determinant user_id is the primary key (superkey), BCNF
    232 
    233 
    234 components(component_id, name, brand, price, component_type, img_url):
    235 
    236  FD: component_id → name, brand, price, component_type, img_url
    237 
    238  Determinant component_id is the primary key (superkey), BCNF
    239 
    240 
    241 Component specialization tables (cpu, gpu, memory, etc.):
    242 
    243  Each table: primary key = component_id
    244 
    245  All attributes depend only on component_id
    246 
    247  Determinant is primary key(superkey), BCNF
    248 
    249 
    250 build(build_id, user_id, build_name, build_created_at, build_description, build_total_price, build_is_approved):
    251 
    252  FD: build_id → user_id, build_name, build_created_at, build_description, build_total_price, build_is_approved
    253 
    254  Determinant build_id is primary key(superkey), BCNF
    255 
    256 
    257 build_component(build_component_id, build_id, component_id):
    258 
    259  FD: build_component_id → build_id, component_id
    260 
    261  Determinant build_component_id is primary key(superkey), BCNF
    262 
    263 
    264 favorite_build(build_id, user_id):
    265 
    266  FD: Composite key (build_id, user_id) → /
    267 
    268  No non-key attributes so its by default BCNF
    269 
    270 
    271 rating_build(build_id, user_id, rating_value):
    272 
    273  FD: (build_id, user_id) → rating_value
    274 
    275  Determinant is full primary key (superkey), BCNF
    276 
    277 
    278 review(review_id, build_id, user_id, review_content, review_created_at):
    279 
    280  FD: review_id → build_id, user_id, review_content, review_created_at
    281 
    282  Determinant = primary key (superkey), BCNF
    283 
    284 
    285 suggestions(suggestion_id, user_id, admin_id, link, description, status, admin_comment, component_type):
    286 
    287  FD: suggestion_id → user_id, admin_id, link, description, status, admin_comment, component_type
    288 
    289  Determinant is primary key (superkey)
    290 
    291 
    292 case_storage_form_factors(case_id, form_factor, num_slots):
    293 
    294  FD: (case_id, form_factor) → num_slots
    295 
    296  Full composite key is determinant (superkey), BCNF
    297 
    298 
    299 case_ps_form_factors(case_id, form_factor):
    300 
    301  FD: (case_id, form_factor) → /
    302 
    303  Full composite key is determinant (superkey), BCNF
    304 
    305 
    306 case_mobo_form_factors(case_id, form_factor):
    307  
    308  FD: (case_id, form_factor) → /
    309 
    310  Full composite key is determinant (superkey), BCNF
    311 
    312  
    313 cooler_cpu_sockets(cooler_id, socket):
    314 
    315  FD: (cooler_id, socket) → /
    316 
    317  Full composite key is determinant (superkey), BCNF
    318 
    319 
    320 We can now see that all determinants are superkeys, so BCNF is satisfied.
    321 
    322 
     131To achieve 1NF, we decompose the multivalued attributes from R into:
     132
     133component_id , pc_case_storage_form_factor -> num_slots
     134
     135component_id, pc_case_ps_form_factor -> no non-key attributes
     136
     137component_id, pc_case_mobo_form_factor -> no non-key attributes
     138
     139component_id, cooler_cpu_socket -> no non-key attributes
     140
     1411NF is satisfied now. 2NF is not satisfied because of partial dependencies. We can see this through the functional dependencies:
     142
     143FD2-FD16: component_id is part of the key, but the these attributes such as component_name, brand, component_price etc. depend only on component_id.
     144
     145We will decompose by creating new relations from R following FD2 to FD16 where the attributes will depend only on component_id:
     146
     147component_id -> component_id, component_name, brand, component_price, component_type, img_url
     148
     149component_id -> cpu_socket, cpu_cores, cpu_threads, cpu_base_clock, cpu_boost_clock, cpu_tdp
     150
     151component_id -> gpu_vram, gpu_tdp, gpu_base_clock, gpu_boost_clock, gpu_chipset, gpu_length
     152
     153component_id -> memory_type, memory_speed, memory_capacity, memory_modules
     154
     155component_id -> storage_type, storage_capacity, storage_form_factor
     156
     157component_id -> power_supply_type, power_supply_capacity, power_supply_form_factor
     158
     159component_id -> motherboard_socket, motherboard_chipset, motherboard_form_factor, motherboard_ram_type, motherboard_num_ram_slots, motherboard_max_ram_capacity,
     160motherboard_pci_express_slots
     161
     162component_id -> pc_case_coooler_max_height, pc_case_gpu_max_length
     163
     164component_id -> cooler_type, cooler_height, cooler_max_tdp_supported, cooler_cpu_socket
     165
     166component_id -> memory_card_num_slots, memory_card_interface
     167
     168component_id -> optical_drive_form_factor, optical_drive_type, optical_drive_interface, optical_drive_write_speed, optical_drive_read_speed
     169
     170component_id -> sound_card_sample_rate, sound_card_bit_depth, sound_card_chipset, sound_card_interface, sound_card_channel
     171
     172component_id -> cables_length_cm, cables_type
     173
     174component_id -> network_adapter_wifi_version, network_adapter_interface, network_adapter_num_antennas
     175
     176component_id -> network_card_num_ports, network_card_speed, network_card_interface
     177
     178Primary key in all of these is component_id.
     179
     180FD21: review_id is part of the key, but these attributes build_id, user_id, review_content, review_created_at depend  only on review_id.
     181
     182We will solve this partial dependency by creating a new relation:
     183
     184review_id -> build_id, user_id, review_content, review_created_at
     185
     186Primary key here is review_id.
     187
     188FD22: suggestion_id is part of the key, but user_id, suggestion_admin_id, suggestion_link, suggestion_admin_comment, suggestion_description, suggestion_status, suggestion_component_type depend only on suggestion_id.
     189
     190We will solve this partial dependency by creating a new relation:
     191
     192suggestion_id -> user_id, suggestion_admin_id, suggestion_link, suggestion_admin_comment, suggestion_description, suggestion_status, suggestion_component_type
     193
     194We get the following relations:
     195
     196R1 { review_id, build_id, user_id, review_content, review_created_at } where PK = review_id - BCNF
     197
     198R2 { suggestion_id, user_id, suggestion_admin_id, suggestion_link, suggestion_admin_comment, suggestion_description, suggestion_status, suggestion_component_type } where PK = suggestion_id - BCNF
     199
     200R3 { component_id, component_name, brand, component_price, component_type, img_url } where PK = component_id - BCNF
     201
     202R4 { component_id, cpu_socket, cpu_cores, cpu_threads, cpu_base_clock, cpu_boost_clock, cpu_tdp } where PK = component_id - BCNF
     203
     204R5 { component_id, gpu_vram, gpu_tdp, gpu_base_clock, gpu_boost_clock, gpu_chipset, gpu_length } where PK = component_id - BCNF
     205
     206R6 { component_id, memory_type, memory_speed, memory_capacity, memory_modules } where PK = component_id - BCNF
     207
     208R7 { component_id, storage_type, storage_capacity, storage_form_factor } where PK = component_id - BCNF
     209
     210R8 { component_id, power_supply_type, power_supply_capacity, power_supply_form_factor } where PK = component_id - BCNF
     211
     212R9 { component_id, motherboard_socket, motherboard_chipset, motherboard_form_factor, motherboard_ram_type, motherboard_num_ram_slots, motherboard_max_ram_capacity, motherboard_pci_express_slots } where PK = component_id - BCNF
     213
     214R10 { component_id,  pc_case_coooler_max_height, pc_case_gpu_max_length } where PK = component_id - BCNF
     215
     216R11 { component_id, cooler_type, cooler_height, cooler_max_tdp_supported, cooler_cpu_socket } where PK = component_id - BCNF
     217
     218R12 { component_id, memory_card_num_slots, memory_card_interface } where PK = component_id - BCNF
     219
     220R13 { component_id, optical_drive_form_factor, optical_drive_type, optical_drive_interface, optical_drive_write_speed, optical_drive_read_speed } where PK = component_id - BCNF
     221
     222R14 { component_id, sound_card_sample_rate, sound_card_bit_depth, sound_card_chipset, sound_card_interface, sound_card_channel } where PK = component_id - BCNF
     223
     224R15 { component_id, cables_length_cm, cables_type } where PK = component_id - BCNF
     225
     226R16 { component_id, network_adapter_wifi_version, network_adapter_interface, network_adapter_num_antennas } where PK = component_id - BCNF
     227
     228R17 { component_id, network_card_num_ports, network_card_speed, network_card_interface } where PK = component_id - BCNF
     229
     230R18 { component_id,  pc_case_storage_form_factor , num_slots } where PK = component_id and pc_case_storage_form_factor - BCNF
     231
     232R19 { component_id, pc_case_ps_form_factor } where PK = component_id and pc_case_ps_form_factor - BCNF
     233
     234R20 { component_id, pc_case_mobo_form_factor } where PK = component_id and pc_case_mobo_form_factor - BCNF
     235
     236R21 { component_id, cooler_cpu_socket } where PK = component_id and cooler_cpu_socket - BCNF
     237
     238The remainder of R { component_id, review_id, suggestion_id, build_id, user_id, build_name, build_created_at, build_description, build_total_price, build_is_approved, num_components, rating_build_value, username, password, email } where PK = K (component_id, review_id, suggestion_id)
     239
     2402NF is satisfied but the remaining of R has transitive dependencies which violate 3NF. When looking at FD17: build_id -> build_name, build_created_at, build_description, build_total_price, build_is_approved, here build_id is not part of the candidate key K, but it determines build_name and other attributes. The same thing goes for user_id -> username, password, email when looking at FD1. We will handle these transitive dependencies by creating separate tables.
     241
     242== 3NF decomposition
     243R22 { user_id, username, password, email } where PK = user_id - BCNF
     244
     245R23 { build_id, user_id, build_name, build_created_at, build_description, build_total_price, build_is_approved } where PK = build_id – BCNF
     246
     247Leftover relation R { component_id, review_id, suggestion_id, build_id, user_id, num_components, rating_build_value }
     248
     249From FD18 (build_id, component_id) → num_components we see that build_id and component_id is not a superkey of leftover relation R, this violates BCNF. Same thing goes for FD19 (build_id, user_id) -> / and FD20 (build_id, user_id) → rating_build_value, build_id and user_id is not a superkey of the leftover relation. We will decompose by creating new relations
     250
     251R24 { build_id , component_id, num_components } where PK = build_id, component_id - BCNF
     252
     253R25 { build_id, user_id, rating_build_value } where PK = build_id, user_id - BCNF
     254
     255R26 { build_id, user_id } where PK = build_id, user_id – BCNF
     256
     257== Final BCNF relations
     258
     259Users { user_id, username, password, email }
     260
     261Components { component_id, component_name, brand, component_price, component_type, img_url }
     262
     263Cpu { component_id, cpu_socket, cpu_cores, cpu_threads, cpu_base_clock, cpu_boost_clock, cpu_tdp }
     264
     265Gpu { { component_id, gpu_vram, gpu_tdp, gpu_base_clock, gpu_boost_clock, gpu_chipset, gpu_length }
     266
     267Memory { component_id, memory_type, memory_speed, memory_capacity, memory_modules }
     268
     269Storage { component_id, storage_type, storage_capacity, storage_form_factor }
     270
     271Power_Supply { component_id, power_supply_type, power_supply_capacity, power_supply_form_factor }
     272
     273Motherboard { component_id, motherboard_socket, motherboard_chipset, motherboard_form_factor, motherboard_ram_type, motherboard_num_ram_slots, motherboard_max_ram_capacity, motherboard_pci_express_slots }
     274
     275Pc_Case { component_id,  pc_case_coooler_max_height, pc_case_gpu_max_length }
     276
     277Cooler { component_id, cooler_type, cooler_height, cooler_max_tdp_supported }
     278
     279Memory_Card { component_id, memory_card_num_slots, memory_card_interface }
     280
     281Optical_Drive { component_id, optical_drive_form_factor, optical_drive_type, optical_drive_interface, optical_drive_write_speed, optical_drive_read_speed }
     282
     283Sound_Card { component_id, sound_card_sample_rate, sound_card_bit_depth, sound_card_chipset, sound_card_interface, sound_card_channel }
     284
     285Cables { component_id, cables_length_cm, cables_type }
     286
     287Network_Adapter { component_id, network_adapter_wifi_version, network_adapter_interface, network_adapter_num_antennas }
     288
     289Network_Card { component_id, network_card_num_ports, network_card_speed, network_card_interface }
     290
     291Pc_Case_Storage_Form_Factor { component_id,  pc_case_storage_form_factor , num_slots }
     292
     293Pc_Case_Ps_Form_Factor { component_id, pc_case_ps_form_factor }
     294
     295Pc_Case_Mobo_Form_Factor { component_id, pc_case_mobo_form_factor }
     296
     297Cooler_Cpu_Socket { component_id, cooler_cpu_socket }
     298
     299Build { build_id, user_id, build_name, build_created_at, build_description, build_total_price, build_is_approved }
     300
     301Build_Component { build_id, component_id, num_components }
     302
     303Rating_Build { build_id, user_id, rating_build_value }
     304
     305Favorite_Build { build_id, user_id }
     306
     307Review { review_id, build_id, user_id, review_content, review_created_at }
     308
     309Suggestion { suggestion_id, user_id, suggestion_admin_id, suggestion_link, suggestion_admin_comment, suggestion_description, suggestion_status, suggestion_component_type }
     310
     311For better contextualization we will add the Admins table which is just a specialization of Users, that has admin_id which references user_id in Users.
     312
     313Admins { admin_id } - BCNF
     314
     315
     316
     317
     318
     319
     320