查看权限通常如何在关系数据库中实现?
Posted
技术标签:
【中文标题】查看权限通常如何在关系数据库中实现?【英文标题】:how are viewing permissions usually implemented in a relational database? 【发布时间】:2010-06-26 05:01:10 【问题描述】:为项目设置权限的标准关系数据库惯用语是什么?
答案应该是一般的;但是,它们应该能够应用于下面的示例。任何事情都会发生:添加列、添加另一个表——只要它运行良好即可。
应用/示例
假设 Twitter 数据库非常简单:我们有一个 User
表,其中包含登录名和用户 ID;我们有一个Tweet
表,其中包含推文ID、推文文本和创建者ID;我们有一个Follower
表,其中包含被关注的人和关注者的ID。
现在,假设 Twitter 想要启用高级隐私设置(查看权限),以便用户可以准确选择哪些关注者可以查看推文。设置可以是:
Twitter 上的每个人 只有当前的追随者(这当然必须得到用户的批准,但这并不重要)编辑: 像当前一样,我有一个新的追随者,他看到了;我删除了一个关注者,他不再看到它。 特定关注者(例如,用户 ID 5、10、234 和 1) 只有所有者在这种情况下,表示查看权限的最佳方式是什么?优先级依次是查找速度(您希望能够快速确定要向用户显示哪些推文)、创建速度(您不需要不想花很长时间发布推文),以及有效利用空间(每次我向关注者列表中的每个人发布推文时,我都不应该为每个人添加一行,并且每个追随者我都有一张桌子。)
【问题讨论】:
“答案应该是一般性的;但是,他们应该……”听起来像是从教授的问题中逐字提取的。也许您可以先尝试自己做功课,然后在遇到麻烦时向我们提出具体问题。这不是 RentACoder。 很抱歉,这不是家庭作业——我正在尝试开发一个 Web 应用程序,但对整个 SQL 事物还是很陌生;这个问题困扰我很久了。如果它听起来像一本教科书,我很抱歉——我不是故意那么无聊。 :) 【参考方案1】:看起来像一个典型的多对多关系——我没有看到任何你想要的限制,这可以节省空间的典型关系数据库习惯用法,即一个有两列的表(都是外国的)键,一个进入用户,一个进入推文)......因为当前的关注者可以并且确实一直在改变,所以向发布时当前的所有关注者发布推文(我假设这就是你的意思?)确实意味着在该关系表中添加许多(极短)行(保留关注者集的时间戳历史的替代方法,以便您可以在任何给定的推文发布时间重建谁是关注者,这在时间而不是在空间上明显更好)。
另一方面,如果您想在查看时(而不是在发帖时)检查关注者,那么您可以制作一个特别的userid 人为地表示“当前用户的所有关注者”(就像您将有一个意思是“Twitter 上的所有用户”);使查找快速所需的 SQL,在这种情况下,看起来很麻烦但可行(一个 UNION 或 OR,带有“我是作者的追随者的所有推文,并且推文可由 [代表的人工用户 ID] 所有追随者读取”)。我不会深入了解 SQL 的那个迷宫,除非你确认这是你心中所想的特殊含义(而不是对我来说似乎更自然但没有的简单含义)允许在关系表上为“向所有关注者发布推文”的操作节省任何空间。
编辑:OP已澄清他们的意思是我在第二段中提到的方法。
然后,假设userid
是Users
表的主键,Tweets
表有一个主键tweetid
和一个外键author
,用于每条推文作者的用户ID,@987654326 @table 是一个典型的多对多关系表,有两列(外键都变成Users
)follower
和followee
,而Canread
表是一个不那么典型的多对多关系表,仍然有两列——Users
的外键是reader
列,Tweets
的外键是tweet
列(呸;-)。两个特殊用户@everybody
和@allfollowers
定义为上述含义(因此向所有人、所有关注者或“只是我自己”发帖,都只在Canread
中添加一行——仅选择性发布到特定列表N 个人添加 N 行)。
因此,我认为用户@me
可以读取的一组推文 ID 的 SQL 类似于:
SELECT Tweets.tweetid
FROM Tweets
JOIN Canread ON(Tweets.tweetid=Canread.tweet)
WHERE Canread.reader IN (@me, @everybody)
UNION
SELECT Tweets.tweetid
FROM Tweets
JOIN Canread ON(Tweets.tweetid=Canread.tweet)
JOIN Followers ON(Tweets.author=Followers.followee)
WHERE Canread.reader=@allfollowers
AND Followers.follower=@me
【讨论】:
对不起,我的模棱两可不好——我的意思是当前的变化。查看更新的问题。 我只是认为在每个帖子中添加这么多行并不是最佳的做事方式; Facebook 有类似的(真正的)能力,我怀疑他们会这样做——如果只是看起来需要做很多工作的话。 @aharon,Facebook 使用关系数据库吗?我想,就像所有流量非常大的网站(包括 Twitter)一样,它们已经加入了 NoSQL 的潮流(正是出于可扩展性的原因)。 Facebook 据说使用了一个巨大的 mysql 集群——至少在 2008 年是这样。有没有你知道的可以更好地处理这种查询/关系的非 sql 数据库? @aharon,是的,有(其中“更好”意味着“更具可扩展性”)——当然,NoSQL DB 总是必须仔细地去规范化以获得最大的性能和可扩展性,其方式各不相同完全在其中,但是 Google 的 Bigtable(不是 App Engine 中暴露的更简单的外观)会对此做出贡献,如果说 Cassandra 做不到,我会感到惊讶(但作为 Google 员工,我的工作是在 bigtable 上,所以这就是我非常熟悉的那个)。不管怎样,看看我上面的 SQL 尝试,对我来说看起来还不错(当然还有所有需要的索引)。以上是关于查看权限通常如何在关系数据库中实现?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SQL 中实现聚合? (这与 GroupBy 无关)