2010-03-26 80 views
2

我正处于多用户应用程序的规划阶段,每个用户只能访问自己的数据。会有几个相互关联的表,所以我可以使用JOIN来确保它们只访问他们的数据,但是我应该在每个表中包含user_id吗?这会更快吗?从长远来看,这肯定会让一些查询更容易。我应该在多个表中包含user_id吗?

具体来说,问题是关于包含user_id字段的多个表。

例如,每个用户可以配置类别,项目(在这些类别中)以及针对这些项目的子项目。从用户到子项通过其他表有一个逻辑路径,但它需要3个JOIN。我应该只在所有表中包含user_id吗?

谢谢!

回答

3

通常,您使用外键来关联表间的数据。在很多情况下,这个外键是用户ID。例如:

users 
    id 
    name 

phonenumbers 
    user_id 
    phonenumber 

所以是的,这是非常有意义的。

+0

我的问题是,是否包含多个表格,而不仅仅是一个表格,我会编辑我的问题。 – Drarok 2010-03-26 00:12:13

0

如果一个类别只能属于一个用户,那么是的,你需要在类别表中包含user_id。如果一个类别可以属于多个人,那么您将拥有一个将类别ID映射到用户ID的单独表格。如果两者之间有一对一的映射关系,你仍然可以做到这一点,但没有真正的理由。

如果您可以保证总是通过加入到类别表来访问这些子表,那么您不需要在其他表中包含user_id。如果您有机会独立访问它们,那么您应该在这些表上拥有user_id。

1

normalize的程度可能是一个困难的决定。有关此主题的最佳StackOverflow答案之一(Database Development Mistakes Made by App Developers)针对以下两种情况发出警告:(1)未能正常化,以及(2)过度归一化。

您提到,从长远来看,在多个表格中重复相同的数据可能会更容易(也就是说,不会规范化该数据)。查看上一个链接中的“不通过视图简化复杂查询”主题。如果您有效地使用视图,那么在编写视图时只需执行一次3连接查询,然后就可以在大多数情况下使用不含连接的查询。

大多数开发人员往往欠规范化,因为它似乎更简单。继续并正常化。使用视图来简化您的日常查询。当您的需求变得更加复杂或者您决定添加功能时,您会很高兴将时间投入到关系数据库设计中。

或者,根据您的工具集,您可能希望使用database abstraction图层,该图层在处理较高级别的数据对象时执行关联设计。

0

这是多租户数据库中的设计决策。用“根”表,显然你有user_id。但是在非“根”表中,当您使用代理PK时您有选择。

假设您有具有项目和项目的用户。项目显然必须有一个user_id,但是如果动作绑定到一个且只有一个项目,那么user_id是多余的,并且也违反了正常形式,因为如果要移动到另一个用户的项目(可能不太可能在您的用例中),项目FK和用户FK都必须更新。通常在多租户方案中,这并非真正可行的方案,因此每个表的主键实际上都是承租人和承租人“内部”的唯一主键(它们也可能是全球唯一的) 。

如果您在设计中广泛使用自然键,那么需要明确的租户+自然键,以便可以使用每个租户的自然键。只有在使用像IDENTITY或GUID或序列这样的替代品时,这会成为一个问题,因为它很容易使IDENTITY成为PK,毕竟它的定义是唯一的。

让user_id在所有表格中都允许您在视图中执行某些操作来增强安全性(纵深防御),为您提供一些防御性编程(在SQL Server中,您可以通过内联表值函数限制所有访问 - 基本上是参数化视图 - 要求应用程序在每个“表格”访问中指定user_id),并且还允许您通过将所有共享密钥上的所有内容叉开来轻松扩展到多个数据库。

请参阅this article了解一些有趣的见解。

(在大型多人并行模式像的Teradata,主索引确定在其上的数据的生活,所以我会认为这是必须的以停止行的重新分配到另一安培的安培。)

一般来说,我会说你在每个表中都有一个tenantid,它应该是表中的第一列,在大多数索引中应该是大多数情况下的主键的一部分,除非另有说明。在可能的情况下,它应该是大多数存储过程中必需的参数。

0

,如果它是Oracle,那么你可能会建立一个细粒度的安全规则做连接和防止在原有基础上的用户ID是否存在某些活动...(SELECT INSERT,UPDATE,DELETE等)
您需要登录的用户和user_id之间的映射。你可以使用uid,但是如果数据库在灾难之后重建,这个数字可能会改变......

相关问题