简体   繁体   中英

Structuring Postgres DB for subqueries

I have a product catalog, and each product can have several subproduct variations. I'm looking to structure the database to allow for searching across both models efficiently.

Users can search by:

  • keywords, mapped to product.search_ts_vector (title + content) and subproduct.search_ts_vector (subtitle + subcontent)
  • material
  • price

The (simplified) product model looks like this:

+----+----------------+-----------------+------------------+
| 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      | ...              |
+----+----------------+-----------------+------------------+

And the (simplified) subproduct model is like so:

+----+------------+----------------+-------------+-------+-------+------------------+
| 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. First off, is this a good DB structure for these needs?

  • Does the product/subproduct relationship make sense?
  • Size can be all over the map -- does it make sense to have a separate table of sizes?
  • Should categorization play a part on sizing, or treat it like text search?

2. Second, what is a good approach to setting up searches?

For example, if a user wants to find all products that match the keyword "Elvis Presley" and are size "king", it would take a form like:

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

But I am unsure of what the best (or a strong) implementation would be.

Your structure seems ok. Your sample query looks more complicated than necessary. I think all you need is:

 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
 )

The one thing that might get you is case sensitivity. Searching on 'elvis' will give different results than searching on 'Elvis'. One way around this is to have extra fields, indexed of course, that are upper or lower case versions of the other fields. You don't want to do this:

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

It will be too slow.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM