我目前正在构建一个系统,用户可以将他们创建的内容标记为公共(public)或私有(private)。我想限制某些用户仅创建公共(public)内容或仅创建私有(private)内容,并允许其他用户选择。
为了避免使用 ENUM 作为数据类型,我有一个包含两行的 types 表:“public”和“private”。我还有一个allowed 表,它采用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 ]
因此“我”用户只能创建私有(private)内容。
这一切都很好,因为这样我就可以在 content 表中使用外键来限制其内容设置。
table: content; columns: id, userid, typeid, content
[ content.userid, content.typeid ] references [ allowed.userid, allowed.typeid ]
content: [ 1, 1, 2, "some text" ]
但一年后的现在,我决定“我”现在只能创建公共(public)内容。因此,我可以从“me”用户的 allowed 表中删除该行并创建一个新行:
delete from allowed: [ 1, 2 ]
insert into allowed: [ 1, 1 ]
问题是,我希望确保他们已经创建的私有(private)内容保持私有(private),而只有新内容必须创建为公开内容。据我从我的研究中得知,这只是一个称为“孤儿行”的概念,这听起来与此设计所需的功能类型完全一样,但 MySQL 根本不允许孤儿行。 p>
维护数据完整性的最佳方法是什么?从概念上讲,保留外键并允许孤立行是完美的设计。我可以在 PHP 中执行 if 语句,但我想找到“纯粹”的解决方案(如果有的话)。
您建议设计此数据库的适当方法是什么?
最佳答案
content
应引用 users
和 types
表,而不是 allowed
表。外键约束主要是为了维护数据完整性,而不是强制安全/权限。
顺便说一句,我在用户表 can_create_public
和 can_create_private
中只有两个标志;除非您计划创建新的类型
(...“半公共(public)”?),拥有一个表可能有点矫枉过正。在这种情况下,content
将只有一个 private
标志。
我可以看到您可能需要扩展“类型”列表的场景,但这将是一个更加复杂的用户组访问权限场景,其中“组”将是类型。
关于MySQL:如何避免需要孤立行的情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48530575/