Sql 我应该如何处理多个外键,这些外键都指向另一个表中的同一列?

Sql 我应该如何处理多个外键,这些外键都指向另一个表中的同一列?,sql,sql-server,Sql,Sql Server,假设我有这两张桌子 IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='UnitsDef' AND xtype='U') CREATE TABLE UnitsDef ( UnitsID INTEGER PRIMARY KEY, UnitsName NVARCHAR(32) NOT NULL, UnitsDisplay NVARCHAR(8) NOT NULL ); IF NOT EXISTS (SELECT * FRO

假设我有这两张桌子

IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='UnitsDef' AND xtype='U')
CREATE TABLE UnitsDef
(
    UnitsID INTEGER PRIMARY KEY,
    UnitsName NVARCHAR(32) NOT NULL,
    UnitsDisplay NVARCHAR(8) NOT NULL
);

IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='Dimensions' AND xtype='U')
CREATE TABLE Dimensions
(
    DimID INTEGER PRIMARY KEY IDENTITY(0,1),
    DimX FLOAT,
    DimXUnitsID INTEGER DEFAULT 0,
    DimY FLOAT,
    DimYUnitsID INTEGER DEFAULT 0,
    DimZ FLOAT,
    DimZUnitsID INTEGER DEFAULT 0,
    FOREIGN KEY (DimXUnitsID) REFERENCES UnitsDef(UnitsID), 
    FOREIGN KEY (DimYUnitsID) REFERENCES UnitsDef(UnitsID),
    FOREIGN KEY (DimZUnitsID) REFERENCES UnitsDef(UnitsID)
);
我将在第一个表中插入与此类似的数据

INSERT INTO UnitsDef (UnitsID, UnitsName, UnitsDisplay) VALUES (0, 'inch', 'in.');
INSERT INTO UnitsDef (UnitsID, UnitsName, UnitsDisplay) VALUES (1, 'millimeter', 'mm');
INSERT INTO UnitsDef (UnitsID, UnitsName, UnitsDisplay) VALUES (2, 'degree', '°');
我这样做对吗?这是问题的一个简化版本,但我需要知道每个度量单位是什么。对于这种情况,是否有更好的设计实践


如何处理这些外键的删除和更新操作?如果我尝试级联删除和更新,SQL Server将不会对此感到高兴。

您的方法非常好。我会立即建议UnitsId是一个标识列,因此它会递增。您的插入将是:

INSERT INTO UnitsDef (UnitsName, UnitsDisplay) VALUES ('inch', 'in.');
INSERT INTO UnitsDef (UnitsName, UnitsDisplay) VALUES ('millimeter', 'mm');
INSERT INTO UnitsDef (UnitsName, UnitsDisplay) VALUES ('degree', '°');
您还应该使字符串列在UnitsDef中唯一,并为它们提供区分大小写的排序规则。毕竟,Ml和Ml是两个不同的东西,M是mega,M是milli


您可能还希望将单位和值合并为一种类型。这既有积极的一面,也有消极的一面。对我来说,它增加了开销,但如果您想支持更完整的类型代数,它会有所帮助。

这正是您必须要做的。不确定sql server对级联删除/更新不满意是什么意思?我认为你不会做任何更新。这意味着您不会将英寸从0更改为8或其他。请记住,如果级联删除,则意味着如果删除UnitsDef,将删除维度中的整行。删除集NULL可能更好。@SeanLange这样的fk数量有限制吗?一张真正的桌子可能有10张左右。不过,关于更新时和删除时,您可能是对的。UnitDef可能永远不会更改。可能需要再次检查多个外键是否可以使用。在我脑海中的某个地方,我记得对同一列使用SET NULL或DELETE以及多个外键可能会导致多周期错误。试试看。确实没有限制,但这些限制高得离谱。我仍然对UnitsID持怀疑态度。我最初把它作为身份,但最近删除了它。在最终版本中,我可能会把它放回去。