Your thread looks answerable. But first, can you rewrite your thread with this markdown guide? so it is more comprehensive.
Mar 31, 2024
5
Level 1
How to optimize variant_value and attribute_product_value table in e-commerce database ?
By all things about e-commerce I find, I see the database like this:
Table "products" {
"id" UUID [not null, default: `uuid_generate_v4()`]
"slug" TEXT [unique, not null]
"product_name" VARCHAR(255) [not null]
"sku" VARCHAR(255)
"sale_price" NUMERIC [not null, default: 0]
"compare_price" NUMERIC [default: 0]
"buying_price" NUMERIC [default: NULL]
"quantity" INTEGER [not null, default: 0]
"short_description" VARCHAR(165) [not null]
"product_description" TEXT [not null]
"product_type" VARCHAR(64)
"published" BOOLEAN [default: FALSE]
"disable_out_of_stock" BOOLEAN [default: TRUE]
"note" TEXT
"created_at" TIMESTAMPTZ [not null, default: `NOW()`]
"updated_at" TIMESTAMPTZ [not null, default: `NOW()`]
"created_by" UUID
"updated_by" UUID
Indexes {
id [pk]
}
}
Table "product_categories" {
"id" UUID [not null, default: `uuid_generate_v4()`]
"product_id" UUID [not null]
"category_id" UUID [not null]
Indexes {
id [pk]
}
}
Table "product_shipping_info" {
"id" UUID [not null, default: `uuid_generate_v4()`]
"product_id" UUID
"weight" NUMERIC [not null, default: 0]
"weight_unit" VARCHAR(10)
"volume" NUMERIC [not null, default: 0]
"volume_unit" VARCHAR(10)
"dimension_width" NUMERIC [not null, default: 0]
"dimension_height" NUMERIC [not null, default: 0]
"dimension_depth" NUMERIC [not null, default: 0]
"dimension_unit" VARCHAR(10)
Indexes {
id [pk]
}
}
Table "attributes" {
"id" UUID [not null, default: `uuid_generate_v4()`]
"attribute_name" VARCHAR(255) [not null]
"created_at" TIMESTAMPTZ [not null, default: `NOW()`]
"updated_at" TIMESTAMPTZ [not null, default: `NOW()`]
"created_by" UUID
"updated_by" UUID
Indexes {
id [pk]
}
}
Table "attribute_values" {
"id" UUID [not null, default: `uuid_generate_v4()`]
"attribute_id" UUID [not null]
"attribute_value" VARCHAR(255) [not null]
"value" JSON
Indexes {
id [pk]
}
}
Table "product_attributes" {
"id" UUID [not null, default: `uuid_generate_v4()`]
"product_id" UUID [not null]
"attribute_id" UUID [not null]
Indexes {
id [pk]
}
}
Table "product_attribute_values" {
"id" UUID [not null, default: `uuid_generate_v4()`]
"product_attribute_id" UUID [not null]
"attribute_value_id" UUID [not null]
Indexes {
id [pk]
}
}
Table "variant_options" {
"id" UUID [not null, default: `uuid_generate_v4()`]
"title" TEXT [not null]
"image_id" UUID
"product_id" UUID [not null]
"sale_price" NUMERIC [not null, default: 0]
"compare_price" NUMERIC [default: 0]
"buying_price" NUMERIC [default: NULL]
"quantity" INTEGER [not null, default: 0]
"sku" VARCHAR(255)
"active" BOOLEAN [default: TRUE]
Indexes {
id [pk]
}
}
Table "variants" {
"id" UUID [not null, default: `uuid_generate_v4()`]
"variant_option" TEXT [not null]
"product_id" UUID [not null]
"variant_option_id" UUID [not null]
Indexes {
id [pk]
}
}
Table "variant_values" {
"id" UUID [not null, default: `uuid_generate_v4()`]
"variant_id" UUID [not null]
"product_attribute_value_id" UUID [not null]
Indexes {
id [pk]
}
}
Ref:"products"."id" < "product_categories"."product_id"
Ref:"products"."id" < "product_shipping_info"."product_id" [delete: set null]
Ref:"attributes"."id" < "attribute_values"."attribute_id"
Ref:"products"."id" < "product_attributes"."product_id"
Ref:"attributes"."id" < "product_attributes"."attribute_id"
Ref:"product_attributes"."id" < "product_attribute_values"."product_attribute_id"
Ref:"attribute_values"."id" < "product_attribute_values"."attribute_value_id"
Ref:"products"."id" < "variant_options"."product_id"
Ref:"products"."id" < "variants"."product_id"
Ref:"variant_options"."id" < "variants"."variant_option_id"
Ref:"variants"."id" < "variant_values"."variant_id"
Ref:"product_attribute_values"."id" < "variant_values"."product_attribute_value_id"
Ref: "products"."disable_out_of_stock" < "products"."published"
Ref: "variant_options"."id" < "variant_options"."active"
Ref: "product_attributes"."product_id" < "product_attributes"."id"
Ref: "products"."product_type" < "products"."product_name"
But my wonder why they are connect variant_values to product_attribute_values. I think that not necessary to discard the variants_values and product_attribute_values table because the variants table have already the products_id which means we can query by attribute and values either by that.
And if the table functions like that design, I actually will need to insert records to product_attributes_values and variant_values additionally whenever I need to add a product. I think it will be too complex
Do I need to optimize it or not?
Please or to participate in this conversation.