DB:如何设置多个表来处理多个可选条件

时间:2018-04-03 18:12:18

标签: sql sql-server rdbms

我正在开发一个网站的搜索过滤器,可以帮助用户找到满足他们需求的场地(用于聚会和仪式)。过滤器包括以下内容:样式,设施,事件类型等。类别中的多个选项可以应用于场地,因此用户可以在搜索时从样式,设施和事件类型类别中选择多个选项。

我的问题在于我应该如何处理数据库中的表设计。目前我有一个具有唯一ID和基本信息的Venue表,以及表示每个类别(样式,便利设施等)的多个表,其中包含id和name字段。

我知道我需要一个中间表来保存外键,因此适用于某个类别的每个选项都与该地点相关联。

选项1:为每个类别表创建一个多对多的中间表,其中包含该类别和场地的外键。

选项2:为每个类别以及Venue创建一个包含外键的大型中间表 即。

fk_venue

fk_style

fk_amenities

...

我正在尝试决定什么是更高效,而不是编码的问题。选项1需要对每个表进行查询,这可能会变得很复杂,因为选项2似乎更容易查询,但可能有更多的记录来处理具有许多设施和事件类型的场所。

这似乎不是一个新问题,但我很难找到详细说明如何最好地解决这个问题的资源。我们目前正在使用MSSQL作为数据库,并使用.net核心构建网站。

2 个答案:

答案 0 :(得分:0)

选项3:您可以从元数据设计开始。这将允许您为每个项目或实体拥有多个记录。

这些事情通常随着任务的发展,过程的演变和学习数据或客户理解随着时间推移而得出的一些更精细的细节而发展。

我见过类似的东西,人们设计了标签或白名单,搜索它可能会让你更接近你想要的东西。这是一个让你入门的工作示例。

declare @venue as table(
    VenueID int identity(1,1) not null primary key clustered
,   Name_ nvarchar(255) not null
,   Address_ nvarchar(255) null
);

declare @venueType as table (
    VenueTypeID int identity(1,1) not null primary key clustered
,   VenueType nvarchar(255) not null
);

declare @venueStuff as table (
    VenueStuffID int identity(1,1) not null primary key clustered
,   VenueID int not null -- constraint back to venueid
,   VenueTypeID int not null -- constraint to dim or lookup table for ... attribute types
,   AttributeValue nvarchar(255) not null
);

insert into @venue (Name_)
select 'Bob''s Funhouse'

insert into @venueStuff (VenueID, VenueTypeID, AttributeValue)
select 1, 1, 'Scarrrrry' union all
select 1, 2, 'Food Avaliable' union all
select 1, 3, 'Game tables provided' union all
select 1, 4, 'Creepy';

insert into @venueType (VenueType)
select 'Haunted House Theme' union all
select 'Gaming' union all
select 'Concessions' union all
select 'post apocalyptic'; 

select a.Name_
     , b.AttributeValue
     , c.VenueType
  from @venue a
  join @venueStuff b
    on a.VenueID = b.VenueID
  join @venueType c
    on c.VenueTypeID = b.VenueTypeID

答案 1 :(得分:0)

选择第一个选项。创建连接表以记录场地的每个可用功能的多对多关系。选项2在存储方面非常浪费。假设您有一个只有一个设施的场地,当有50种设施类型可用时。此外,据我了解您对选项2的建议,每次添加舒适性,event_type或样式时都必须更新数据库设计。那将是一个非常困难的支持。

在选项1的情况下,一些表格将是:

Table Name: venue_amenities 
Columns: venue_id, amenity_id

Table Name: venue_event_types
Columns: venue_id, event_type_id

Table Name: venue_styles
Columns: venue_id, style_id

使用过滤器查询所有内容时,可以像查询一样查询:

select distinct
v.venue_id
from venues v
inner join venue_amenities va on v.venue_id = va.venue_id
inner join venue_event_types vet on v.venue_id = vet.venue_id
inner join venue_styles vs on v.venue_id = vs.venue_id
where va.amenity_id in ([selected amenities])
and vet.event_type_id in ([selected event types])
and vs.venue_style in ([selected styles])