【问题标题】:Using Json format to decrease JOINs in MySQL在 MySQL 中使用 Json 格式减少 JOIN
【发布时间】:2014-01-02 17:58:46
【问题描述】:

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

4 列来自表 fs_user:

show_email_to
show_address_to
show_gender_to
show_interested_in_to

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

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

这就是为什么,我想到了将这些数据保存在 Json 表单中的每一列(其 type=TEXT)的想法,例如

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 元素,可以被视为一个一个对象

【问题讨论】:

  • 这使得查询特定值变得非常困难。
  • 如果你要做这样的事情,它的结构应该像{"allow": "ALL", "exclude": [3, 4, 80, 10]}
  • 这就是为什么我已经计划与此并行使用 Memcache 的原因,再加上 php 与 json 一起表现出色的事实。
  • 或者更好:列出所有不允许向用户名XXX发送电子邮件的用户。
  • 您的格式也使检查参照完整性变得困难。对于普通关系,您可以使用外键约束。

标签: php mysql sql json


【解决方案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 号,以允许您使用单个权限表。有关如何执行此操作的示例,请参见this。 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)

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

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

【讨论】:

  • 哇,这是非常好的解释,非常感谢@OllieJones...从现在开始我将使用规范化表。 +1 , 最佳答案
  • 为了记录,我将使用第三个选项Or you could have a single permission table with a type id.,它包含一个3列的复合键
【解决方案2】:

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

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

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

【讨论】:

  • 当然我的意思不是每列都有一个表格,不……我的意思是我还有其他可显示的页面、群组、俱乐部、视频、专辑数据,这些数据与这些数据不同。例如:show_album_to 和 show_photo_to 和 show_video_to。
  • 所以,在这里我需要为:showableAlbumData、showableVideoData、showablePageData 添加更多表,而不是将它们放在 fs_album、fs_video、fs_photo 和 fs_page 等表中。你明白了吗
  • 所以,正如你之前所说,我将创建其他表(用于用户、页面、组等的权限......)非常感谢亲爱的,最佳答案 +1跨度>
  • 你的回答也很有用,但是 OllieJones 的回答更详细……你的答案都是最好的,谢谢大家
猜你喜欢
  • 1970-01-01
  • 2016-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-19
  • 1970-01-01
  • 1970-01-01
  • 2020-03-25
相关资源
最近更新 更多