数据库结构,用户+用户类型,其中用户可以是多个类型

时间:2013-03-05 22:47:19

标签: c# asp.net sql-server

我目前有一个用户表tblUser和一个用户类型表tblUserTypes

这两者通过tblUser... fkUserTypeID中的外键链接进行链接。

因此,目前用户只能是一种类型。

但是,在某些情况下,用户可以是多种类型的...例如,Customer以及Supplier

对我来说,显而易见的解决方案是在tblUsertblUserTypes之间创建一个新表,tblUser_UserTypes这是一个桥接表:

[tblUser] ---< [tblUser_UserTypes] >--- [tblUserTypes]

但是,我可以看到由此引起的复杂性...例如,当导出加入其用户类型的用户列表时,通过直接连接,我将最终得到这些用户的多行。有可能使用PIVOT查询将每个用户记录带回一行吗? (更多信息如下)

将用户导入系统似乎也有问题......我目前正在使用文件中的BCP(批量复制过程)将用户直接导入用户表...导入文件包含单个字段“用户类型”在现有模型中有效,因为每个用户当前只能是一种类型。但是,对于多种用户类型,我无法看到直接BCP如何直接进入用户表。

增加复杂性的是用户类型目前尚未修复...表tblUserTypes是动态的......系统的一部分是允许创建任意数量的用户类型。但是,我需要了解一些类型的用户才能在更高级别定义业务逻辑.... “只允许在此区域中使用type = x的用户”...因此有人建议在用户类型表中有一系列标志,用于定义用户键入的类型(例如IsCustomer), IsSupplier

这感觉就像一个过于复杂的混乱,我在如何前进中失去了睡眠。

我希望将用户类型带回到表tblUser中并完全取消其他两个表...用户表中的一系列复选框(例如IsCustomer,{{ 1}})...因为这使得直接导入和导出。然后,用户类型将不是动态的。有趣的是,虽然用户类型不是完全动态的......因为如上所述,在商业登录方面我需要了解一些用户类型。

嗯,它应该是两者的混合体吗?我想把两个功能压缩成一个吗?也许我可以在用户表中使用与业务逻辑相关的类型的复选框/布尔类型(例如IsSupplierIsCustomer)并将IsSupplier的上下文重命名为{{1或类似的东西。

对我来说,一个主要的问题是在考虑直接连接将导致用户被复制的结构时对导入,导出和搜索结果的影响......他们所属的每种用户类型都有一行。我必须做一个PIVOT查询,将每个用户的记录带回一个记录,每个用户类型都有一列,不是吗?一个现实的例子是一个包含300万条记录的User表,一次导入10,000条记录......或者一次导出10,000条记录......或搜索这300万条记录以检索3,000条匹配并在网页上呈现以分页的方式,他们可以浏览搜索结果页面(我在搜索查询中使用"User Types"来处理分页,我不会每次都返回整个页面。)

这是我关于Stack Overflow的第一个问题,如果它有点复杂或者已经列出了答案,我很抱歉......我试图搜索但是无法提供处理与用户合作的复杂性的示例可以是多种类型。

哦,如果它很重要......这是一个使用SQL Server的C#ASP.NET应用程序。


在仔细考虑并阅读回复后,我将一路走下去并使用桥接表...要求说用户可以是多种类型,这样就可以了。对现有代码的后果是戏剧性的,但现在比在赛道上更好。

我玩桌面结构,在平面结构中获取数据所需的查询有点繁琐,最终需要动态SQL(因为用户类型列表是动态的),我不喜欢它但我看不到另一种方法。

在下面的示例中,提取的公司将通过“事件ID”(即fkEventID

)进行过滤

如果有更好的方法来实现'扁平',我会非常感谢任何帮助:-)


直接前进联接(如果每个公司有多个类型,则为多行)

"User Groups"


硬编码数据透视查询(如果每个公司有多个类型,但公司类型不是动态的,则每个公司有一行)

ROWNUM


动态数据透视查询(每个公司有多行并处理动态公司类型)

select * from tblCompany 
left join tblCompany_CompanyType on fkCompanyID = pkCompanyID
left join tblCompanyType on fkCompanyTypeID = pkCompanyTypeID
where tblCompany.fkEventID = 1

1 个答案:

答案 0 :(得分:0)

您确实在用户和用户类型之间存在多对多的关系,我建议您继续以这种方式实施。

如果您需要在某些情况下看到它变平,您可以通过视图或存储过程来容纳它。

如果要继续使用BCP导入,可以始终将BCP导入临时表,然后使用存储过程来填写3个表。无论如何,这样做可能更安全。

保持完全实现多对多关系将为您提供应用程序中最大的灵活性,并且当您获得新安全角色的新要求时,将阻止您不断地修改用户表。