【问题标题】:Problem with designing one to one relationship sql设计一对一关系sql的问题
【发布时间】:2019-07-07 17:03:02
【问题描述】:

一个设备只能分配给员工或车辆一次,我有两种方法来建立关系,在第一种方法中,我将表 EquipmentAssigned 与两个外来的表分配给它们的依赖表。我这种方法在每一行中都会有一个字段为空,因为设备只能分配一次。

在第二种方法中,我有两个表:EquipmentEmployee 和 EquipmentVehicle,在这种方法中没有空值。

根据数据库设计原则,我不知道哪种方法更适合这种情况

方法 1

方法 2

我无法更改设备表,我只需要创建设备与员工和车辆之间的关系。

更新:

设备表仅包含有关设备的信息,关系在 EquipmentAssigned 表中(方法 1)或 [EquipmentEmployee, EquipmentVehicle] 表中(方法 2)。我正在寻找一种不会有空字段的方法。图表可以从左到右阅读。

【问题讨论】:

    标签: sql sql-server database-design


    【解决方案1】:

    我建议你有一个名为 EquipmentAssignment 的交叉引用表

    应该是这样的

    Create Table EquipmentAssignment(
    EquipmentId int not null 
    AssignedId   int  not null
    AssignedType  varchar(10) not null
    ) 
    

    AssignedType 可以是“Vehicle”或“Employee”(或 V/E 等等...)

    我已经使用这种模式在处理类似情况时取得了巨大成功。

    这允许类似下面的视图来帮助您轻松处理受让人的 2 个表性质

    create View Assignees
    as
    ;with assignees as (
    Select Name [AssigneeName], Id [AssigneeId], convert(varchar(10),'Employee') as [AssigneeType] from Employee
    union 
    Select Name, Id, convert(varchar(10),'Vehiclle') as [AssigneeType] from Vehicle
    )
    
    select  e.*, a.* 
    from EquipmentAssignment ea 
    join assignees a  on ea.AssigneeId = a.AssigneeId and ea.AssigneeType = a.AssigneeType
    

    【讨论】:

      【解决方案2】:

      请提供更多信息:在设备表中,字段的含义是什么?

      Id : 设备的唯一标识符

      Code = 你这里有 Vehicle.Code 或 Employee.Unitid 吗?

      设备类型:(我想是车辆还是雇员?)

      如果是这种情况,一个合适的解决方案是有一个带有字段的表 EquipmentType :

      ID:1 代表员工,2 代表车辆
      标签:员工、车辆

      然后在表设备中,您有: (我将使用符号:TableName.FieldName)

      Equipment.EquipmentType = EquipmentType.Id(即 1 或 2)

      Equipment.Code = Vehicle.Code 或 Employee.Unitid

      问候。

      【讨论】:

      • 我建议我已经写过的方法。它是工业中使用的那种BD结构。我看到@greg 提出了类似的解决方案。
      【解决方案3】:

      我不明白您为什么需要任何中间表,因为您指定最多有一个分配。两个更好的选择将引用直接放在Equipment

      第一个可以很容易地指定外键关系:

      create table Equipment (
          EquipmentId int identity primary key,
          . . . ,
          EmployeeId int references employees(EmployeeId),
          VehicleId int references vehicles(VehicleId),
          check (employeeId is null or vehicleId is null)
      );
      

      第二个没有:

      create table Equipment (
          EquipmentId int identity primary key,
          . . . ,
          ReferenceId int references employees(EmployeeId),
          ReferenceType varchar(10),
          check (ReferenceType in ('Employee', 'Vehicle')
      );
      

      【讨论】:

      • 我同意第一个选项。我使用中间表来避免空字段,例如,如果我将设备分配给车辆,则字段 EmployeeId 将为空,这是我第一次遇到这个问题,所以如果保留空字段是一个好习惯,我不会这样做
      • 当您的客户添加更多分配目标时会发生什么?您必须添加更多字段。
      猜你喜欢
      • 1970-01-01
      • 2019-05-10
      • 2013-05-27
      • 2014-02-17
      • 2014-11-06
      • 2015-08-05
      • 2018-10-20
      • 2013-02-08
      • 1970-01-01
      相关资源
      最近更新 更多