将外键用于单独的表而不是使用布尔值(即SQL Server中的BIT)时会出现什么情况
例如,您可以在此表中替换以下两个布尔值:
engine_sensors
--------------
id (int, primary key)
name (varchar(50))
fault_code (int)
display_warning (boolean) /* if fault show driver a warning */
is_test_sensor (boolean) /* ignore this sensor in diagnostic checks */
e.g。 display_warning这里可能不会向驱动程序显示警告,但会向正在测试引擎的机械师显示警告。因此,单独的表格是合适的。
is_test_sensor可以替换为sensor_type(FK到sensor_types表),它有类型的test,live。
答案 0 :(得分:4)
如果字段模拟布尔值,我会将它们保留为布尔值。这就是他们存在的原因。
我不会尝试将来证明我的数据库设计(YAGNI原则),您可以随时更改它。
答案 1 :(得分:2)
这取决于你为什么要避免它。您可以将数字字段的0表示为false,将1表示为true。不确定是否有任何好处。
答案 2 :(得分:1)
您添加了一条信息
'它是一个SQL Server数据库,我知道你使用了一个位字段。我想知道将外键替换为单独的表是多么糟糕'
如果这对您寻求的解决方案很重要,您应该编辑原始问题并将其放入,以便更多人能够轻松找到它。
但你仍然没有说为什么你想知道用FK替换它们。如果您告诉人们您的最终目标是什么或您想要实现的目标,他们更有可能提供一系列解决方案。
对不起,我无法提出解决方案。外键(对于什么?)比布尔值更好?相比?
我认为你需要澄清/重新构建你的问题。祝你好运。
答案 3 :(得分:1)
Np个。现在我看到你的目标(我想)。
如果你问的是我认为你问的是什么,你可能想要将FK用于传感器表并列出传感器。这通常就是我要做的......
CREATE TABLE [SensorType](
[Id] [int] NOT NULL,
[Type] [int] NOT NULL,
[DisplayWarningTo] [int] NOT NULL,
[Description] [nvarchar](100) NULL,
CONSTRAINT [PK_SensorType_Id] PRIMARY KEY (Id),
CONSTRAINT [FK_SensorType_WarningReceivor] FOREIGN KEY (DisplayWarningTo) REFERENCES WarningReceivor(Id)
);
CREATE TABLE [WarningReceiver](
[Id] [int] NOT NULL,
[Receiver] [int] NOT NULL,
CONSTRAINT [PK_WarningReceiver_Id] PRIMARY KEY (Id)
);
------
INSERT INTO WarningReceiver(Id, Type) VALUES (1, 'Mechanic');
INSERT INTO WarningReceiver(Id, Type) VALUES (2, 'Driver');
INSERT INTO SensorType(Id, Type, DisplayWarningTo) VALUES (1, 'Rear sensor', 2);
INSERT INTO SensorType(Id, Type, DisplayWarningTo) VALUES (2, 'Test sensor', 1);
INSERT INTO SensorType(Id, Type, DisplayWarningTo) VALUES (3, 'Production sensor', 2);
我倾向于不在“类型”这样的事情上使用标识列并指定我自己的id,我将其直接映射到C#枚举常量,如
public enum SensorType
{
RearSensor = 1,
TestSensor = 2,
ProductionSensor = 3
}
然后在您的代码中,当您从数据库中拔出引擎传感器时,您可以只比较您的枚举。 e.g。
var engine_sensor = // get engine sensor from db.
if (engine_sensor == (int)SensorType.RearSensor)
{
// do something
}
else if (engine_sensor == (int)SensorType.TestSensor)
{
// display something to mechanic or whatever
}
我真的不知道您的应用程序域是什么,如果这没有意义,那就很抱歉。
所以要结束几点并尝试回答你的问题;
最后,如果您有一个FK表,它会强制执行参照完整性,并将您可以作为传感器类型输入的值限制为您在传感器类型表中定义的值。
希望这有所帮助。
答案 4 :(得分:1)
id(主键) 名称 fault_code
id(主键,FK到engine_sensors)
id(主键,FK到engine_sensors)
请记住:代码很差,表格很丰富。无论这看起来多么矛盾:永远不要用布尔来表示真值信息。关系模型已经有了一种表示真值信息的方法,就像某些关系中某些元组的存在一样,这是某些relvar的值(在SQL术语中:表中存在某些行)。 / p>
您不能轻易“扩展”布尔值以添加额外的功能,例如“仅在时间在[x小时 - 小时]范围内时显示警告。
答案 5 :(得分:1)
关系理论可以帮助您回答问题。布尔值的位置(在所示的表中或在示例中描述的单独的表中)应该由布尔数据元素依赖(并且完全依赖)的内容来确定。
例如,如果数据元素“display_warning”仅依赖于传感器(您的表所描述的实体),则该列属于该表。但是,如果它依赖于其他实体(人 - 所有者或机制 - 与传感器交互),则它更恰当地属于不同的表,在该表中它可以完全且仅依赖于该表的主键。
通过数据的“规范化”确保数据元素依赖于密钥(除密钥之外的其他任何东西)。这里包含的答案很多,但网上有很多参考资料可以帮助您更全面地理解规范化。维基百科是一个很好的起点:
http://en.wikipedia.org/wiki/Database_normalization#Normal_forms
答案 6 :(得分:1)
索引是避免布尔类型的一个原因。你可以; t索引布尔字段,所以如果你有很多记录并经常在布尔字段上搜索,那么拥有一个单独的表可能会有所帮助。如果添加更多类型,单独的传感器类型表也更具可扩展性。如果特定传感器类型成为一对多关系,也会有所帮助。假设发动机需要三种特定类型的传感器。
答案 7 :(得分:0)
首先,我想确认一下Oded。如果需要布尔值,则应使用负责的列类型。
但是,如果你必须存储非常不同的布尔值,那么使用存储在INT,BIGINT甚至BINARY列中的旧学位掩码有时会更有用。
答案 8 :(得分:0)
如果您仍希望在代码中使用布尔值,则在SQL服务器(0或1)中使用“bit”将自动映射回linq中的布尔值。
但是你还没有说明你想要替代bool的数据库或原因。