MySQL:如何避免需要孤立行的情况?

时间:2018-01-30 21:11:19

标签: mysql sql foreign-keys

我目前正在构建一个系统,用户可以将其创建的内容标记为公共或私有。我想限制一些用户只创建公共内容或仅创建私人内容,并允许其他人选择。

为避免使用ENUM作为数据类型,我有一个带有两行的 types 表:“public”和“private”。我还有一个允许的表,它带有 userid typeid 。例如:

table: users; columns: id, username
table: types; columns: id, name
table: allowed; columns: userid, typeid

我可能在这些表格中有以下记录:

users: [ 1, me ]
types: [ 1, public ], [ 2, private ]
allowed: [ 1, 2 ]

所以“我”用户只能创建私人内容。

这一切都很好,因为我可以使用 content 表中的外键来限制其内容设置。

table: content; columns: id, userid, typeid, content
[ content.userid, content.typeid ] references [ allowed.userid, allowed.typeid ]

content: [ 1, 1, 2, "some text" ]

但是现在,一年后,我决定“我”现在只能创建公共内容。因此,我可以删除“我”用户的允许表中的行并创建一个新行:

delete from allowed: [ 1, 2 ]
insert into allowed: [ 1, 1 ]

问题是,我希望确保他们已经创建的私有内容保持私密,而只有内容必须创建为公开内容。据我所知,这只是一个名为 orphan rows 的概念,听起来就像这个设计需要的功能类型,但MySQL根本不允许孤立行。

维护数据完整性的最佳方法是什么?从概念上讲,保留外键并允许孤立行是完美的设计。我可以在PHP中做一个if语句,但我想找到“纯粹”解决方案,如果有的话。

您建议使用哪种方法来设计此数据库?

2 个答案:

答案 0 :(得分:1)

content应引用userstypes表,而不是allowed表。外键约束主要用于维护数据完整性,而不是强制执行安全/权限。

作为旁注,我在用户表can_create_publiccan_create_private中只有两个标记;除非你打算创建一个新的types(..."半公共"?),因为它有一个表可能有点过分。在这种情况下,content只会有一个private标记。

我可以看到你想要一个扩展的"类型"但这将是一个更复杂的用户组访问权限的情况,其中"组"将是类型。

答案 1 :(得分:0)

我不明白这个问题。 typeid表中有content列。它不会因为你更改users表而改变 - 除非你有一个触发器强制执行问题中没有描述的内容。

然而,我建议使用类型2维度,而不是删除记录。基本上,它有eff_dateend_date,用于描述用户/类型组合有效的时间段。这会将typeidusers表分开,而是将其放在UserTypes表中。这张桌子将是#34;平铺"随着时间的推移,不同时间点的不同类型。