1

I have database design quandry...

My system has a series of "missions" and each mission can be assigned either to a single hard-bitten individual or a well-oiled team of crack experts.

Thinking about the usage of the system...

  • Most commonly a person would connect to the system to find out what mission(s) they are assigned to.
  • The next most common thing would be that someone would be assigning teams or individuals to missions
  • And thirdly, of course, there is always the possibility that this coordinator would be wanting to check who is assigned where and to juggle around the personnel as is their wont

My first thought is that a structure like this would be just the ticket:

Option 1

The thing is, in that case, my most common query would have to look something like this:

declare @name nvarchar(1000)
set @name = ...

declare @myId int

-- find out my user id
set @myId = (select top 1 IndividualId from Individuals where Name = @name)

-- Now find all the missions where I am am member of a team that's been assigned
select a.Name
from Missions a
inner join IndividualsInTeams b on a.TeamId = b.TeamId
where a.TeamAssigned = 1 and b.IndividualId = @myId

-- And UNION that with all the missions where I have been solely assigned

union

select  Name
from Missions
where TeamAssigned = 0 and IndividualId = @myId

I figure I can smooth this over by creating a view (called MissionsWithIndividuals ) like so:

select  a.Name As 'MissionName', c.Name As 'IndividualName'
from Missions a
inner join IndividualsInTeams b on a.TeamId = b.TeamId
inner join Individuals c on b.IndividualId = c.IndividualId
where a.TeamAssigned = 1 

union

select a.Name As 'MissionName', b.Name As 'IndividualName'
from Missions a
inner join Individuals b on b.IndividualId = a.IndividualId
where TeamAssigned = 0 

And then my most common query would be:

select MissionName from MissionsWithIndividuals where IndividualName = @name

But that feels kind of dodgy.

I mean, aren't I having to make the database go through a whole bunch of hoops to deal with my most common query. Wouldn't it be better if my data were structured in a way that makes my most common query more natural?

Also, I open the possibility that a mission is assigned to an individual AND a team and that is not really allowed (if it is more than a single person it must be within an allocated team).

I could go instead with this:

option 2

But that, whilst making my most common query easy, feels a bit horrible due to the multi-purpose nature of the TeamOrIndividualName and the fact that I cannot put a constraint on it.

So, what would be the best way to structure my data in this case?

Is there another possibility that I have not considered?

4

1 回答 1

3

正如 Gilbert Le Blanc 所建议的那样,我认为这里的解决方案是将任务与团队联系起来,即使团队中只有一个人。这消除了某人将人员和团队分配给任务的可能性,消除了UNION查询的需要。这但是强制您进行 3 次加入(任务 -> 团队、团队 -> IndividualsInTeams、IndividualsInTeams -> 个人)。如果这太昂贵,那么如果您可以容忍不实时的数据,我建议您每天为您的数据创建一个静态视图。根据您的数据库大小,生成视图的成本可能会也可能不会很高。根据时间成本,您可能希望每天更新两次以获得更准确的数据。这将为您最重要的查询节省时间(为用户 X 分配了哪些任务?)。

于 2013-06-24T19:25:21.077 回答