Вычисленные поля Hasura против Postgres сгенерированных столбцов против Postgres просмотров - PullRequest
1 голос
/ 26 мая 2020

Мы внедряем модель данных электронной коммерции и пытаемся выбрать между Postgres сгенерированными столбцами, вычисленными полями Hasura и Postgres представлениями.

В качестве упрощения у нас есть две таблицы:

items
------------
id
order_id
unit_price
quantity

orders
------------
id

Теперь мы хотим добавить total_price в таблицу items (unit_price * quantity) и total_price в заказы (sum из total_price из всех items в заказе ).

В первом случае мы использовали сгенерированный столбец Postgres. Преимущество здесь заключается в том, что он создается один раз и сохраняется, а не повторно запускается для каждого запроса, как это было бы с вычисляемым полем Hasura.

Это правильный выбор?

items
------------
id
order_id
unit_price
quantity
total_price : Postgres generated column : (unit_price * quantity)

CREATE TABLE orders (
    ...,
    total_price integer GENERATED ALWAYS AS (unit_price * quantity) STORED
);

Во втором случае мы не можем использовать сгенерированный столбец, поскольку он не может ссылаться на поля из другой таблицы.

Вместо этого мы можем решить эту проблему с помощью вычисляемого поля Hasura:

orders
------------
id
total_price : Hasura computed field : SUM(items.total_price)

CREATE FUNCTION calculate_order_total_price(orders_row orders)
RETURNS INTEGER AS $$
    SELECT CAST(SUM(total_price) AS INTEGER)
      FROM items
     WHERE order_id = orders_row.id
$$ LANGUAGE sql STABLE;

В качестве альтернативы, мы можем создать Postgres представление:

vw_orders
------------
orders.id
total_price : SELECT SUM(items.total_price)

CREATE VIEW vw_orders AS 
    SELECT orders.id,
        (SELECT sum(items.total_price) AS sum
           FROM items
          WHERE (items.order_id = orders.id)) AS total_price
        FROM orders;

Решение вычисляемого поля Hasura имеет тот недостаток, что total_price отображается только в запросах GraphQL, поэтому мы не можем использовать его в SQL .

Решение для просмотра Postgres, на первый взгляд, не вызывает никаких проблем.

Мы что-то упускаем?

Зачем вообще использовать вычисленный Hasura Postgres сгенерированных полей или представлений?

Есть ли где-нибудь сравнительная таблица или блок-схема, которые помогли бы нам решить, какой подход лучше всего в каждой конкретной ситуации?

Наконец, для всех эти, мы можно, конечно, также использовать Postgres триггеры, триггеры событий Hasura и действия Hasura ... когда это будут подходящие решения?

Ура!

1 Ответ

0 голосов
/ 26 мая 2020

Для этого конкретного случая c я бы использовал go с представлением PostgreSQL, потому что требуемые вычисления довольно дешевые (однократное умножение). Возможно даже, что экономия места для хранения и результирующий выигрыш в скорости при последовательном сканировании перевешивают обратную сторону необходимости выполнять вычисления всякий раз, когда требуется значение. Последние версии PostgreSQL также могут использовать JIT-компиляцию, чтобы удешевить вычисление таких выражений (для более крупных запросов).

Вообще говоря, лучшая стратегия, вероятно, будет зависеть от вычислительной интенсивности выражение. Если это высокое значение, и строки чаще читаются, чем записываются, вероятно, имеет смысл использовать сгенерированный столбец.

Вы можете запустить небольшой тест и изучить разницу. В вашем случае я не думаю, что влияние будет очень сильным, и, возможно, лучше выбрать наиболее простую или удобочитаемую реализацию, поскольку это улучшает ремонтопригодность.

...