【问题标题】:Is a one column table good design? [closed]单列表是好的设计吗? [关闭]
【发布时间】:2010-10-31 09:40:06
【问题描述】:

可以有一个只有一列的表吗?我知道这在技术上并不违法,但它是否被认为是糟糕的设计?

编辑:

这里有几个例子:

  • 您有一个包含 50 个有效美国州代码的表,但您无需存储详细的州名称。
  • 电子邮件黑名单。

有人提到添加一个关键字段。在我看来,这一列将是主键。

【问题讨论】:

  • 我很难想象一个只有一列的表的用例。能举个例子吗?
  • 但至少不要为它创建索引!
  • 美国州代码是定义域的经典示例
  • 我之前见过一个数据库表用来保存应用程序的锁值
  • 我使用这种模式是为了创建数据集。主表中的每条记录都有一个 SET 字段。具有相同 SET 的记录被连接。如何使用相同的 SET 插入多条记录? 'INSERT INTO sets VALUES ()' 然后使用最后一个插入 ID 作为您的 SET ID 以附加到记录。再说一次,也许我可以使用 UUID,但感觉有些不对劲。

标签: sql database-design


【解决方案1】:

relational algebra而言,这将是一个一元关系,意味着“这个东西存在

是的,有一个表来定义这样的关系很好:例如,定义一个域。

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

prime numbers 的查找表是我首先想到的。

【讨论】:

  • +1:该表是一组恰好是 RDBMS 的原始类型的值。
  • +1 用于提供基于关系理论的答案。
  • 这是一个很好的例子,它有一个非自然键的 1 列表,消息系统中的 Thread 表...stackoverflow.com/a/6542556/45767
  • 一个很容易被数据库背后的数学理论回答的问题如何因为过于“基于意见”而被关闭?
【解决方案2】:

是的,以最高效的方式设计表格当然是一个很好的设计。 “糟糕的 RDBMS 设计”通常以低效率为中心。

但是,我发现大多数单列设计案例都可以从附加列中受益。例如,州代码通常可以在第二列中拼写出州全名。或者黑名单可以关联注释。但是,如果您的设计确实不需要这些信息,那么使用单列是完全可以的。

【讨论】:

  • 这个答案非常有用。我觉得奇怪的是,当这个答案(以及它下面的答案)非常清楚地表明它可以以足够真实的方式回答时,这个帖子被关闭为过于“基于意见”。
【解决方案3】:

我过去曾使用过它们。我的一个客户想要自动阻止任何人试图用他拥有的这个大名单中的电话号码注册,所以这只是一个大黑名单。

【讨论】:

    【解决方案4】:

    如果确实需要它,那么我认为没有问题。也许您只是出于某种原因想要显示一个可能性列表,并且您希望能够动态更改它,但不需要将其链接到另一个表。

    【讨论】:

    • +1 - 底线,这是我书中的正确答案
    • +1 简洁明了的答案。
    • 为什么一列表不能链接到另一个表?
    • 为什么不呢?以状态码表为例。为什么不将其用作针对具有地址字段的另一个表的外键约束?
    • 这是一个很好的例子,说明这将是一个好主意。
    【解决方案5】:

    我有时发现的一个案例是这样的:

    countries_id,每个国家只包含一列数字ID。

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

    company_factories,包含公司每个工厂的信息,包括位于威奇的国家/地区。

    因此,为了保持表中的数据一致性和与语言无关的数据,数据库将这种模式与只有一列的表一起使用,以允许外键没有语言依赖性。

    在这种情况下,我认为单列表的存在是合理的。

    根据评论编辑: Quassnoi


    (来源:ggpht.com

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

    【讨论】:

    • 为什么要有country_id?要插入一个国家,您需要知道它的名称至少是一种语言,这将导致 country_id 出现在 countries_description 中。没有 country_description 条目的 country_id 是没有意义的。 "COALESCE(14243, country_name) 总裁 Barack Obama 先生返回空值,今天会见了 Россия 总裁 Dmitry Medvedev"
    • @Doliveras:好的,我知道了,+1。但是,我宁愿将 ISO 3166-1 用于 coutry_code。与数字 id 不同,3 个字母的国家/地区代码可以让世界上几乎所有可以阅读拉丁字母的人都知道提到的国家/地区。
    • 这是我为在同一个表中容纳自然语言翻译而实施的另一种方法。当然,许多字段因此可以为空,但您可以将数据完整性卸载到自定义触发器。 CREATE TABLE "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,
    【解决方案6】:

    在极少数情况下单列表是有意义的。我做了一个数据库,其中有效语言代码列表是一个用作外键的单列表。拥有不同的密钥没有意义,因为代码本身就是密钥。并且没有固定的描述,因为在某些上下文中语言代码描述会因语言而异。

    一般来说,如果您需要一个没有任何附加属性的权威值列表,则适合使用单列表。

    【讨论】:

      【解决方案7】:

      我一直使用单列表——当然,这取决于应用程序设计是否已经使用数据库。一旦我忍受了建立数据库连接的设计开销,我就会尽可能将所有可变数据放入表中。

      我能想到单列表OTMH的两种用途:

      1) 数据项存在。常用于下拉列表。也用于简单的合法性测试。

      例如。两个字母的美国州缩写;我们运送到的邮政编码;拼字游戏中合法的单词;等等

      2) 稀疏二元属性,即在大表中,二元属性仅对极少数记录为真。我可能会创建一个单独的表,其中包含属性为 true 的记录的键,而不是添加新的布尔列。

      例如。患有绝症的员工;一年 360 天的银行(大多数使用 365);等等

      -阿尔。

      【讨论】:

        【解决方案8】:

        大多数情况下,我在诸如您描述的状态表之类的查找类型表中看到了这一点。但是,如果您这样做,请务必将列设置为主键以强制唯一性。如果您不能将此值设置为唯一值,则不应使用一列。

        【讨论】:

        • 虽然在这里使用单列可能没问题,但请记住,您也可以在其他列上设置唯一性约束。
        【解决方案9】:

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

        【讨论】:

          【解决方案10】:

          我一般会说,是的。不知道为什么你只需要一列。我已经看到有效使用了一些例外情况。这取决于您要达到的目标。

          当您考虑数据库的架构时,它们并不是很好的设计,但实际上应该只用作实用表。

          我曾经看到numbers tables 过去被有效地使用过。

          【讨论】:

            【解决方案11】:

            数据库的目的是将信息片段相互关联。当没有相关数据时,你怎么能做到这一点?

            也许这是某种编译表(即 FirstName + LastName + Birthdate),但我仍然不确定您为什么要这样做。

            编辑:我可以看到将这种表用于某种简单的列表。这就是你用它的目的吗?

            【讨论】:

            • 不,数据库的主要目的是存储信息。
            • 但是电子表格可以存储信息。如果信息只是一堆不连贯的数字和字母,它们之间没有相关性,那么这些信息有什么用呢?
            • 该信息可能很有用,因为使用数据库的应用程序需要它并且它不是一个固定的集合。也就是说,数据库只是放置信息以供数据库应用程序使用的最方便的地方 - 关系或其他方式。我很确定你会同意我们不是在构建应用程序来证明我们在关系理想方面的纯洁性。相反,我们构建的应用程序是有用的。
            • @Mark - 这就是我所说的简单列表的意思。我猜我没有很好地解释自己。
            • @SR - 不,数据库的主要目的是检索信息。由于感兴趣的行往往依赖于其他数据,我认为 MJ 的原始评论是正确的。
            【解决方案12】:

            是的,只要该字段是您所说的主键。原因是如果您插入重复数据,这些行将是只读的。如果您尝试删除重复的行之一。它不起作用,因为服务器不知道要删除哪一行。

            【讨论】:

            • 这太荒谬了。没有主键或约束的删除操作将删除所有匹配的行,而不是忽略它们。
            • “不工作”的意思可能是“没有按预期工作”,它涵盖了“嘿,我删除了一行,但两者都消失了”的情况。
            • 或者,如果您尝试从“打开表”视图中删除 SSMS 中的记录,它实际上会弹出一个对话框,提示该记录无法唯一标识,然后什么也不做...
            【解决方案13】:

            我能想到的唯一用例是一个单词表,也许是一个文字游戏。您访问该表只是为了验证字符串是否为单词:从 word = ? 的单词中选择单词。但保存单词列表的数据结构比关系数据库要好得多。

            否则,通常将数据库中的数据放在数据库中,以利用数据的各种属性之间的关系。如果您的数据没有超出其价值的属性,这些关系将如何发展?

            因此,虽然不违法,但一般来说,您可能不应该有一个只有一列的表格。

            【讨论】:

            • 与此类似的是可以非常方便地停止循环的数字表。
            【解决方案14】:

            我所有的表都至少有四个技术字段、串行主键、创建和修改时间戳以及软删除布尔值。在任何黑名单中,您还想知道是谁添加了该条目。所以对我来说,答案是否定的,只有一列的表格是没有意义的,除非在制作原型时。

            【讨论】:

            • 听起来您正在将数据表与事务表混为一谈。在我看来,这应该是两个不同的东西。
            【解决方案15】:

            是的,这很好。但是 ID 字段不会伤害它吗?

            【讨论】:

            • 其实可以的。当您有一个明确的有效值列表时,您最不想要的是一个 ID 字段,因为它暗示这些值不是唯一的。如果“LightBlue”是键,那么您不希望有人认为 ID 为 1 的“LightBlue”可能与 ID 为 4 的“LightBlue”不同。
            • 谁说 ID 必须是身份?还是钥匙的一部分?
            • 它可能是一个合成键,原始字段可能有一个唯一的约束。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-09-05
            • 1970-01-01
            • 1970-01-01
            • 2011-04-23
            • 1970-01-01
            • 2017-02-02
            相关资源
            最近更新 更多