Избегайте дублирования данных в Postgres с таблицей поиска - PullRequest
0 голосов
/ 13 февраля 2019

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

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
);

В этой таблице гораздо больше полей, и в ней будет много миллионов строк, и у меня есть другие таблицы в аналогичной ситуации с общим объемом данных около 600 ГБ.

Исходные данныедолжно быть одинаковым (т. е. «Panasonic» и «PANASONIC» не могут быть объединены / исправлены), а масштаб и разнообразие данных делают это непрактичным в любом случае.

Я предполагаю отдельноеТаблица key: value, в которой хранятся значения, а затем идентификатор просто сохраняется в таблице оборудования, с функцией, в которой я просто передаю значение, и оно возвращает идентификатор (независимо от того, просматривает ли он его, возвращает ли идентификатор или вставляет его и возвращаетновый идентификатор).

Это приведет к тому, что таблицы станут:

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
);

И взаимодействие с таблицей будет:

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()) 

таблица поиска может быть повторно использована в различных полях и таблицах, при этом каждое строковое значение появляется только один раз, а ключ: значение остается неизменным навсегда (изменение «Panasonic» и «PANASONIC» не изменит ключ для «Panasonic», вместо этого он вернул бы ключ для «PANASONIC», вставив при необходимости).

Какие проблемы возникают у этого подхода (кроме сложности кода)?

Есть ли лучший подход?

1 Ответ

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

Вы никогда не захотите иметь общую таблицу поиска, подобную этой.Для одного это означает, что вы не можете создать внешний ключ между двумя столбцами «value» и идентификаторами, потому что нет способа остановить запись для Make, попавшего в Model.

Как сказал @a_horse_with_no_name, вам лучше создать модель и создать таблицу с FK между ними, а затем делать, как вы говорите, только сохранение новой модели или ее создание, если она еще не существует..

Мне также хотелось бы иметь третий столбец, поэтому для всех возможных вариантов написания для PANASONIC, например, у вас есть и строка поиска для того, что они ввели, и ссылка на то, что они, вероятно, имели в виду.Это поможет в очистке данных в будущем.Например, вы можете указать в пользовательском интерфейсе «Вы имели в виду Panasonic», когда они вводят «Panasoonic».

Кодирование нас до вас, либо в одном обновлении, либо в сохраненном протоколе, либо в коде приложения.

...