0

我不知道如何在 sql 中解决这个问题:

表广告:

ad_id
ad_title
ad_type_id

.... 表 ADS_DATA:

ad_data_id
ad_id
ad_data_name
ad_data_value

好的,让我们试着让它变得简单:表 ADS 存储类型为 ad_type_id 的对象的公共数据。表 ADS_DATA 根据其 ad_type_id 存储对象的额外数据。

ADS_DATA.ad_data_name 存储数据的名称(在普通表中将是列名),ADS_DATA.ad_data_value 存储此数据的值。根据 ad_type_id,ADS_DATA 表填充了特定的 ad_data_name 值。例如:

ADS
ad_id = 1,ad_type_id = 2
ad_id = 2,ad_type_id = 3
ADS_DATA
ad_data_id = 1,ad_id = 1,ad_data_name = 'rooms',ad_data_value = 2
ad_data_id = 2,ad_id = 1,ad_data_name = 'size',ad_data_value = 20
ad_data_id = 3,ad_id = 2,ad_data_name = 'fingers',ad_data_value = 15
ad_data_id = 4,ad_id = 2,ad_data_name = 'toes',ad_data_value = 5

好的,我如何从具有特定 ad_id 的 ADS_DATA 中获取所有行(每一行,尽管其名称或值)以及(ad_data_name = x 和 ad_data_value = y)AND(ad_data_name = x1 和 ad_data_value = y2)AND ...

我知道这是一个huuuugge混乱,但感谢阅读!

更新:这是一个例子:我试图建立一个不同类别的广告系统(ADS.ad_type_id)。根据您选择的广告类型,ads_data 表会填充此类别的特定数据,例如:AD 房屋类别,ads_data 表中将包含:rooms,size,baths,...。我可以创建一个 ads_data 表列包含每个类别的所有可能数据的名称,并且只填写我需要的那些,但我认为这是一种浪费,所以决定创建一个包含列的表:

ad_data_id        UNIQUE ID
ad_id             REFERENCE TO ADS.ad_id
ad_data_name      for the "column name",e.g: house_rooms
ad_data_value     for the value.

INSTEAD OF A "NORMAL" RELATION:
ad_data_id        UNIQUE ID
ad_id             REFERENCE TO ADS.ad_id
house_rooms       ad data,only fill columns relative to choseen category(e.g:house_)
house_size
house_baths
car_engine
car_hp
car_year
...

我想通过 ADS 表搜索(例如按广告价格过滤(这是所有广告的通用数据,所以它在 ADS 表中,而不是 ADS_DATA),然后只获取具有的行,例如:(house_rooms BETWEEN X AND Y) AND (house_size BETWEEN A AND B)。在 ADS_DATA 列之间,我需要一个“AND”而不是“OR”。您认为制作“NORMAL”表是否更好(并且可能是唯一的方法)并且只填写每个类别我需要的列?

谢谢

更新:虽然有很多谷歌建议不要使用键/值对,但我发现,尽管性能受到影响,但这里有一个解决方案: 需要一个 MySQL 查询来从存储键值对的表中进行选择

4

2 回答 2

0

我想你有点回答了你自己的问题。子选择似乎适用于此...

SELECT * FROM ADS_DATA WHERE ad_id IN (
    SELECT DISTINCT ad_id FROM ADS_DATA 
    WHERE 
        (ad_data_name = 'Foo' AND ad_data_value = 'Bar') 
    OR 
        (ad_data_name = 'Fizz' AND ad_data_value = 'Buzz')
)

不过,您的架构似乎可以进行规范化。在关系数据库中存储键/值对有点浪费。

于 2012-10-15T16:40:04.463 回答
0

这假设您不会有相同的重复行ad_data_namead_data_value给定的值ad_id

select a.*
from ADS_DATA a
inner join (
    select ad_id
    from ADS_DATA
    and (
        (ad_data_name = 'rooms' and ad_data_value = 2) 
        or (ad_data_name = 'size' and ad_data_value = 20)
    ) 
    group by ad_id
    having count(*) = 2
) am on a.ad_id = am.ad_id
where a.ad_id = 1
于 2012-10-15T16:36:03.220 回答