1

我正在为 MySQL 设计一个数据库,以在应用程序的两个用户之间创建关系。我不确定存储这种关系细节的最佳方式,尽管我目前打算在名为 RELATIONS 的链接表中为每个关系使用一条记录。每个用户都有他们的姓名和职业等基本数据存储在 USERS 表中,以及通过 FK 链接存储在其他表中的更具体的个人数据,我们将其称为 OTHER1、OTHER2 和 OTHER3,它们都将包含一些其他数据要共享,我们将在名为 [Data] 的字段中说每个,并用 ID 和 USER_ID 标识。

困难在于该应用程序允许用户指定他们向每个用户显示的基本数据和高级数据,反之亦然。RELATIONS 链接表需要有 FK 到 USERS 才能让两个用户建立关系,但我不知道如何最好地指定每个用户能够共享哪些数据,因为数据库存储的几乎所有数据都是可选存储,但可能需要对无权查看它的用户隐藏所有内容。但是,第二个用户应该能够查看那里是否有数据,以便他可以请求查看数据的权限。

此时我的关系模型如下所示:

关系

ID
USER_ID1
USER_ID2
USER1OTHER1_ID [(Value), Unshared, Null]
...
USER1OTHER100_ID [(Value), Unshared, Null]
USER2OTHER1_ID [(Value), Unshared, Null]
...
USER2OTHER100_ID [(Value), Unshared, Null]

因此,如果 User1 已与 User2 共享,则 USER1OTHER1_ID 将包含 OTHER1 的 FK,如果存在但未共享,则为“未共享”,如果 User1 在 OTHER1 中没有数据,则为 Null。与用户 1 共享的 USER2OTHER1 相同。不过,我不喜欢拥有庞大的字段数组,而且如果 User1 稍后决定将数据添加到 OTHER1,我不喜欢我必须如何更新所有关系。有没有一种更简单、更规范的方式来表示这一点?

4

4 回答 4

3

我相信规范化的方法是只存储 userA 是否有权查看 userB 的数据,而不是在关系表中添加对它的 FK 引用,因为您已经在其他地方引用了 userB 的数据。通过在关系表中存储额外的引用,您正在复制数据,并且必须确保它保持同步,如您在问题中描述的那样,这可能是一个持续的维护麻烦,而且您在重构代码时还必须记住一件事.

如果您只在关系表中存储权限(没有 fks),您将加入一个表(用户?)以获取用户的共享数据或根据权限查看它是否存在。

至于关系表上的列数过多,我认为您在查询表时不足以看到真正的降级(您可以对此进行纠正)。为了清楚起见数据库代码以及您的应用程序代码,我认为您最好为每个权限设置一个列,而不是尝试找到捷径,例如将它们组合成一个 clob 或其他东西。

于 2012-07-07T18:47:11.180 回答
0

..因为几乎所有数据库存储的数据都是可选存储的...

考虑到这一点,我建议对所有用户属性使用6NF

  • User表用作锚,理想情况下仅容纳UserID.

  • 每个用户属性都有自己的表,只有UserID和属性值(6NF);仅当指定了属性时才存在行(所有属性值都不是 NULL)。

  • 每个属性也只有一个共享表OwnerID, VisitorID。仅当所有者与访问者共享属性时才存在行。


在此处输入图像描述


  • 在此模型中,用户只能共享确实存在的属性。如果您想允许共享未指定的属性,请将 也指向OwnerID表格User

为了使事情更简单,您可以(应该)为用户数据创建一个视图。

于 2012-07-07T22:00:28.087 回答
0

我能想到的最简洁的方法是存储一个带有关系的 INT,这是权限的按位表示;在代码中解释该 INT。INT 将需要与您拥有唯一权限一样多的位,然后为每个位定义常量。我不确定你用什么语言实现,但是有几种方法可以给这只猫剥皮......

因此,一些伪代码可能如下所示:

define RELATION_PERMISSION_SEE_MY_PHOTOS = 1;
define RELATION_PERMISSION_SEE_MY_FRIENDS = 1<<1;
define RELATION_PERMISSION_SEE_MY_EMAIL = 1<<2;

然后构建一些支持信息的数组(如本地化字符串等)来构建你的界面,然后做这样的事情来修改它:

int new_permission = 0
foreach(user-selected-permissions as selected_permission) {
  new_permission |= selected_permission
}
my_relation_model.permissions_flags = new_permission
于 2012-07-07T18:38:19.943 回答
0

一种方法是使用本质上的键值对..

与此类似:

user_1_id
user_2_id
field
privilege
于 2012-07-07T18:45:22.560 回答