sqlserver表约束设计

sqlserver表约束设计,sql,sql-server,Sql,Sql Server,我有一个SQL server表的设计问题。 我将设备放在一张表中,如下所示: Table Equipments id int PK idCommunications int FK to table Communications (defined below) Name varchar 每个设备只能有一种类型的通信系统(表通信) 每个通信系统可以有任意数量的参数。我不想为我所知道的每个通信系统创建一个特定的表,因为它们不断发展,所以我创建了一个表,列出了参数 Table ParamCommu

我有一个SQL server表的设计问题。
我将设备放在一张表中,如下所示:

Table Equipments
id int PK
idCommunications int FK to table Communications (defined below)
Name varchar  
每个设备只能有一种类型的通信系统(表通信)

每个通信系统可以有任意数量的参数。我不想为我所知道的每个通信系统创建一个特定的表,因为它们不断发展,所以我创建了一个表,列出了参数

Table ParamCommunications
id int PK
idCommunications int FK to table Communications
Parameter varchar
以及另一个表格,其中包含每个设备的每个参数值

Table ConfComEquipment
id int PK
idParamCommunications int FK to table ParamCommunications
idEquipment int FK to table Equipment
Value varchar
此表结构允许我为每个通信系统创建参数列表,并将其分配给一个设备。我发现的问题是,在上一个表中,我可以输入一个idParamCommunications的配置,该配置不属于设备定义的同一个idCommunications

比如说。我有两个通讯系统

id Name
1 Serial
2 TCP/IP
我在表2中有以下参数:

id idCommunications Parameter
1        1            BaudRate
2        1            COMPort
3        2            IPAddress
工作台设备有:

id idCommunications Name
1        1           SerialEquipment
2        2           EthernetEquipment
当我配置表格时,约束不允许我使用任何未定义的设备或未定义的参数,但允许我这样做:

id idCommunications idParamCommunications idEquipment Value
 1      1                   1                2       "somevalue"
id=2的设备的idCommunications=2,但在此设置中,这不是约束条件

我知道我有以下潜在的解决方案:

  • 创建一个复合主键,使用设备和通信来定义它。这将给我带来一个问题,我将需要使用组合来链接到其他一些与通信系统无关的表(此处未显示)
  • 创建另一个表:CommunicationByEquipment,该表将设备链接到其通信系统,然后从ConfComeEquipment表中引用此表的主键
  • 控制程序端的数据完整性。可能更容易出现错误和孤立记录
  • 还有其他我看不到的选择吗?如果没有,你会推荐哪一个

    谢谢你的帮助,很抱歉发了这么长的帖子。我本来打算粘贴显示表格结构的数字,但在获得更高排名之前,我是不被允许的


    Rusty

    没有声明性约束将强制执行您指定的完整性规则。这些类型的完整性规则不能通过唯一约束、外键约束或检查约束的任何组合来实施

    如果需要在数据库中/由数据库强制执行这些完整性规则,您可以选择1)实现触发器(在执行DML操作时触发)和/或2)实现存储过程(代替DML(插入/更新/删除)操作)

    随着完整性规则的发展,这些触发器和/或存储过程将需要维护。正如您所提到的,同样的逻辑也可以在应用程序中实现,作为应用程序和数据库之间的另一层

    问题的关键是关系模型和实体属性值(EAV)模型之间的“阻抗不匹配”


    对于EAV模型,我们不能定义任何有用的外键(除了属性值与实体的基本关联)。如果试图将实体和属性值作为一行返回,则查询更复杂,数量级更复杂,要从EAV模型转换回类似于关系模型中的行的形式。

    鉴于上述信息,我认为如果您在设备表设计中进行一次初始更改,设备和参数之间可能存在多对多关系:

  • 由于每种类型的设备只有一种类型的通信系统,只需将通信系统添加到设备表中即可(通过这样做,您的参数现在是设备的属性,而不是通信系统)
  • (可选)建立一个表,定义各种通信系统和 在下拉列表中使用它
  • (此处有两个选项)
    • a、 构建一个仅定义等级库名称的表(以多对多的形式放置值)。不建议使用,因为规格将变得更加动态
    • b、 建立定义所有参数/规格的表格
  • 建立一个连接设备和参数的表(这是一个多对多关系)
  • 1.表:设备
    -pk
    -fk_通信系统(已定义的下拉通信系统)
    -名称

    2.表格:定义的通信系统
    -pk
    -名称(以太网/串行/等)
    -等等

    3a.表:定义的参数
    -pk
    -名称(如波特率)
    注意:在此场景中,值存储在多对多表中

    3b。表:定义的参数
    -pk
    -名称(名称:波特率)
    -etc(值:速度、等级、范围等)

    4a.表:设备参数
    -pk
    -fk_装备
    -fk_参数(名称)
    -速度(值)
    注意:严格来说,这不是2NF

    4b。表:设备参数
    -pk(考虑复合键)
    -fk_设备
    -fk_参数

    注意:如果您希望避免DUP,您需要在此处使用复合键

    主键不是外键目标的唯一可能性-外键约束也可以将任何唯一索引作为目标。因此,我认为以下结构强化了您的要求:

    create table Communications (
        ID int not null,
        Name varchar(20) not null,
        constraint PK_Communications PRIMARY KEY (ID),
        constraint UQ_Communication_Names UNIQUE (Name)
    )
    go
    create table CommunicationParameters (
        ID int not null,
        CommunicationID int not null,
        Parameter varchar(20) not null,
        constraint PK_CommunicationParameters PRIMARY KEY (ID),
        constraint UQ_CommunicationParameter_Parameters UNIQUE (Parameter),
        constraint FK_CommunicationParameters_Communications
              FOREIGN KEY (CommunicationID) references Communications (ID),
    
        constraint UQ_CommunicationParameters_Communication_XRef
              UNIQUE (ID,CommunicationID)
    )
    go
    create table Equipments (
        ID int not null,
        CommunicationID int not null,
        Name varchar(20) not null,
        constraint PK_Equipments PRIMARY KEY (ID),
        constraint UQ_Equipment_Names UNIQUE (Name),
        constraint FK_Equipments_Communications
              FOREIGN KEY (CommunicationID) references Communications (ID),
    
        constraint UQ_Equipment_Communication_XRef
              UNIQUE (ID,CommunicationID)
    )
    
    最后:

    create table ConfComEquipment (
        ID int not null,
        CommunicationID int not null,
        CommunicationsParameterID int not null,
        EquipmentID int not null,
        Value varchar(99) not null,
        constraint PK_ConfComEquipment PRIMARY KEY (ID),
        constraint FK_ConfComEquipment_CommunicationParameters
              FOREIGN KEY (CommunicationsParameterID) references
                    CommunicationParameters (ID),
        constraint FK_ConfComEquipment_Equipment
              FOREIGN KEY (EquipmentID) references
                    Equipments (ID),
    
        constraint FK_ConfComEquipment_CommunicationParameters_XRef
              FOREIGN KEY (CommunicationsParameterID,CommunicationID) references
                    CommunicationParameters (ID,CommunicationID),
        constraint FK_ConfComEquipment_Equipment_XRef
              FOREIGN KEY (EquipmentID,CommunicationID) references
                    Equipments (ID,CommunicationID)
    )
    
    请注意,正是在名称末尾添加了这些带有
    XRef
    的约束,才允许强制最后一个表中的
    CommunicationID
    列与
    CommunicationParameters
    devices
    表中存储的值一致,同时将这些表上的主键保留为
    ID

    严格来说,这使得“真实”外键、
    FK\u ConfComEquipment\u通信参数
    FK\u ConfComEquipment\u设备
    成为冗余,
    XRef
    约束就足够了。这是可选的,你是否保持这些仍然在你的国际泳联
    create table ConfComEquipment (
        ID int not null,
        CommunicationID int not null,
        CommunicationsParameterID int not null,
        EquipmentID int not null,
        Value varchar(99) not null,
        constraint PK_ConfComEquipment PRIMARY KEY (ID),
        constraint FK_ConfComEquipment_CommunicationParameters
              FOREIGN KEY (CommunicationsParameterID) references
                    CommunicationParameters (ID),
        constraint FK_ConfComEquipment_Equipment
              FOREIGN KEY (EquipmentID) references
                    Equipments (ID),
    
        constraint FK_ConfComEquipment_CommunicationParameters_XRef
              FOREIGN KEY (CommunicationsParameterID,CommunicationID) references
                    CommunicationParameters (ID,CommunicationID),
        constraint FK_ConfComEquipment_Equipment_XRef
              FOREIGN KEY (EquipmentID,CommunicationID) references
                    Equipments (ID,CommunicationID)
    )