Как использовать Sphinx для поиска больших таблиц JOINed? - PullRequest
2 голосов
/ 11 декабря 2011

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

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

Я бы хотел иметь возможность запрашивать у Сфинкса ответы на такие вопросы, как:

  • Сколько людей, живущих на улице под названием «Клен», заказали предмет с «большим» в описании?
  • Какие заказы содержат слово "синий" в описании коробки или в описании товара?

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

Пример базы данных

CREATE TABLE orders (
    id               integer PRIMARY KEY,
    date_ordered     date,
    customer_po      varchar
);
INSERT INTO orders VALUES (1, '2012-12-13', NULL);
INSERT INTO orders VALUES (2, '2012-12-14', 'DF312442');

CREATE TABLE parties (
    id               integer PRIMARY KEY,
    order_id         integer NOT NULL REFERENCES orders(id),
    party_type       varchar,
    company          varchar,
    city             varchar,
    state            char(2)
);
INSERT INTO parties VALUES (1, 1, 'shipper', 'ACME, Inc.', 'New York', 'NY');
INSERT INTO parties VALUES (2, 1, 'recipient', 'Wylie Coyote Corp.', 'Flagstaff', 'AZ');
INSERT INTO parties VALUES (3, 2, 'shipper', 'Cyberdyne', 'Las Vegas', 'NV');
-- Please disregard the fact that this design permits multiple shippers and multiple recipients
-- per order.  This is a vastly simplified version of the system I'm working on.

CREATE TABLE boxes (
    id               integer PRIMARY KEY,
    order_id         integer NOT NULL REFERENCES orders(id),
    tracking_num     varchar NOT NULL,
    description      varchar NOT NULL,
);
INSERT INTO boxes VALUES (1, 1, '1234567890', 'household goods');
INSERT INTO boxes VALUES (2, 1, '0987654321', 'kitchen appliances');
INSERT INTO boxes VALUES (3, 2, 'ABCDE12345', 'audio equipment');

CREATE TABLE box_contents (
    id               integer PRIMARY KEY,
    order_id         integer NOT NULL REFERENCES orders(id),
    box              integer NOT NULL REFERENCES boxes(id),
    qty_units        integer,
    description      varchar
);
INSERT INTO box_contents VALUES (1, 1, 1, 4, 'cookbook');
INSERT INTO box_contents VALUES (2, 1, 1, 2, 'baby bottle');
INSERT INTO box_contents VALUES (3, 1, 2, 1, 'television');
INSERT INTO box_contents VALUES (4, 2, 3, 2, 'lamp');

1 Ответ

4 голосов
/ 12 декабря 2011

Вы помещаете JOIN в sql_query, который строит индекс.Таблицы остаются нормализованными, но вы денормализуетесь при построении индекса.

Это только базовый пример, но ваш запрос будет выглядеть примерно так ...Затем Sphinx выполняет процесс соединения для вас

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...