如何建立这种一对一的关系?

时间:2010-04-14 11:59:15

标签: database model entity-relationship

我有几个实体可以解析需要能够登录特定系统的不同类型的用户。此外,他们还有与之相关的不同类型的信息。

例如:“普通用户”,其具有电子邮件地址和“管理员用户”,其具有工作站编号(请注意,这是一个假设的情况)。两个实体还共享公共属性,如姓名,地址和电话号码。最后,他们自然需要有一个(唯一的)用户名和密码才能登录。

在应用程序中,用户只需填写用户名和密码,应用程序的功能就会根据用户的类型略有变化。你可以想象用户名需要对这项工作是唯一的。

我应该如何有效地模拟这个?

我不能只创建两个表,因为那时我无法在用户名上强制使用唯一的constaint。

我也不能将它们全部放在一个表中,因为它们有不同类型的特定信息。

我想我可能需要3个单独的表,一个用于“用户”(用户名和密码),一个用于“普通用户”,另一个用于“管理员用户”,但这些工作之间的关系如何? ?还是有另一种解决方案吗?

(顺便说一下,目标DBMS是MySQL,所以我不认为数据库系统本身支持泛化。)

5 个答案:

答案 0 :(得分:0)

两张桌子。具有用户名,第一个,最后一个等的用户。具有角色的ROLES,以及返回用户名(或用户ID或其他)的链接。对用户名添加唯一约束。将工作站nbr,电子邮件,电话以及其他任何需要放在用户表中。在ROLES表中放置2列 - USERID和ROLE。

答案 1 :(得分:0)

你的3桌表示似乎没问题。 在users表中只有ID,用户名,密码,usertype。 一般来说,users表有ID,UserID(来自users表),其他字段。 管理员用户也是如此。

Usertype字段将告诉您从哪个表中搜索其他信息

if(usertype==admin)
  select * from  admins where userid=:id;
else    
  select * from  general where userid=:id;

答案 2 :(得分:0)

您应该决定存储多少特定信息(或将来可能存储的信息)并根据该信息做出决定。如果每种用户类型只有少数几个字段,那么使用单个表就没问题。

USERS表(名称,类型,电子邮件,密码,genfield1,genfield2,adminfield1,adminfield2)

确保包含类型(不要假设因为用户属于该类型的某些特定于该用户的字段)字段。任何查询都只需要包含“AND usertype =”子句。

如果每种类型都有许多字段或规则,那么您对三个表的想法是最好的。

USERS表(ID,类型,名称,密码)
GENUSERS(ID,genfield1,genfield2)
ADMINUSERS(ID,adminfield1,adminfield2)

表中ID之间的约束是您所需要的(并且主USERS表保持ID唯一)。在大多数情况下都能很好地工作,但包含两种类型用户及其特定字段的报告必须分两部分完成(联合SQL或子查询或多个左联接)。

答案 3 :(得分:0)

您可以使用一个“常规”用户表来解决它,其中包含可供所有用户使用的信息,以及每个特定用户类型的1个表。在您的示例中,您将需要3个表。

用户:此表仅包含所有usertypes之间共享的信息,即。 UserId,姓名,地址等

GeneralUsers:此表通过提供引用Users表的foreing键UserId来“扩展”Users表。此外,这里还有特定于一般用户的信息,fx。 EmailAddress等

AdminUsers:与GeneralUsers一样,此表还通过提供引用Users表的外键UserId来“扩展”Users表。另外,管理员用户的特定信息在这里举行,fx。 WorkstationId等

使用这种方法,如果需要,只需添加使用外键引用“扩展”Users表的新表,就可以添加其他“特化”。您还可以创建多个级别的专业化。例如,如果管理员用户是普通用户以及管理员用户,则AdminUsers可以通过使用常规密钥而不是用户来扩展'GeneralUsers而不是用户。

当您需要从此模型中检索数据时,您需要查询哪种类型的用户。例如,如果您需要查询GeneralUser,则需要类似于:

的内容

SELECT * FROM GeneralUsers 在GeneralUsers.UserId = Users.UserId

上LEFT JOIN用户

或者查询管理员用户

SELECT * FROM AdminUsers LEFT JOIN用户ON AdminUsers.UserId = Users.UserId

如果您有其他级别的专业化,例如让管理员用户也是普通用户,那么您就可以加入回来。

SELECT * FROM AdminUsers LEFT JOIN GeneralUsers ON AdminUsers.UserId = GeneralUsers.UserId 在GeneralUsers.UsersId = Users.UserId

上LEFT JOIN用户

答案 4 :(得分:0)

我绝对不会像GeneralUser,AdminUser和ReadOnlyUser那样使用单独的表进行模型。

在数据库设计中,一个好的经验法则是“Down beats across”。我将创建一个SystemUsers表和一个Roles表,并定义一个连接表以将SystemUsers放入角色中,而不是多个表(每种类型一个)。另外,我会定义个人角色。

这样,可以在多个角色中添加和删除用户。

角色可以拥有多个权限,可以随时修改。

加入其他地方不需要GeneralUserId,AdminUserId和ReadOnlyUserId列 - 只需一个SystemUserId列。

这与基于ASP.Net角色的安全模型非常相似。

alt text http://img52.imageshack.us/img52/2861/rolebasedsecurity.jpg