我遇到这种情况,我需要有关数据库表设计的建议。
背景
我正在用PHP开发一个应用程序(准确地说是cakephp)。在我们上传xml文件的地方,它解析文件并将数据保存在数据库中。这些XML可以是文件或网址源,这些是从各个供应商处购买的数据。它旨在从源网站收集各种场地数据,场地可以是酒店,电影院,学校,餐馆等等。
问题
这些场地的初始桌面结构如下。 table最初用于存储通用信息。
id
Address
Postcode
Lat
Long
SourceURL
Source
Type
Phone
Email
Website
随着来自不同来源的更多数据,我意识到不同类型的场地有很多属性。
例如 酒店可以有一些属性,如
price_for_one_day, types_of_accommodation, Number_of_rooms etc
学校不会拥有它们但具有不同的属性。餐厅将具有其他一些属性。
我的第一个想法是创建两个名为vanue_attribute_names的表,Venue_attributes
##table venue_attribute_names
_____________________________
id
name
##table venue_attributes
________________________
id
venue_id
venue_attribute_name_id
value
因此,如果我检测到任何新属性,我想创建一个属性,并在属性表中创建一个具有关系的值。但我怀疑这不是正确的做法。我相信可能还有其他办法吗?此外,如果表变大,可能会出现性能问题,因为连接和SQL查询的增加
正在创建具有所有可能属性的最宽表,因为列是正确的方法吗?请告诉我。如果有任何我可以参考的链接我可以遵循它。感谢
答案 0 :(得分:2)
这是一个令人惊讶的常见问题。
您描述的设计通常称为“实体/属性/值”或EAV。它的好处是允许您存储所有类型的数据,而无需事先知道该数据的架构是什么。它具有难以查询的缺点 - 想象一下在给定位置找到所有酒店,其中每日房价在100美元到150美元之间,其名称以“Waldorf”开头。对所有属性编写查询并快速应用布尔逻辑变得比你想要的更难。您也无法轻松应用数据库级一致性检查,例如“hotel_name不能为空”或“daily_room_rate必须为数字”。
如果这些问题都不让您担心,也许您的设计有效。
第二个选项是将“common”字段存储在传统的关系结构中,但是要将变体数据存储在某种文档中 - 例如MySQL supports XML。这允许您定义XML模式,并使用XPath等进行查询。
这种方法比EAV提供更好的数据完整性,因为您可以应用模式约束。它确实意味着您必须为您正在处理的每种类型的数据创建一个模式。这对你来说可能没问题 - 我猜这项业务每周都不会增加几十种新的场地类型。
使用XML查询的性能可能很棘手,而且通用工具和开发方法将使构建比“只是SQL”更难。
如果你想坚持使用关系数据库,那么最后一个选择就是简单地咬住子弹并使用“纯粹的”SQL。您可以创建具有公共属性的“主”表,以及具有餐厅特定属性的“餐馆”表,具有酒店属性的“酒店”表。只要您拥有可管理数量的场地类型,它就会起作用,并且它们不会出现不可预测的情况。
最后,您可以查看NoSQL选项。
答案 1 :(得分:0)
如果您坚持使用关系数据库,那就是它。您列出的选项几乎可以为您提供。
对于您的情况MongoDB(或其他面向文档的NoSql系统)可能是一个不错的选择。如果你有很多具有不同属性的记录,那么这个数据库系统非常好。