简体   繁体   中英

database design: best way to store multiple options with multiple selects

So i am trying to determine what is the best way to do this: I will try to make this as simple as possible but give enough info

I have a database with a large dataset. for this example each car is a car that someone is looking for

i have a table:

CREATE TABLE cars (
`car_id` INT(10),
`car_name` VARCHAR(20)
)  

and options table like

CREATE TABLE `car_selected_options` (
`car_sel_id`   INT       NOT NULL AUTO_INCREMENT,
`car_id`       INT       //the id of the car record created
`value`        INT       //id of info in a ref table
`key`          VARCHAR(20)   //from the car_option_reference,
)

some examples would be: the value is the id of more info in a ref table(note two electronics)

car_id=1, value='10',    key='exterior_color'  10='red'
car_id=1, value='21',    key='interior_color'  21='blue' 
car_id=1, value='100',   key='electronics'     100='radio'
car_id=1, value='101',   key='electronics'     101='nav'

I need to find all the car id's that are red and have nav and radios i am doing something like:

SELECT distinct(c.car_id)
FROM `car` c 
   INNER JOIN `car_selected_options` AS o ON c.car_id = o.car_id
WHERE 
o.car_sel_id IN 
        ( SELECT car_sel_id 
            FROM car_selected_options so 
            WHERE so.`key` = 'exterior_color' 
              AND so.value IN ('10' ) AND b.buyer_id = bm.buyer_id )
    AND
o.car_sel_id IN 
        ( SELECT car_sel_id 
            FROM car_selected_options so 
            WHERE so.`key` = 'electronics'  
              AND so.value IN ('100','101' ) AND b.buyer_id = bm.buyer_id )

or would it be better to instead of having the keys and everthing in one table have each key.option with separate tables for each thing like:

car_exterior_color (could have one entry per car or multiples if this person is ok with a red or a blue colored car)
car_interior_color 
car_electronics

and instead of doing these multiple sub selects (could be many) , do multiple inner joins?

I hope this makes sense thanks for any help

There seems to be something missing from the query you posted because I don't see what the "b" and "bm" tables are. Ignoring that clause, you can greatly simplify your query without doing multiple subselects:

SELECT c.car_id
FROM `car` c 
   INNER JOIN `car_selected_options` AS o ON c.car_id = o.car_id
WHERE 
   (o.key = 'exterior_color' AND o.value = 10) OR
   (o.key = 'electronics' AND o.value = 100) OR
   (o.key = 'electronics' AND o.value = 101) OR
GROUP BY c.car_id
HAVING COUNT(*) = 3;

The "3" in this case is the number of criteria you are applying. The trick here is that for each matching car you should have exactly three matching rows, so if you group by car_id, and filter by count(*) = 3 you will select only the cars that match on ALL criteria.

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