我的数据库中有几个不同的表,我试图使用Sphinx进行快速全文搜索。为了便于讨论,让我们说感兴趣的主要记录是装箱单,其中一个包含在订单发货时。如何在不完全非规范化数据库的情况下使用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');
答案 0 :(得分:4)
将JOIN放在构建索引的sql_query中。表保持规范化,但在构建索引时进行非规范化。
它只是一个基本的例子,但你的查询会像.. ..
sql_query = SELECT o.id,customer_po,UNIX_TIMESTAMP(date_ordered) AS date_ordered, \
GROUP_CONCAT(DISTINCT party_type) AS party_type, \
GROUP_CONCAT(DISTINCT company) AS company, \
GROUP_CONCAT(DISTINCT city) AS city, \
GROUP_CONCAT(DISTINCT description) AS description \
FROM orders o \
INNER JOIN parties p ON (o.id = p.order_id) \
INNER JOIN box_contents b ON (o.id = b.order_id) \
GROUP BY o.id \
ORDER BY NULL
更新:或者可以使用sql_joined_field来做同样的事情但避免实际的sql_query连接。然后Sphinx为您做加入过程