Мое решение по итогу:
Использование атрибутов трех типов
int (и date сюда же)
float
string (сюда же идентификаторы из других таблиц, обеспечение ссылочной целостности на уровне приложения )
CREATE TABLE "public"."products_attributes" (
"id" int8 NOT NULL DEFAULT unique_rowid(),
"product_id" int8 NOT NULL,
"attribute_id" int8 NOT NULL,
"value_int" int8,
"value_float" numeric,
"value_string" text,
PRIMARY KEY ("id")
);
---
SELECT
"products"."id"
FROM
"products"
INNER JOIN products_attributes t1 ON products.id = products_attributes.product_id
INNER JOIN products_attributes t2 ON products.id = products_attributes.product_id
WHERE
"t1"."attribute_id" = 733698711938367489
AND "t1"."value_string" IN ('425618460007989249')
AND "t2"."attribute_id" = 733699190507405313
AND "t2"."value_int" >= 2020
Индексы
BTREE attribyte_id, value_string
BTREE attribyte_id, value_int
BTREE attribyte_id, value_float
BTREE product_id
BTREE product_id, attribyte_id