Выбор между Array of String (с индексом GIN) и Split Rows (индекс B-Tree) - PullRequest
0 голосов
/ 02 февраля 2019

У меня есть база данных, в которой хранится столбец receiver, чтобы указать учетную запись, к которой относятся данные (например, «Чарли»).Это, однако, привело к множеству дублирования данных, так как один набор данных может создать 3 отдельные строки, где единственным отличием является столбец receiver.

|---------------------|------------------||---------------------|------------------|
|      Receiver       |       Event      ||         Date        |     Location    |
|---------------------|------------------||---------------------|------------------|
|       Alpha         |         3        ||          12         |         USA       |
|---------------------|------------------||---------------------|------------------|
|       Bravo         |         3        ||          12         |         USA       |
|---------------------|------------------||---------------------|------------------|
|       Charlie       |         3        ||          12         |         USA       |
|---------------------|------------------||---------------------|------------------|

При изменении базы данных я рассмотрелиспользование массива с индексом GIN вместо текущего индекса B-Tree на приемнике.Моя предлагаемая новая таблица будет выглядеть следующим образом:

|-------------------------------|------------------||------------------|-------------------|
|           Receivers           |       Event      ||      Date        |     Location      |
|-------------------------------|------------------||------------------|-------------------|
| ["Alpha", "Bravo", "Charlie"] |         3        ||       12         |         USA       |
|-------------------------------|------------------||------------------|-------------------|

95% всех запросов в настоящее время имеют вид: SELECT * FROM table WHERE Receiver = Alpha

Кроме того, таблица в настоящее время содержит более 4 млрд.строк, и это сократило бы его до 2 миллиардов строк.

Какой вариант более эффективен?

1 Ответ

0 голосов
/ 04 февраля 2019

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

Таблицы будут выглядеть следующим образом:

CREATE TABLE occurrence (
   occurrence_id bigint PRIMARY KEY,
   event integer NOT NULL,
   date integer NOT NULL,
   location text NOT NULL
);

CREATE TABLE receiver (
   receiver_id bigint PRIMARY KEY,
   receiver_name text NOT NULL
);

CREATE TABLE log_entry (
   occurrence_id bigint NOT NULL REFERENCES occurrence,
   receiver_id   bigint NOT NULL REFERENCES receiver,
   PRIMARY KEY (occurrence_id, receiver_id)
);

Запись журнала ссылается на событие и получателя.

Вы бы запросили как

SELECT r.receiver_name,
       o.event,
       o.date,
       o.location
FROM occurrence AS o
   JOIN log_entry AS l USING (occurrence_id)
   JOIN receiver AS r USING (receiver_id)
WHERE /* your conditions */;
...