使用Json格式减少MySQL中的JOIN

时间:2014-01-02 17:58:47

标签: php mysql sql json

我的数据库中有很多表,例如表fs_user,以下是表列的摘录(处理隐私设置):

来自表fs_user:

4列

show_email_to
show_address_to
show_gender_to
show_interested_in_to

与许多社交网络一样,我不仅要指定哪些数据是私有的,哪些数据是公开的,还要指定哪些数据可供所选用户使用,哪些数据不可用。

由于我有大约30个数据,如上面的4个数据,我认为为每个数据创建一个表并与表fs_user建立多对多关系是不好的。

这就是为什么我想到了为每个列(类型= TEXT)以Json形式保存这些数据的例子,例如

show_email_to => {1:'ALL',2:'BUT',3:'3'}

此数据表示向所有用户显示电子邮件,但id = 3的用户除外。

另一个例子:

show_email_to => {1:'NONE',2:'BUT',3:'3',4:'80',5:'10'}

这意味着,除了用户ID = 3,id = 80和id = 10之外,没有用户会看到该电子邮件。

当然,MySql查询将选择此数据,PHP / Js将从Json中提取我需要的数据。

另一点是,有时......用户只想向他的朋友展示数据,除了3个朋友。

这样做:

show_email_to => {1:'FRIENDS',2:'BUT',3:'3'}

这意味着除了id = 3的用户外,电子邮件将显示给他的所有朋友。

我的问题是:与“多对多”解决方案(需要在许多表中包含许多数据)相比,此系统的性能,灵活性(用于其他用途)多少?

注意:我已经知道在一列中保存许多元素是一种不好的做法,但是在这里:我认为这是一个json元素,可以被视为一个对象

2 个答案:

答案 0 :(得分:1)

你说,“因为我有大约30个数据,如上面的4个数据,我认为为每个数据创建一个表并与表fs_user建立多对多的关系会很糟糕”

我同意你的陈述的第一部分。你只需要一张桌子。为了名称,我将其称为ShowableItems。字段是ShowableItemId(PK)和Item。其中一些项目将是电子邮件,性别,地址等。

然后你需要一个多对多的表来显示哪些项目可以显示给谁。您的三个字段是,拥有该项目的人的ID,可显示的项目ID以及可以看到它的人的ID。

答案 1 :(得分:1)

这是一个很好的问题。你提出的建议是,如果你使用任何SQL的话,确实是一个非常糟糕的想法。您建议以一种能够阻止将来加速搜索或查询的所有尝试来对您的表进行非规范化。

你应该怎么做?您可以看一下使用像MarkLogic这样的以XML为中心的dbms。它能够创建加速各种Xpath样式查询的索引,因此您可以搜索关系。如果你这样做,我希望你有一个很大的预算。

或者,您可以使用规范化的权限表。

   item_to_show  (item id)
   order (an integer specifying rule ordering,  needed for this)
   recipient (user id)
   isdenied  (0 means recipient is allowed, 1 means she is denied)

在此表中,主键是由前两列构成的复合键。

我知道你有很多种类的物品。您断言为系统中的每个项目类型添加一个额外的表是不好的。我不同意这本来就很糟糕。我相信您建议的解决方案更糟糕。

您可以安排为每个项目提供唯一的ID号,以允许您使用单个权限表。有关如何执行此操作的示例,请参阅此处。 Fastest way to generate 11,000,000 unique ids

或者您可以拥有一个类型为id的权限表。

   item_to_show  (item id)
   item_type_to_show (item type id)
   order (an integer specifying rule ordering,  needed for this)
   recipient (user id)
   isdenied  (0 means recipient is allowed, 1 means she is denied)

在这种情况下,主键是前三列。

或者,您可以执行您不想做的事情,并为每个项目类型设置单独的权限表。