我必须为C#/ .NET WinForms / Desktop应用程序添加一些安全性。我正在使用Oracle DB后端。
表格很简单:用户(ID,名称),角色(ID,角色),UserRole(UserID,RoleID)。
我使用Windows帐户名来填充User表。角色表现在只是'Admin','SuperUser','BasicUser'......
因为没有两个人可能拥有相同的Windows帐户名称...即使我不控制这些名称管理(netops确实如此,因此我想使用Windows帐户,所以我不必管理它; ))。对于角色表,我应该永远不会有重复值 - 我控制输入,只有3(战术应用程序在一年内消失)。 UserRole是一个连接表,用于表示用户和角色的多对多关系,因此没有合法的surragate密钥。
简单问题 - 为什么要在“用户和角色”表中使用“ID”(int)?这里有什么意义或优势吗?这是“我一直都是这样做的”那种类型的东西吗?或者我暂时没有这样做并忘记原因?
答案 0 :(得分:2)
名称更改 - 主键值不得。阿比盖尔·史密斯成为阿比盖尔·琼斯并且用户名发生了变化,但代理密钥可以防止必须在任何地方级联这些变化。
如果您使用的是代理键,但是列或列的组合应该是唯一的,那么请使用唯一索引强制执行该操作。无论如何,您很可能希望在user.name和role.role列上使用索引,并且唯一索引的空间效率更高,并为优化器提供有用的元数据。如果您有代理键但没有唯一标识行的其他列组合,那么请再次考虑您的实体定义是否正确。
一个警告。特别是对于访问路径很少的非常窄的表,您可以使用索引组织表。 Oracle只允许主键上的索引组织表,但允许外键对一组唯一的列(如果它由唯一约束强制执行,而不仅仅是唯一索引)。
您最终可能会得到一个表,其中唯一ID通过唯一索引强制执行,并被ORM视为PK并用作外键关系的父级,但是主键(如DB)是rolename / username / whatever,因为你希望它作为索引组织表的驱动程序。
答案 1 :(得分:1)
intersection tables不需要代理密钥,但有以下几个理由:
ON
和WHERE
条款更短,因此更不容易出错。