字符串的阵列(与GIN索引)相对于分离行之间进行选择(B树索引)

问题描述 投票:0回答:1

我有其存储柱receiver的数据库,以表示该数据涉及(例如“查理”)的帐户。这然而导致吨数据的复制的,作为一组数据的可产生3个单独的行,其中所述唯一的区别是receiver柱。

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

而重新设计数据库中,我使用具有GIN索引,而不是在接收机当前B树索引的阵列考虑。我提出了新的表是这样的:

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

所有查询的95%,目前的形式是:SELECT * FROM table WHERE Receiver = Alpha

此外,该表目前包含超过4个十亿行,这将削减下来,以在2个十亿行。

哪种选择更有效?

database postgresql database-design data-modeling
1个回答
0
投票

你不应该使用数组,而是一个标准化的数据模型,其中eventreceiver是两个不同的表。表之间的关系应该通过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 */;
© www.soinside.com 2019 - 2024. All rights reserved.