什么是表示数据库中两个不同用户输入的数据的有效方式

时间:2012-01-04 13:33:01

标签: sql sql-server database

我有一个名为Request的表格,数据将由两种类型的用户(公司员工和网站成员)输入。最初我有一个名为createdby的列。但是,人员和成员表主键是具有身份的整数。所以我不得不改变它,因为可能有一个ID对应于两个实体。

然后我在请求表ByStaffIdByMemberID中创建了两列。我想知道这是否正确。

4 个答案:

答案 0 :(得分:5)

鉴于现有表的约束,您的方法听起来很合理,这意味着您将能够从Request表创建外键约束到Staff和Member表。使用先前的方法(单个CreatedBy字段)创建任何外键约束是不可能的。

如果有机会重构现有设计,请考虑将Staff和Members视为同一抽象类型的子类(例如“User”),使用其中一种模式将继承映射到描述的here关系表

答案 1 :(得分:4)

现在为您设置的方法是通过创建两列来完成的是解决方案。

但是,这不是一个好的。基本上,您应该只有一个Users表,以某种方式区分用户类型,如单独的表(角色,用户类型等)。然后,您将能够在Request表中拥有一个外键,该外键将引用创建初始请求的用户。

答案 2 :(得分:2)

下面是如何使用与StaffUser表和MemberUser表具有一对一关系的公共User表将Staff和Members关联在一起的示例。

当然,这种方法在选择/插入/更新/删除用户时会带来更大的复杂性,因此您可以决定这是否值得额外的复杂性。

create table [User]
(
    UserID int identity(1,1) not null primary key,
    Username nvarchar(50) not null
)

create table StaffUser
(
    UserID int not null primary key references [User] (UserID),
    FirstName nvarchar(50) not null,
    LastName nvarchar(50) not null
)

create table MemberUser
(
    UserID int not null primary key references [User] (UserID),
    Email nvarchar(100) not null,
)

create table Request
(
    ByUserID int not null references [User] (UserID),
)

declare @UserID int

insert into [User] values ('john.smith')
set @UserID = scope_identity()
insert into StaffUser values (@UserID, 'John', 'Smith')

insert into Request values (@UserID)

insert into [User] values ('billy.bob')
set @UserID = scope_identity()
insert into StaffUser values (@UserID, 'Billy', 'Bob')

insert into Request values (@UserID)

insert into [User] values ('member1')
set @UserID = scope_identity()
insert into MemberUser values (@UserID, 'member1@awesome.com')

insert into Request values (@UserID)

insert into [User] values ('member2')
set @UserID = scope_identity()
insert into MemberUser values (@UserID, 'member2@awesome.com')

insert into Request values (@UserID)

insert into [User] values ('member3')
set @UserID = scope_identity()
insert into MemberUser values (@UserID, 'member3@awesome.com')

insert into Request values (@UserID)

-- select staff
select
    StaffUser.UserID,
    [User].Username,
    StaffUser.FirstName,
    StaffUser.LastName
from StaffUser
inner join [User] on
    [User].UserID = StaffUser.UserID

-- select members
select
    MemberUser.UserID,
    [User].Username,
    MemberUser.Email
from MemberUser
inner join [User] on
    [User].UserID = MemberUser.UserID


-- select all users
select
    StaffUser.UserID,
    [User].Username
from StaffUser
inner join [User] on
    [User].UserID = StaffUser.UserID

union all

select
    MemberUser.UserID,
    [User].Username
from MemberUser
inner join [User] on
    [User].UserID = MemberUser.UserID


select * from Request


drop table Request
drop table MemberUser
drop table StaffUser
drop table [User]

<小时/> 下面是一个稍微复杂一点的结构,完成与上面例子相同的事情,但在这种情况下,会员和员工与用户的联系更加紧密。

create table [User]
(
    UserID int identity(1,1) not null primary key,
    CreatedOn datetime not null default getdate()
)

create table StaffUser
(
    UserID int not null primary key references [User] (UserID)
)

create table MemberUser
(
    UserID int not null primary key references [User] (UserID)
)

create table Staff
(
    StaffID int identity(1,1) not null primary key,
    FirstName nvarchar(50) not null,
    LastName nvarchar(50) not null,
    UserID int null references StaffUser (UserID),
)

create table Member
(
    MemberID int identity(1,1) not null primary key,
    Username nvarchar(50),
    Email nvarchar(100) not null,
    UserID int null references MemberUser (UserID),
)

create table Request
(
    ByUserID int not null references [User] (UserID),
)

declare @UserID int

insert into [User] default values
set @UserID = scope_identity()
insert into StaffUser values (@UserID)
insert into Staff values ('John', 'Smith', @UserID)

insert into Request values (@UserID)

insert into [User] default values
set @UserID = scope_identity()
insert into StaffUser values (@UserID)
insert into Staff values('Billy', 'Bob', @UserID)

insert into Request values (@UserID)

insert into [User] default values
set @UserID = scope_identity()
insert into MemberUser values (@UserID)
insert into Member values ('member1', 'member1@awesome.com', @UserID)

insert into Request values (@UserID)

insert into [User] default values
set @UserID = scope_identity()
insert into MemberUser values (@UserID)
insert into Member values ('member2', 'member2@awesome.com', @UserID)

insert into Request values (@UserID)

insert into [User] default values
set @UserID = scope_identity()
insert into MemberUser values (@UserID)
insert into Member values ('member3', 'member3@awesome.com', @UserID)

insert into Request values (@UserID)

-- select staff
select
    Staff.StaffID,
    Staff.FirstName,
    Staff.LastName,
    Staff.UserID
from Staff

-- select members
select
    Member.MemberID,
    Member.Username,
    Member.Email,
    Member.UserID
from Member

-- select all users
select
    [User].UserID,
    Staff.FirstName + ' ' + Staff.LastName as Name,
    [User].CreatedOn
from [User]
inner join Staff on
    Staff.UserID = [User].UserID

union all

select
    [User].UserID,
    Member.Username as Name,
    [User].CreatedOn
from [User]
inner join Member on
    Member.UserID = [User].UserID


select * from Request


drop table Request
drop table Member
drop table Staff
drop table MemberUser
drop table StaffUser
drop table [User]

答案 3 :(得分:0)

为什么您想要使用单独的表来区分成员和员工?我宁愿实现Role表,并按指定的角色区分用户。

.createdby列可能引用其中一个表?不好的想法,但如果你在员工和记忆中使用Guid作为主键,它可能会有用