MySQL模式建议:不可预测的字段添加

时间:2019-02-07 03:54:46

标签: mysql database schema

问题概述。

比方说,我有一个名为TableA的表,该表具有固定属性PropertyA,PropertyB和PropertyC。这已经足以满足您自己的网站需求,但随后突然有一些客户希望在您的网站上使用自定义字段。

ClientA想要添加PropertyD和PropertyE。 ClientB想要添加PropertyF和PropertyG。

要注意的是,这些客户互不相干。现在想像一下,如果您有更多的客户端,则仅在TableA中添加可为空的字段的解决方案将很麻烦,并且最终将导致一堆表格。或者至少我认为情况是可以纠正我的。如果我那样做会更好吗?

现在我想到了两种解决方案。我在问是否有更好的方法来做,因为我对权衡及其未来表现不那么自信。

建议的解决方案#1 Proposed Solution #1

data_id并非完全是外键,但它存储附加到表A行的任何相应客户端属性。使用client_id作为属性表和表A上唯一的外键。

这似乎是某种反模式,但我可以想象这种查询将很容易,但是它要求开发人员知道应该从中选择什么属性表。我不确定很多表是否是一件坏事。

建议的解决方案2 Proposed Solution #2

我相信它会更优雅一些,并可以根据需要轻松添加更多字段。更不用说这些是我需要做其他所有事情的唯一表。只是想像。我将请求属性添加到属性表中,如下所示:

Properties
-------------
1 | PropertyD
2 | PropertyE
3 | PropertyF
4 | PropertyG

每当我保存任何数据时,我都会标记所有属性,只要它们可用。对于此示例,我要保存存储在ID为1的“客户”表中的ClientA。

Property_Mapping
--------------------------------------------------------
property_id | table_a_id | property_value   | client_id
--------------------------------------------------------
1           | 1          | PROPERTY_D_VALUE | 1
2           | 1          | PROPERTY_E_VALUE | 1

我想这很可能会导致查询的复杂性,但这是一个权衡。我打算将client_id放在property_mapping上,以防万一客户端需要相同的字段。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

您已发现Entity-Attribute-Value反图案。对于关系数据库,这是一个可怕的想法。它使您的查询更加复杂,并且占用4-10倍的存储空间。

在Stack Overflow的一个旧答案中,我介绍了几种替代方法的优缺点:

在演示文稿中:

作为EAV造成麻烦的一个示例,请考虑如果您的一位客户说PropertyD必须是强制性的(即等效于NOT NULL,而PropertyE必须是UNIQUE,您将如何应对。同时,另一位客户说PropertyG应该限制为一组有限的值,因此您应该使用ENUM数据类型,或者对允许值表使用外键。

但是您无法使用“属性”表实现任何这些约束,因为所有属性的所有值都存储在同一列中。

使用此反模式时,您将失去关系数据库的功能,例如数据类型和约束。