为子查询构造Postgres DB

时间:2015-10-16 19:03:42

标签: sql postgresql search

我有一个产品目录,每个产品可能有几个子产品变化。我希望构建数据库以便有效地在两个模型中进行搜索。

用户可以搜索:

  • 关键字,映射到product.search_ts_vector(标题+内容)和subproduct.search_ts_vector(字幕+子内容)
  • 材料

(简化)product模型如下所示:

+----+----------------+-----------------+------------------+
| id | title          | content         | search_ts_vector |
+----+----------------+-----------------+------------------+
| 1  | Suede shoe     | It's a zapato   | ...              |
| 2  | Bed frame      | It's a cama     | ...              |
| 3  | Elvis figurine | It's Elvis      | ...              |
+----+----------------+-----------------+------------------+

(简化的)subproduct模型就像这样:

+----+------------+----------------+-------------+-------+-------+------------------+
| id | product_id | subtitle       | subcontent  | size  | price | search_ts_vector |
+----+------------+----------------+-------------+-------+-------+------------------+
| 1  | 1          | Red suede shoe | Elvis-ish   | 12    | 7999  | ...              |
| 2  | 2          | Queen bed      | Elizabethan | queen | 18999 | ...              |
| 3  | 2          | King bed       | Elvis-ish   | king  | 20999 | ...              |
| 4  | 3          | null           | null        | king  | 999   | ...              |
+----+------------+----------------+-------------+-------+-------+------------------+

1。首先,这是否是满足这些需求的良好数据库结构?

  • 产品/子产品关系是否有意义?
  • 大小可以遍布地图 - 有一个单独的大小表是否有意义?
  • 分类是否应该在调整大小时起作用,或者将其视为文本搜索?

2。第二,设置搜索的好方法是什么?

例如,如果用户想要找到所有符合关键字" Elvis Presley"并且大小"国王",它将采取如下形式:

select
    p.title,
    p.content,
    (select
        sp.subtitle,
        sp.price
     from
        subproducts sp
     where
        sp.product_id = p.id
    )
from
    products p
        join subproducts sp

但我不确定最佳(或强大)实施是什么。

1 个答案:

答案 0 :(得分:0)

你的结构似乎没问题。您的示例查询看起来比必要的复杂。我想你所需要的只是:

 select yourFields
 from products p join subproducts sp on p.id = sp.product_id
 where size = 'King'
 and (
 p.title like '%elvis%'
 or sp.title like '%elvis%'
 etc
 )

可能会让你感到有一点是区分大小写。在' elvis'上搜索与搜索“猫王”相比,会得到不同的结果。解决此问题的一种方法是使用额外的字段,当然,索引是其他字段的大写或小写版本。你不想这样做:

where lower(p.title) like '%elvis%'

太慢了。