使用查找避免 Postgres 中的重复数据 Table

Avoid Duplicate Data in Postgres with Lookup Table

如果我有一个 table 的已安装设备带有 make 和 model,其中 make 和 model 会重复很多,但有各种拼写等,如何避免浪费的最佳方法space 来自数据重复?

CREATE TABLE equipment (
    id integer NOT NULL,
    make character varying(128),
    model character varying(128),
    lat double precision,
    lon double precision,
    created timestamp without time zone,
    updated timestamp without time zone
);

这个table在现实中有更多的字段,将有数百万行,我还有其他table处于类似情况,总计约600 GB的数据。

源数据需要保持不变(即 "Panasonic" 和 "PANASONIC" 不能合并/更正),而且数据的规模和多样性无论如何都不切实际。

我正在设想一个单独的 key:value table 来存储值,然后 ID 仅存储在设备中 table,具有我仅传递值的功能它 return 是 ID(无论是查找它并 return 是 ID 还是插入它并 return 是新 ID)。

这将使 table 变成:

CREATE TABLE equipment (
    id integer NOT NULL,
    make integer,
    model integer,
    lat double precision,
    lon double precision,
    created timestamp without time zone,
    updated timestamp without time zone
);

CREATE TABLE lookup (
    id integer NOT NULL,
    value character varying(128),
    updated timestamp without time zone
);

与 table 的互动将是:

SELECT
    id,
    lookup_value(make) AS make,
    lookup_value(model) AS model,
    lat,
    lon,
    created,
    updated
FROM
    equipment

INSERT INTO
    equipment (id, make, model, created)
VALUES
    (nextval('equipment_id_seq'::regclass), lookup_value('Panasonic'), lookup_value('ABC123-G'), NOW()) 

查找 table 可以在各种字段和 table 之间重复使用,每个字符串值只出现一次,而 key:value 永远保持不变(从"Panasonic" 和 "PANASONIC" 不会更改 "Panasonic" 的密钥,而是 return "PANASONIC" 的密钥,如果需要则插入)。

这种方法有什么问题(除了代码复杂性)?

有没有更好的方法?

您绝不会想要这样的通用查找 table。一方面,这意味着您不能在两个 "value" 列和 ID 之间创建外键,因为无法停止 Make 最终进入 Model 的条目。

正如@a_horse_with_no_name所说,你最好创建一个模型并制作table,它们之间有FK,然后按照你说的只保存一个新模型或制作如果它还不存在。

我也很想拥有第三列,例如,对于 PANASONIC 的所有可能拼写,您既有他们输入内容的查找行,也有他们可能意思的参考。这将有助于清理未来的数据。例如,当他们输入 "Panasoonic" 时,您可以在 UI "Did you mean Panasonic" 中提出建议。

根据您的需要对我们进行编码,可以是单个更新、存储过程或应用程序代码。