2015-10-16 60 views
0

我有一個產品目錄,每個產品可以有多個子產品版本。我期望構建數據庫以便有效地在兩個模型中進行搜索。構造用於子查詢的Postgres DB

用戶可以搜索通過:

  • 關鍵字映射到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.第二,什麼是設置搜索的好方法?

例如,如果用戶想要找到匹配關鍵字「貓王」和是大小「王」,所有的產品,它會採取類似的形式:

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 

但我不確定什麼是最好的(或強有力的)實施。

回答

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'會得到與搜索'Elvis'不同的結果。解決這個問題的一個方法就是有額外的字段,當然,這些字段是其他字段的大寫或小寫版本。你不想這樣做:

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

它會太慢。

+1

'ilike'會比'like'慢嗎? – tyler

+0

如果'LIKE'能夠使用一個索引,那麼'ILIKE'只會比較慢。 'LIKE'只能使用'p.title LIKE'elvis%'的索引,在類似表達式開始處使用'LOWER'或'%'將停止使用'LIKE'的索引。 – Eelke

+0

[PostgreSQL支持表達式上的索引](http://www.postgresql.org/docs/9.4/static/indexes-expressional.html)。 –