我想写一个网站,用户将使用他们的电子邮件地址和密码登录,但可以有多个用户名。
上下文是一个社交游戏网站。这可能会导致用户希望拥有多个用户名。例如,一个用于在团队中玩游戏的用户名(前缀或类似的)和一个用于单独玩游戏的用户名。
我一直在努力寻找在我的数据库中表示它的最佳方式,到目前为止我想出了:
在此设计中,每个用户的用户名中只有一行将 active 设置为 true。这对我来说有点味道。如果给定用户的行没有将 active 设置为 true 怎么办?
我想对于这个,我们或多或少地保证每个用户都有一个用户名,并且拥有的用户名表提供了用户拥有的用户名列表。感觉好多了,但是有重复的信息(活动时在两个表中指定了用户名)。
任何人都对我如何构建它有更好的想法?这有共同的模式吗?
从本质上讲,我所设想的是一种为我的网站提供功能的方式,即每人拥有一个用户,使用电子邮件和密码登录,并将一个或多个用户名链接到该用户。
我猜用户和用户名之间存在 1:N 关系,其中 N > 0。我只是不确定如何有效地对此进行建模。或者实际上,如果这表明我想要的功能需要重新思考。
没有正式的团队概念,这只是一个例子,一个人可能想要多个用户名。
当然,我们可以简化这一点并强制需要单独用户名的人多次注册。这将大大简化数据库,但允许多个用户名一次登录对用户来说更方便。
我正在考虑将其限制为最多 2 或 3 个,但我想这不会改变设计,只是前端限制。
您已经澄清,您不会在您的系统中实施团队方面,但我认为在此答案中保留针对此类场景的建议方法仍然是相关的,因为它可以成为其他寻求者的有用示例。
除此之外,我还包含了一些其他上下文,您可以在这些上下文中提供具有多个用户名(或Nicknames或Handles)的选项,以及考虑用于处理用户和角色数据的常见 ASP.NET 安排的可能性。这些元素可能有助于与您自己的业务环境的信息需求建立一些类比。
根据我对你对社交游戏网站的描述的理解,我认为以下概念层面的表述是特别相关的:
然后,我从这些业务规则中导出了图 1中显示的两个 IDEF1X 1图。
1.2.1 选项 A
正如您在这样的图中所看到的,实体类型Users
和之间存在多对多 (M:N) 关联或关系Teams
,这在称为的关联实体类型中生效TeamPlayer
。
的UserProfile.UserId
PRIMARY KEY(PK为了简洁)属性迁移2到TeamPlayer
如PlayerId
,角色名称,我已分配到UserProfile.UserId
为了使它在其相应的实体类型的上下文中更有意义的,并且这些性质必须通过外键连接(FK ) 中定义TeamPlayer
。
另一方面,通过另一个 FK 引用TeamPlayer.TeamNumber
关联到Team.TeamNumber
。
通过这种安排,一个人UserProfile
可以持有
Username
作为个人行事时,和Nickname
时,他或她进行角色的Player
每个的Teams
其中UserProfile
的问题已加入。1.2.2 选项 B
该图与选项 A 中提到的图非常相似,但它有一个不同的重要方面,因为我已将该TeamPlayer.Nickname
属性移动到一个单独的实体类型,称为Nickname
. 如果Team Player的Nickname值是可选的,则此配置很有用,即TeamPlayers可以选择提供或不提供Nickname。
Option A daigram 有一个为 定义的 ALTERNATE KEY 3 (AK) TeamPlayer
,它由两个属性组成:TeamNumber
和Nickname
。反过来,选项 B 图在Nickname
由TeamNumber
和组成的实体类型中展示了一个 AK Nickname
。以这种方式,两种方法都会在确定的团队实例的上下文中为昵称值提供唯一性。
如果您想防止同一个昵称值在多次Team中重复出现,那么您应该设置一个仅包含一个属性的 AK,即Nickname
. 此方法适用于选项 A 和选项 B。
或者,如果您希望将Nickname
属性设置为 NULLable(即可选),您可以在选项 A 中定义“过滤”(或“条件”或“部分”,取决于使用平台)UNIQUE 约束以提供相对于 a 的昵称唯一性,Team
但是,在我看来,按照这种方式进行,事情会变得不那么优雅,可以这么说。
我创建了更多 IDEF1X 图表(如图 2 所示),描绘了给定Person可以有多个用户名的不同场景,旨在扩大本文的范围。它们显示在以下部分中。
2.1.1 选项 A
此选项代表以下概念性业务规则:
因此,它与您的第一个图表相当,但我添加了一个Person
实体类型,该实体类型可以通过FK 定义选择性地连接。UserProfile
UserId
另一个重要的补充是Username
PK,它包括
UserProfile.UserId
和的 FK 引用CreatedDateTime
表示插入给定用户名的瞬间的属性。这允许您摆脱Username.UsernameId
(或username.id
,如果您愿意)属性。
在这方面,您问题的这段摘录非常重要:
因此,在此设计中,每个用户的用户名中只有一行将 active 设置为 true。这对我来说有点味道。如果给定用户的行没有将 active 设置为 true 怎么办?
是的,你应该建立一个政策,即国家有多少Username
实例可以有IsActive
属性设置为'TRUE'
相对于精确UserProfile
,无论是一个专门的用户名是“活跃”在给定的时间点,也许是两个,三个等,或无根本。如您所知,每种可能性都需要不同的验证方法。
但是,如果某个User可以有多个Usernames,我不认为如果这样的User没有任何“活动” Usernames 会出现问题,因为登录凭据是Email和Password。在这种情况下,当没有用户名处于“活动状态”时,您可以显示某种“默认消息”来指示这种情况。
2.1.2 选项 B
此方法与选项 A 非常相似,但灵活性较差,因为我已将UserProfile
凭据集成到Person
实体类型中。通过这种方式,您将强制每个Person都有 aLoginEmail
和 a Password
。
相反,选项A允许您留住人(或人们不相关的)用户在清洁和独立的方式下,不采用空(也就是说,可选)属性。
2.1.3 选项 C
显示为选项 C 的图表描述了以下语句:
这种方法意味着与称为时间数据库的主题有关的概念。在这方面,您可能会发现我对情景 A 的看法以及我对情景 B的回应。
使用这种方法——一旦这个图中描述的模式建立在特定的 SQL 环境上——你可以在一个表中保留“活动”用户名,在一个UserProfile
表中保留所有“过去版本” UsernameHistory
。
根据数据操作因素,基本上,每次更新UserProfile
他或她时Username
,您都会在表中保存最后一个版本的副本。每个历史版本都由修改该行的日期和时间数据的组合唯一标识,当然还有将相关行与其各自的.Username
UsernameHistory
UserId
UserProfile
与任何关系数据库项目一样,您应该认真考虑使用ACID TRANSACTIONS以保护您的数据完整性和一致性。
2.1.3 选项 D
让我们假设,在您感兴趣的话语域中,一个Person可以扮演两个角色:管理员和作者。这就是选项 D 发挥作用的地方,接下来的断言对于描绘我们的信息图很有用:
通过这种方式,aPerson
在他或她的特定中持有他或她的特定“活动”用户名,UserProfile
并且还可以拥有一个句柄,以防在执行角色时所说的Person
是Administrator
另一个不同的句柄Author
。
您通过评论提到您正在使用 ASP.NET MVC 作为您的应用程序开发平台,尽管我不确定您是否也在使用通用(或默认)ASP.NET 操作过程来处理用户和角色,但本节假设您必须处理典型条件,可以作为很好的参考。
图 3 中建议的方法似乎是可行的,因为您不需要修改通常在 ASP.NET 应用程序中创建的表。如您所见,您只需要创建一个额外的表来保留给定用户可能(或可能没有)与分配给该用户的某个角色有关的句柄(或昵称,或别名,如果您愿意)在您的应用程序中。换句话说,同一个User可以拥有多个Handles,并且每个Handle实例的上下文将是User执行的确切Role 有问题。
附加一个Handle
直接列在UsersInRoles
表中可以可以过,但它可能有不利的后果在ASP.NET身份验证和授权过程,这方面,你也知道,是任何应用程序的安全性最为重要,因此这种方法需要特别的研究和测试。
3.1.1 选项 A
该方法描述了一个Handle
表,该UsersInRoles
表通过由UserId
和RoleId
列组成的复合 FK连接到该表。所述Handle
表准确地为该Handle
列设置了 AK ,这意味着特定句柄值*只能在一行中插入。
3.1.2 选项 B
在此选项中,我描绘了一个Handle
表格,该UsersInRoles
表格也通过由UserId
和RoleId
列组成的 FK来引用该表,但它显示了一种稍微不同的方法,即显示由RoleId
和Handle
列构成的 AK ,这将打开有机会在多行中重复相同的句柄值,但只能与不同的RoleId
值结合使用。
1所 对于信息建模集成定义( IDEF1X)是被确立为一个非常可取的数据建模技术标准是由美国在1993年12月美国国家标准与技术研究院(NIST)。它是有坚实基础的(a)上的一些理论著作的撰写由独家发起的的关系模型,即EF科德博士; 关于 (b)实体关系视图,由PP Chen 博士开发;以及 (c) 逻辑数据库设计技术,由 Robert G. Brown 创建。
2 IDEF1X 将键迁移定义为“将父实体或通用实体的主键作为外键放置在其子实体或类别实体中的建模过程”。
3 ALTERNATE KEY 是一个属性(或属性的组合),它包含唯一标识实体类型出现但未被选为相关实体类型的 PK 的值;每个实体类型可以有零个、一个或多个 ALTERNATE KEY。在 IDEF1X 图中,它们表示为“AK”加上其各自的编号,例如 AK1、AK2 等。它们通常通过 (i) 单列或多列 UNIQUE 约束在逻辑级 SQL DDL 设计中声明连同 (ii) 一个或多个 NOT NULL 约束。