| Version 11 (modified by , 6 days ago) ( diff ) |
|---|
Normalization
Initial de-normalized relation and functional dependencies
Attributes with identical names originating from different relations were renamed using entity-based prefixes in order to avoid duplicate attribute names in the universal relation.
R(user_id, username, password, email, component_id, component_name, brand, component_price, component_type, 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, pc_case_storage_form_factor, num_slots pc_case_ps_form_factor, pc_case_mobo_form_factor, cooler_type, cooler_height, cooler_max_tdp_supported, cooler_cpu_socket, 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_id, build_name, build_created_at, build_description, build_total_price, build_is_approved, num_components, rating_build_value, review_id, review_content, review_created_at, suggestion_id, suggestion_admin_id, suggestion_link, suggestion_admin_comment, suggestion_description, suggestion_status, suggestion_component_type)
Before 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.
Now 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.
FD1: user_id -> username, password, email
FD2: component_id -> component_name, brand, component_price, component_type, img_url
FD3: component_id(cpu) -> cpu_socket, cpu_cores, cpu_threads, cpu_base_clock, cpu_boost_clock, cpu_tdp
FD4: component_id(gpu) -> gpu_vram, gpu_tdp, gpu_base_clock, gpu_boost_clock, gpu_chipset, gpu_length
FD5: component_id(memory) -> memory_type, memory_speed, memory_capacity, memory_modules
FD6: component_id(storage) -> storage_type, storage_capacity, storage_form_factor
FD7: component_id (power_supply) -> power_supply_type, power_supply_capacity, power_supply_form_factor
FD8: 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
FD9: component_id(pc_case) -> pc_case_coooler_max_height, pc_case_gpu_max_length
FD10: component_id(cooler) -> cooler_type, cooler_height, cooler_max_tdp_supported
FD11: component_id(memory_card) -> memory_card_num_slots, memory_card_interface
FD12: component_id(optical_drive) -> optical_drive_form_factor, optical_drive_type, optical_drive_interface, optical_drive_write_speed, optical_drive_read_speed
FD13: component_id(sound_card) -> sound_card_sample_rate, sound_card_bit_depth, sound_card_chipset, sound_card_interface, sound_card_channel
FD14: component_id(cables) -> cables_length_cm, cables_type
FD15: component_id(network_adapter) -> network_adapter_wifi_version, network_adapter_interface, network_adapter_num_antennas
FD16: component_id(network_card) -> network_card_num_ports, network_card_speed, network_card_interface
FD17: build_id -> user_id, build_name, build_created_at, build_description, build_total_price, build_is_approved
FD18: build_id, component_id -> num_components
FD19: build_id, user_id -> /
FD20: build_id, user_id -> rating_build_value
FD21: review_id -> build_id, user_id, review_content, review_created_at
FD22: suggestion_id -> user_id, suggestion_admin_id, suggestion_link, suggestion_admin_comment, suggestion_description, suggestion_status, suggestion_component_type
Left: user_id, component_id, build_id, review_id, suggestion_id
Left and right: build_id, user_id
Right: username, 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
Attributes 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.
Let K = { component_id, review_id, suggestion_id }
We now compute the closure K+
Start with K+ = { component_id, review_id, suggestion_id }
By applying FD2 – FD16, we add: component_name, brand, component_price, component_type, 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, 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
By applying FD21, we add: build_id, user_id, review_content, review_created_at
By applying FD17, we add: build_name, build_created_at, build_description, build_total_price, build_is_approved
By applying FD1, we add: username, password, email
By applying FD22, we add: suggestion_admin_id, suggestion_link, suggestion_admin_comment, suggestion_description, suggestion_status, suggestion_component_type
By applying FD18 and FD20, we add: num_components, rating_build_value
After excluding multivalued attributes which we handle separatelu in 1NF, K+ contains all attributes of R, which means that K is a superkey.
The 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.
1NF Decomposition
To achieve 1NF, we decompose the multivalued attributes from R into:
component_id , pc_case_storage_form_factor -> num_slots
component_id, pc_case_ps_form_factor -> no non-key attributes
component_id, pc_case_mobo_form_factor -> no non-key attributes
component_id, cooler_cpu_socket -> no non-key attributes
1NF is satisfied now. 2NF is not satisfied because of partial dependencies. We can see this through the functional dependencies:
FD2-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.
We will decompose by creating new relations from R following FD2 to FD16 where the attributes will depend only on component_id:
component_id -> component_id, component_name, brand, component_price, component_type, img_url
component_id -> cpu_socket, cpu_cores, cpu_threads, cpu_base_clock, cpu_boost_clock, cpu_tdp
component_id -> gpu_vram, gpu_tdp, gpu_base_clock, gpu_boost_clock, gpu_chipset, gpu_length
component_id -> memory_type, memory_speed, memory_capacity, memory_modules
component_id -> storage_type, storage_capacity, storage_form_factor
component_id -> power_supply_type, power_supply_capacity, power_supply_form_factor
component_id -> motherboard_socket, motherboard_chipset, motherboard_form_factor, motherboard_ram_type, motherboard_num_ram_slots, motherboard_max_ram_capacity, motherboard_pci_express_slots
component_id -> pc_case_coooler_max_height, pc_case_gpu_max_length
component_id -> cooler_type, cooler_height, cooler_max_tdp_supported, cooler_cpu_socket
component_id -> memory_card_num_slots, memory_card_interface
component_id -> optical_drive_form_factor, optical_drive_type, optical_drive_interface, optical_drive_write_speed, optical_drive_read_speed
component_id -> sound_card_sample_rate, sound_card_bit_depth, sound_card_chipset, sound_card_interface, sound_card_channel
component_id -> cables_length_cm, cables_type
component_id -> network_adapter_wifi_version, network_adapter_interface, network_adapter_num_antennas
component_id -> network_card_num_ports, network_card_speed, network_card_interface
Primary key in all of these is component_id.
FD21: review_id is part of the key, but these attributes build_id, user_id, review_content, review_created_at depend only on review_id.
We will solve this partial dependency by creating a new relation:
review_id -> build_id, user_id, review_content, review_created_at
Primary key here is review_id.
FD22: 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.
We will solve this partial dependency by creating a new relation:
suggestion_id -> user_id, suggestion_admin_id, suggestion_link, suggestion_admin_comment, suggestion_description, suggestion_status, suggestion_component_type
We get the following relations:
R1 { review_id, build_id, user_id, review_content, review_created_at } where PK = review_id - BCNF
R2 { suggestion_id, user_id, suggestion_admin_id, suggestion_link, suggestion_admin_comment, suggestion_description, suggestion_status, suggestion_component_type } where PK = suggestion_id - BCNF
R3 { component_id, component_name, brand, component_price, component_type, img_url } where PK = component_id - BCNF
R4 { component_id, cpu_socket, cpu_cores, cpu_threads, cpu_base_clock, cpu_boost_clock, cpu_tdp } where PK = component_id - BCNF
R5 { component_id, gpu_vram, gpu_tdp, gpu_base_clock, gpu_boost_clock, gpu_chipset, gpu_length } where PK = component_id - BCNF
R6 { component_id, memory_type, memory_speed, memory_capacity, memory_modules } where PK = component_id - BCNF
R7 { component_id, storage_type, storage_capacity, storage_form_factor } where PK = component_id - BCNF
R8 { component_id, power_supply_type, power_supply_capacity, power_supply_form_factor } where PK = component_id - BCNF
R9 { 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
R10 { component_id, pc_case_coooler_max_height, pc_case_gpu_max_length } where PK = component_id - BCNF
R11 { component_id, cooler_type, cooler_height, cooler_max_tdp_supported } where PK = component_id - BCNF
R12 { component_id, memory_card_num_slots, memory_card_interface } where PK = component_id - BCNF
R13 { 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
R14 { component_id, sound_card_sample_rate, sound_card_bit_depth, sound_card_chipset, sound_card_interface, sound_card_channel } where PK = component_id - BCNF
R15 { component_id, cables_length_cm, cables_type } where PK = component_id - BCNF
R16 { component_id, network_adapter_wifi_version, network_adapter_interface, network_adapter_num_antennas } where PK = component_id - BCNF
R17 { component_id, network_card_num_ports, network_card_speed, network_card_interface } where PK = component_id - BCNF
R18 { component_id, pc_case_storage_form_factor , num_slots } where PK = component_id and pc_case_storage_form_factor - BCNF
R19 { component_id, pc_case_ps_form_factor } where PK = component_id and pc_case_ps_form_factor - BCNF
R20 { component_id, pc_case_mobo_form_factor } where PK = component_id and pc_case_mobo_form_factor - BCNF
R21 { component_id, cooler_cpu_socket } where PK = component_id and cooler_cpu_socket - BCNF
The 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)
2NF 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.
3NF decomposition
R22 { user_id, username, password, email } where PK = user_id - BCNF
R23 { build_id, user_id, build_name, build_created_at, build_description, build_total_price, build_is_approved } where PK = build_id – BCNF
Leftover relation R { component_id, review_id, suggestion_id, build_id, user_id, num_components, rating_build_value }
From 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
R24 { build_id , component_id, num_components } where PK = build_id, component_id - BCNF
R25 { build_id, user_id, rating_build_value } where PK = build_id, user_id - BCNF
R26 { build_id, user_id } where PK = build_id, user_id – BCNF
Final BCNF relations
Users { user_id, username, password, email }
Components { component_id, component_name, brand, component_price, component_type, img_url }
Cpu { component_id, cpu_socket, cpu_cores, cpu_threads, cpu_base_clock, cpu_boost_clock, cpu_tdp }
Gpu { { component_id, gpu_vram, gpu_tdp, gpu_base_clock, gpu_boost_clock, gpu_chipset, gpu_length }
Memory { component_id, memory_type, memory_speed, memory_capacity, memory_modules }
Storage { component_id, storage_type, storage_capacity, storage_form_factor }
Power_Supply { component_id, power_supply_type, power_supply_capacity, power_supply_form_factor }
Motherboard { component_id, motherboard_socket, motherboard_chipset, motherboard_form_factor, motherboard_ram_type, motherboard_num_ram_slots, motherboard_max_ram_capacity, motherboard_pci_express_slots }
Pc_Case { component_id, pc_case_coooler_max_height, pc_case_gpu_max_length }
Cooler { component_id, cooler_type, cooler_height, cooler_max_tdp_supported }
Memory_Card { component_id, memory_card_num_slots, memory_card_interface }
Optical_Drive { component_id, optical_drive_form_factor, optical_drive_type, optical_drive_interface, optical_drive_write_speed, optical_drive_read_speed }
Sound_Card { component_id, sound_card_sample_rate, sound_card_bit_depth, sound_card_chipset, sound_card_interface, sound_card_channel }
Cables { component_id, cables_length_cm, cables_type }
Network_Adapter { component_id, network_adapter_wifi_version, network_adapter_interface, network_adapter_num_antennas }
Network_Card { component_id, network_card_num_ports, network_card_speed, network_card_interface }
Pc_Case_Storage_Form_Factor { component_id, pc_case_storage_form_factor , num_slots }
Pc_Case_Ps_Form_Factor { component_id, pc_case_ps_form_factor }
Pc_Case_Mobo_Form_Factor { component_id, pc_case_mobo_form_factor }
Cooler_Cpu_Socket { component_id, cooler_cpu_socket }
Build { build_id, user_id, build_name, build_created_at, build_description, build_total_price, build_is_approved }
Build_Component { build_id, component_id, num_components }
Rating_Build { build_id, user_id, rating_build_value }
Favorite_Build { build_id, user_id }
Review { review_id, build_id, user_id, review_content, review_created_at }
Suggestion { suggestion_id, user_id, suggestion_admin_id, suggestion_link, suggestion_admin_comment, suggestion_description, suggestion_status, suggestion_component_type }
For 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.
Admins { admin_id } - BCNF
