单列表是一个好的设计吗?

131

只有一列的表格可以吗?

我知道这不是非法的。

例如:

  • 您有一个包含50个有效美国州代码的表格,但您不需要存储冗长的州名。
  • 电子邮件黑名单。

有人提到添加关键字段。但是单列将是主键。


我有点难以想象只有一列的表格有什么用途。你能给个例子吗? - Paul Morie
但请至少不要为其创建索引! - Sathya
4
美国州代码是定义领域的经典示例。 - Quassnoi
4
我曾见过一个数据库表格被用来保存应用程序的锁定值。 - Russ Cam
我使用这个模式是为了创建数据集。主表中的每条记录都有一个SET字段。具有相同SET的记录之间存在连接。如何插入具有相同SET的多条记录?'INSERT INTO sets VALUES ()',然后使用最后插入的ID作为您要附加到记录的SET ID。再说一遍,也许我可以使用UUID,但感觉不太对。 - William Entriken
另一个用例是通常为FALSE的布尔标志。我会创建一个具有一个列的表,该列既是主键又是外键。 - Paul Spiegel
15个回答

185

就关系代数而言,这将是一个一元关系,意思是“这个东西存在”

当然可以有一个定义这样一个关系的表:例如,定义一个域。

这个表的值应该是自然主键。

我首先想到的是一个质数查找表。


4
+1:表是您的RDBMS中恰好是原始类型的一组值。 - S.Lott
9
+1 是基于关系理论提供答案的肯定。 - lubos hasko
这是一个很好的模式示例,其中包含一个不是自然键的1列表,在消息系统中的Thread表中... https://dev59.com/7mw15IYBdhLWcg3wi8Zv#6542556 - JeremyWeir
2
数据库背后的数学理论可以很容易地回答一个问题,为什么这个问题因为“基于观点”的原因被关闭呢? - the VBE - it's right for me

99

是的,设计一张表格使其最有效率是很好的设计。通常所说的“糟糕的RDBMS设计”都集中在效率不高上。

然而,我发现大多数单列设计情况下会从增加一列得到好处。例如,州编码通常可以在第二列中拼写完整的州名,或者黑名单可以关联笔记。但是,如果您的设计确实不需要这些信息,那么使用单列也完全没问题。


1
这个答案非常有用。我觉得很奇怪,这个帖子被关闭了,因为它被认为是“基于观点的”,而这个答案(以及下面的答案)非常清楚地表明它可以用足够事实的方式回答。 - the VBE - it's right for me

30

我以前用过它们。我的一个客户想自动屏蔽那些在他的大黑名单中尝试使用电话号码进行注册的人。


20
如果确实有需要,我认为没有问题。也许你只是想要显示一个可能性列表,并希望能够动态更改它,但没有必要将其链接到另一个表中。

+1 - 总之,在我看来这是正确的答案。 - Mark Brittingham
+1 for concise, clear answer. - Matthew Jones
3
为什么单列表不能与另一个表链接? - Aheho
嗯,这可能是可以的。但我认为大多数情况下这不是一个好主意。 - Kevin
2
为什么不呢?以状态代码表为例,为什么不将其作为外键约束应用于另一个带有地址字段的表中呢? - Aheho
1
这是一个很好的例子,可以考虑在某个时间实施。 - Kevin

13

我发现的一种情况有时是这样的:

表countries_id,只包含一个数字ID的列,用于每个国家。

表countries_description,包含国家ID的列、语言ID的列和本地化国家名称的列。

表company_factories,包含公司每个工厂的信息,包括所在国家。

因此,为了在表中维护数据的一致性和语言无关性,数据库使用具有仅一个列的表结构,以允许没有语言依赖性的外键。

在这种情况下,我认为存在一个列的表是有道理的。

根据Quassnoi的评论编辑:


(来源:ggpht.com)

在这个模式中,我可以在表company_factories 中定义一个不需要在表中包含语言列的外键,但如果我没有表countries_id,我必须在表中包含Language列,以定义外键。


2
为什么需要countries_id?要插入一个国家,你需要至少知道它的一个语言名称,这将导致在countries_description中出现一个country_id。没有countries_description条目的country_id是没有意义的。“COALESCE(14243,country_name)返回空值”的总统奥巴马今天会见了俄罗斯总统德米特里·梅德韦杰夫。 - Quassnoi
4
好的,我明白了。我同意+1。不过我更倾向于使用ISO 3166-1标准来表示国家代码。与数字ID不同,一个由3个字母组成的国家代码可以让世界上几乎所有使用拉丁字母的人都能大概了解所提到的国家是哪个。 - Quassnoi
这是我实现自然语言翻译在同一张表中适应的另一种方式。当然,由于这个原因,许多字段都可以为空,但你可以将数据完整性卸载到自定义触发器上。 创建表"DBA"."myLocalisedTable" ( "entry_id" INTEGER NOT NULL DEFAULT AUTOINCREMENT, "master_entry_id" INTEGER NULL, "master_entry_label" VARCHAR(200) NULL, "language_id" INTEGER NULL, "localised_entry_label" VARCHAR(300) NULL, - Vincent Buck

7

很少情况下单列表才是有意义的。我曾经做过一个数据库,其中有效语言代码列表是一个单列表,用作外键。没有必要使用不同的键,因为代码本身就是关键字。而且在某些情况下,语言代码描述会因语言而异,没有固定的描述。

总的来说,任何需要权威值列表且没有其他属性的情况都适合用单列表。


5
我经常使用单列表——当然前提是应用程序设计已经使用了数据库。一旦我忍受了建立数据库连接的设计开销,我会尽可能地将可变数据放入表格中。
我能想到两种OTMH的单列表用途:
1)数据项存在。常用于下拉列表。也用于简单的合法性测试。
例如,美国州名的两个字母缩写;我们运送的邮政编码;合法的Scrabble单词等。
2)稀疏的二进制属性,即在一个大的表格中,只有很少的记录会具有真值的二进制属性。我可能会创建一个单独的表格,其中包含属性为true的记录的键,而不是添加一个新的布尔列。
例如,患有绝症的员工;采用360天年历的银行(大多数采用365天)等。
-Al.

5

大多数情况下,我在查找类型的表格中看到了这种情况,比如你描述的州表。但是,如果你这样做,请确保将该列设置为主键以强制唯一性。如果无法将此值设置为唯一,则不应使用单个列。


在这里使用单列可能是可以的,但请记住,您也可以在其他列上设置唯一性约束。 - Stealth Rabbi

4
只要包含唯一值,就没有问题。

2
我会说一般来说是的。不确定为什么你只需要一个列。我见过有些例外情况,它们被有效地使用了。这取决于你想要实现什么目标。
当你考虑数据库的架构时,它们并不是很好的设计,但真正应该只用作实用表。
我曾经看到数字表被成功地使用过。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接