如何设计数据库来存储属性,通过同义词选择属性

时间:2011-09-14 18:05:07

标签: database-design

我正在为房地产应用程序设计数据库。它被证明比我预期的更多参与(也许我过于复杂化了)。

问题主要是由于存在:

  • 同义词 例如,平面,公寓和顶层公寓都可以指基本上相同类型的财产
  • 属性(不同的属性类型具有不同的属性) 例如,公寓可以是底层或顶层等。

我最终得到了一个针对不同属性类型的相当(无意)精心设计的分类树。树节点是属性类型的实际实例。

我想创建一个数据库,这样我不仅可以查询任何同义词,还可以查询属性。

例如,查询(在伪SQL中):

SELECT * from properties where synonym =“flat”and attribute IN('ground floor','garden');

应该返回公寓楼的列表,这些公寓楼是地下的并且有花园。

有人可以帮我解决如何设计数据库模式以便允许上述类型的查询吗?

最后但并非最不重要的是,我将使用MySQl或PostgreSQL作为后端数据库,但是如果可能的话,我希望这种方法与数据库无关。

2 个答案:

答案 0 :(得分:27)

我会对您的归因方案采取不同的方法。我不会将不同的属性视为同义词,而是将它们视为重叠,或者更具体地说,是对属性的嵌套描述。这将处理您的商业案例,同时承认Mike Sherrill的精明观察。

这是一个快速的ERD草图:

ERD

通过非常快速的数据字典:

PROPERTY是一块房地产。

CATEGORY是一组描述性属性。这个表的重点更像是属性的组织者而不是其他任何东西。它可能包括“财产类型”,“所有权结构”,“浴室数量”以及其他可能感兴趣的内容。

ATTRIBUTE是特定的兴趣品质。请注意此实体类型的复制关系。我稍后会做更多的事情。重点是属性可以更通用或更具体,某些属性可以看作是其他属性的改进。

DESCRIPTOR是与该特定房地产相关联的PROPERTY和ATTRIBUTE的交集。

那么这应该如何帮助?

关键是属性如何运作。如果您使用嵌套集模型,则可以解决或多或少的具体归因和搜索条件。请考虑以下一个潜在CATEGORY及其相关ATTRIBUTE的图表:

enter image description here

在此示例中,CATEGORY是“属性类型”。您可以从图中看到此类别中存在属性的分层细分。图中的每个框都是ATTRIBUTE中的记录。包含其他框的框具有子属性。在另一个盒子里面的盒子里面有一个FK到它们的包含盒子等等。

通过这种方式,你可以说“我想找一个属于阁楼的房产”。然后,您可以找到带有相关DESCRIPTOR的PROPERTY记录,该DESCRIPTOR指向“Penthouse”ATTRIBUTE。这很容易。但是,如果您的搜索结果为空呢?

这种方法的优势在于,您可以通过说“让我们将归因层次结构上升到下一个不如顶层公寓的特定事物”来放松您的标准。在我的例子中,那将是“高层建筑”。现在你再次尝试搜索,你可能会有更好的运气。

这样的系统使您能够在每个属性类别中尽可能具体,同时放宽其他类别,以便开始获得搜索命中率。这真的是房地产经纪人的工作不是吗?帮助客户做出必要的妥协以找到最适合他们最重要标准的东西?

处理嵌套集

这种方法唯一棘手的部分是如何处理嵌套集。有很多方法可以做到这一点,其中许多已在其他地方进行了详细记录。我自己喜欢visitation number技术,特别是对于相对静态的数据集。这使得很容易找到某些给定ATTRIBUTE或其任何子节点的匹配,而无需在SQL中做任何异国情调。

编辑:那么这是如何工作的?

OP问你如何处理卧室数量以及查询结果如何?让我们再举一个例子来说明:

Bedroom Example

上面显示了CATEGORY“Number of Bedrooms”的嵌套集。我还在图表中添加了访问数字。请注意访问数字的工作方式,特别是请注意,任何给定属性值的左(绿色)和右(红色)数字都包含任何从属属性的左右访问数。例如,“2+卧室”分别具有左和右数字6和15。属于“2+卧室”的每个属性都有左右数字。

那么如何查询具有给定描述符的属性?假设我们想找到两间或更多卧室的所有房产。这种查询的SQL可能如下所示:

select P.* 
from PROPERTY P
  inner join DESCRIPTOR D
    on P.id = D.property_id
  inner join ATTRIBUTE A
    on D.attribute_id = A.id
where A.left >= (select X.left from ATTRIBUTE X
                 where X.name = '2+ Bedrooms')
  and A.right <= (select Y.right from ATTRIBUTE Y
                  where Y.name = '2+ Bedrooms')

请注意,上述查询与您实际使用的内容略有不同。例如,您可能使用其int标识键而不是其字符串名称来查找过滤属性。但是,我认为为了清晰起见,我将其保留为主要点,您可以通过查找而不是来查看特定的相关属性,但是对于属于您的过滤器的所有相关属性范围

如果要过滤多个属性,只需在where子句中添加更多子子句。

答案 1 :(得分:1)

要处理同义词,您可以在包含属性类型的静态列表的表和包含同义词的表之间进行多对多查找。这样,一个同义词可以映射到多个属性类型。

例如:

Table:Property Type
1 House
2 Appartment
3 Large House
4 Cave

Table:Synonym
1 house
2 flat
3 dwelling
4 condo
5 mansion

Table:PropertyType-Synonym
1 1 (House is a house
1 3 (House is a dwelling)
2 2 (Appartment is a flat)
2 3 (Appartment is a dwelling)
2 4 (Appartment is a condo)
3 1 (Large House is a house)
3 3 (Large House is a dwelling)
3 5 (Large House is a mansion)
4 3 (Cave is a dwelling)

对于属性,您可以使用一种开放属性结构。

例如:

Table:Property
1 Apartment F, Field House Gardens
2 123 Alphabet Street, NumberTown

Table:Attribute
1 Is ground floor?
2 Number of bedrooms
3 Has garden?

Table:Property-Attribute-Values
1 1 No
1 2 2
1 3 Yes
2 2 5 
2 3 Yes

希望这有帮助