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

oom*_*pah 9 database-design

我正在设计一个房地产应用程序的数据库.它被证明比我预期的更多参与(也许我过度复杂的事情).

问题主要是由于存在:

  • 同义词例如术语:flat,apartment和penthouse可能都是基本上相同类型的属性
  • 属性(不同的属性类型具有不同的属性)例如,公寓可以是底层或顶层等

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

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

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

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

应该返回公寓列表,这些公寓位于一楼并且有一个花园.

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

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

Joe*_*own 28

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

这是一个快速的ERD草图:

ERD

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

PROPERTY 是一块房地产.

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

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

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

那应该如何帮助呢?

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

在此输入图像描述

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

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

这种方法的优点是,你可以放松你的标准,说:"让我们把归因层次上升到下一个不那么具体的东西而不是顶层公寓".在我的例子中,那将是"高层建筑".现在你再次尝试搜索,你可能会有更好的运气.

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

处理嵌套集

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

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

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

卧室示例

上面显示了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')
Run Code Online (Sandbox Code Playgroud)

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

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


tom*_*ern 2

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

例如:

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)
Run Code Online (Sandbox Code Playgroud)

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

例如:

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
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助