我从数据库设计中休息了很长时间(一年多),我刚刚回来。我正在为我正在创建的网站设计一个数据库。我将 2 个布尔值存储在一个表中(两个单独的列)。我意识到,如果第一个值为真,则另一个也将始终为真,但如果第一个值为假,则另一个可以为真或假。就我而言,这不是传递依赖,我不应该创建一个新表,但我想确保我做的一切都是正确的。如果有多个值的行为类似于第二个布尔值,我是否仍将其保留在同一个表中?将此类数据存储在数据库中的最佳方法是什么?
如果 anwser 包含 ER 图,我将不胜感激。
我从数据库设计中休息了很长时间(一年多),我刚刚回来。我正在为我正在创建的网站设计一个数据库。我将 2 个布尔值存储在一个表中(两个单独的列)。我意识到,如果第一个值为真,则另一个也将始终为真,但如果第一个值为假,则另一个可以为真或假。就我而言,这不是传递依赖,我不应该创建一个新表,但我想确保我做的一切都是正确的。如果有多个值的行为类似于第二个布尔值,我是否仍将其保留在同一个表中?将此类数据存储在数据库中的最佳方法是什么?
如果 anwser 包含 ER 图,我将不胜感激。
标准化:
我认为我们应该区分两种情况:
第一种情况可以使用具有两个字段的单个表来解决,因为它保证了良好的性能和空间优化(你不能比这种方式节省更多的空间,除非你忽略规范化规则,我在最后一个解决方案):
MyBools (id, firstBool, secondBool);
关于第二种情况,我提出了两个想法,我都不满意。
我们可以说的主要事情是,当您有长序列时,每个布尔值的列不是很方便。这是我的两个想法:
具有 PK、布尔字段和自引用外键的单个表:
MyBools (id, thisBool, idNextBool);
thisBool
显然包含一个布尔值。如果thisBool
为真,您就完成了,您不需要存储以下布尔值,因为它的值与第一个值匹配。If thisBool
is falseidNextBool
指向以下布尔值。
此解决方案仅允许前向搜索。
具有 PK、布尔值和自引用外键的单个表:
MyBools (id, thisBool, idNextBool);
如果idNextBool
为 null,则您已达到序列的第一个值。否则idNextBool
指向以下布尔值。
此解决方案仅允许向后搜索。
如您所见,第二种情况(序列长于 2 个值)的解决方案相当难以管理。
这就是我提出非标准化解决方案的原因。
未标准化:
您可以将这些布尔值视为数字字段的位(特别是考虑到布尔值实际上由位表示)。假设我们有两个字段field1
和field2
,并考虑我们可以将它们放在一个字段中(我们称之为myfield
):
1) IF field1 is True THEN field2 True myfield = 0
__ True myfield = 10
2) IF field1 is False THEN field2 /
\__ False myfield = 11
如您所见,您可以将其扩展到尽可能多的布尔值,以适应数字字段(例如,在 32 位数字字段中,您可以存储 32 个布尔值,只要每个布尔值取决于较低的值)。
它不是函数依赖,因此它不是传递函数依赖。
根据定义,X -> Y 当且仅当每个 X 值都与一个 Y 值相关联。
在您的情况下,当 X 为假时,Y 可能是以太真或假,因此上述定义不成立。
不过,它看起来确实像一个多值依赖项。
除了添加适当的 CHECK 约束之外,我不确定您是否应该对此做任何事情(使事情复杂化的成本对于预期的收益来说太高了)。
我想到了一个解决方案,但我不知道它是否有任何好处。如果第一个值为假,我可以使用 FK 为所有其他值创建另一个表,如果值为真,则存储其他值,我无法为这些值生成表,因为无论如何它们都将为真
你的问题有点模糊,但我会试一试。首先,根据您的描述,您没有传递依赖。原因是,你只提到了两个,我假设你的表中的属性,当传递依赖需要三个属性存在时。
当 A 隐含 B 且 B 隐含 C 时,存在传递依赖。换句话说,A 通过 B 传递隐含 C。
无论如何,我认为寻找具有小数据样本且没有上下文的功能依赖关系会导致糟糕的数据库设计。你的表中有哪些元素?