0

我有这种情况,我需要有关数据库表设计的建议。

背景

我正在用 PHP 开发一个应用程序(准确地说是 cakephp)。我们上传一个 xml 文件,它会解析文件并将数据保存在数据库中。这些 XML 可以是文件或 url 提要,这些是从各种供应商处购买的数据。它旨在从源 url 收集各种场所数据,场所可以是酒店、电影院、学校、餐馆等。

问题

这些场地的初始表格结构如下。表最初设计用于存储通用信息。

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 查询的增加,可能会出现性能问题

创建具有所有可能属性的最广泛的表作为列是正确的方法吗?请告诉我。如果有任何我可以参考的链接,我可以关注它。谢谢

4

2 回答 2

2

这是一个令人惊讶的普遍问题。

您描述的设计通常称为“实体/属性/值”或 EAV。它的好处是允许您存储各种数据,而无需事先知道该数据的架构是什么。它的缺点是难以查询 - 想象一下在给定位置查找所有酒店,其中每日房价在 100 美元到 150 美元之间,其名称以“Waldorf”开头。针对所有属性编写查询并快速应用布尔逻辑变得比您希望的要难。您也无法轻松应用数据库级别的一致性检查,例如“hotel_name 不得为空”或“daily_room_rate 必须为数字”。

如果这些问题都不让您担心,那么您的设计可能会奏效。

第二种选择是将“通用”字段存储在传统的关系结构中,但将变体数据存储在某种文档中——例如 MySQL支持 XML。这允许您定义 XML 模式,并使用 XPath 等进行查询。

这种方法为您提供比 EAV 更好的数据完整性,因为您可以应用模式约束。这确实意味着您必须为您正在处理的每种类型的数据创建一个模式。这对你来说可能没问题——我猜这家公司每周不会增加几十个新的场地类型。

XML 查询的性能可能很棘手,通用工具和开发方法将使其比“仅 SQL”更难构建。

如果您想坚持使用关系数据库,最后的选择就是硬着头皮使用“纯”SQL。您可以创建一个具有公共属性的“主”表,一个具有餐厅特定属性的“餐厅”表,一个具有酒店属性的“酒店”表。只要您拥有可管理数量的场地类型,并且它们不会意外出现,这就会起作用。

最后,您可以查看 NoSQL 选项。

于 2013-02-19T12:48:46.817 回答
0

如果您坚持使用关系数据库,就是这样。您列出的选项几乎就是他们可以给您的。

对于您的情况, MongoDB(或其他面向文档的 NoSql 系统)可能是一个不错的选择。如果你有很多不同属性的记录,这个数据库系统非常好。

于 2013-02-19T12:32:02.257 回答