数据库设计:在数据库中保留分隔字符串是不好的

时间:2009-11-06 20:02:39

标签: database-design

之前我曾在项目上工作过将字段存储在以逗号分隔或以管道分隔的字符串中作为字段,这可能代表选项或类似的东西。我想知道这样做是否被认为是错误的数据库设计,应该总是使用关系表,或者有时以这种方式存储数据是否可以接受?

14 个答案:

答案 0 :(得分:10)

通常,这是一个坏主意

然而,正常化与表现之间存在平衡。

如果列表没有被解析并且只是按原样显示,那么最好存储以逗号分隔的列表,但是如果为单个元素解析列表,则应该坚持使用{{3} }。

答案 1 :(得分:7)

这取决于你。数据库字段应该包含原子数据,也就是说,整个值是有意义的,但值的一部分不是。例如,我可能决定将一个人的姓名存储在名为fullname的字段中,因此值为John Smith和Mary Jane等。

这是正确的,如果我将永远将这些值视为一个整体,并且永远不需要仅选择名字或姓氏,或按姓氏排序等。

如果姓氏或名字对我有意义,也许我必须在查询中按姓氏排序,那么我将创建两个字段firstname和lastName。

在您的情况下,如果分隔的项目在数据库级别不感兴趣,那么可以将它们保存在单个字段中。但是,如果您需要通过分隔项进行查询,则将它们拆分为各自的字段。

答案 2 :(得分:1)

就个人而言,我会以两种方式接近:

  • 如果可行,我只需将该逗号/管道分隔列表转换为外键实现,并将该数据存储在另一个表中。如果您处理大量数据,这可能会有缺点,但在大多数情况下它可以工作,如果您打算按这些字段进行查询,您通常希望采用这种方式。

  • 另一种方法是简单地将数据存储为数据库中的序列化对象,而不是分隔列表。例如,在Python中,您可以使用pickle模块来序列化标准对象,您可以将其存储在数据库中,而无需担心代码执行和可能发生的其他讨厌的黑客攻击。

答案 3 :(得分:1)

如果您发现越来越需要使用字符串中存储的值在其他表中进行搜索,那么您应该考虑根据其他人的建议对数据库进行规范化。 Drupal,Wordpress等将基本信息存储在字符串中,并且可以正常工作。

答案 4 :(得分:0)

这取决于 - 如果数据库不需要对分隔字符串中的数据进行任何类型的过滤或排序,并且数据最初是以分隔格式发送到数据库的,为什么不呢?如果数据库永远不会使用它,为什么要解析并将其拆分为单独的字段呢?

答案 5 :(得分:0)

它通常被认为是不好的,因为它违背了拥有数据库(及其强大的索引和搜索数据的方法)的目的。但是,可以根据具体情况进行证明。如果已经为分隔的字符串进行了处理,并且你永远不想对结构做任何事情而不是检索它...谁会阻止你?

答案 6 :(得分:0)

我会避免在数据库字段中放置分隔字符串。字段应始终只包含一个值。这样可以提供更大的灵活性,并允许您使用数据库的内置功能来实现大量聚合和其他功能:

例如,假设您有一个书籍和作者数据库(通常用于数据库书籍)

  1. 获取每位作者的书籍数
  2. 从作者添加或删除单本书
  3. 获取所有作者的书籍总数
  4. 可能性(几乎)无穷无尽。但是如果一个字段通过使用分隔符持有多个值,则每次需要对这些基本函数的答案时,都需要解析该字段。

答案 7 :(得分:0)

这不是关系。

例如,如果你有这个:

abc | 123,456,789
def | 123
ghi | 123

将其标准化为以下内容:

1 | abc | 123
2 | abc | 456
3 | def | 123
4 | ghi | 123
5 | abc | 789

答案 8 :(得分:0)

像所有好的设计问题一样,答案应该是“它取决于”。关系数据库中的列旨在提供可用于表征数据的一个离散逻辑信息单元。我会说,如果根据列的内容永远没有任何理由来表征两个不同的数据 - 也就是说,你根本不想根据列的内容找到一些数据而不是其他数据 - 这没关系。

例如,如果您将文件权限数据存储在列中,并且只保留数据以存储文件的权限以便以后可以读取,那么就可以了。如果您想查询那些具有u + x权限的文件(该列是该列中数据的一个组件),则应将数据分隔到不同的列。

答案 9 :(得分:0)

这可能是一件好事。我使用过几个使用数据库表来记录SOAP请求和响应的系统。尝试规范化所有数据将是非常难看的。逗号分隔列表可能存在类似情况。

答案 10 :(得分:0)

重要的是要记住,数据库是为了满足应用程序的需求,而不是 。如果您的应用需要存储管道分隔数据列表,那就这样吧。

这方面的一个很好的例子是我建立的管理工具。我需要大量关系数据的版本控制功能。我已经有了将所述数据序列化到JSON和来自JSON的例程,所以我创建了一个新的“版本”表,其中包含每个版本的一些头信息和一个存储JSON版本的文本字段。编辑器还包括一个“激活”按钮,用于反序列化和规范化数据,并将其放在单独的表中,以便主应用程序可以访问它的内容。请注意,主应用程序永远不会修改此数据。

虽然我可以在此架构中的每个表中添加“version_id”字段,并为我的所有存储过程添加了相应的参数,但它本来就没有充分的理由创建工作。

请不要过分使用这种方法。从技术上讲,将整个数据库存储在一个字段中是可能的,但这几乎不可取或不高效。

答案 11 :(得分:0)

正如其他人所说,通常最好将数据标准化,以便可以轻松访问和更新,但可能会有例外情况,这样做没有任何优势。

我要注意的是“过早优化”的思维模式,设计者假定将数据保存在规范化的表中会对性能造成不利影响,而无论如何都不能证明这一点。我经常使用数据库,其中一些信息(例如,用户拥有的角色列表)已连接成一个字符串。我几乎总是发现,出于好奇,我构建数据的规范化版本并对其进行基准测试时,它至少执行 以及“针对性能的非规范化”版本。

答案 12 :(得分:0)

如果您要存储项目的快照并希望返回并查看当时选择了哪些选项,我可以看到将这样的值存储到一个字段中。我曾经在一个单独的字段存储一个大型XML文件的位置工作,该文件重新处理了作为历史文档引用的发票。

使用这种类型的方法虽然用于日常使用,但从许多其他答案中可以说明并不简单或有用。

答案 13 :(得分:0)

虽然这个问题很老,但我必须说我现在有一个非常艰难的经历,因为我必须在后端使用分隔字符串。我同意这个问题上的大多数帖子,因为它确实取决于应用程序的需求,但是还必须考虑后端的需求,这意味着那些可能实际上必须在以后使用这些数据的人。正如文森特所说,如果您计划进行报告,或以某种方式使用您以后出于某种目的存储的数据,那么通常您需要确保避免让自己更难或者使用数据的人更难。如果你担心的只是存储它,那就做任何让你开心的事。