按位列与单独表

时间:2016-03-31 22:18:56

标签: sql relational-database

我想获得一些关于在表中存储按位枚举的优缺点的输入,而不是创建一个单独的表。

详细说明,假设我存储了有关各种应用程序的信息,并且每个应用程序都可以使用各种编程语言。

方法1.通常,我会创建三个表:

**APP**
APP_ID
APP_NAME

**LANGUAGE**
LANGUAGE_ID
LANGUAGE_NAME

**APP_LANGUAGE**
APP_ID
LANGUAGE_ID

方法2.我能想到的另一种方法是将语言分配给按位枚举并在APP表中存储单个整数:

**APP**
APP_ID
APP_NAME
LANGUAGES

**LANGUAGE**
LANGUAGE_ID | LANGUAGE_NAME | LANGUAGE_VALUE
------------+---------------+---------------
1           |  Java         |      1
2           |  Python       |      2
3           |  Ruby         |      4
4           |  C#           |      8
etc.

显然,在这种情况下,APP表不会被外键绑定到LANGUAGE。

这两种方法之间的根本区别是什么?我假设第一种方法需要在数据库端进行更多处理,特别是如果可以在应用程序中添加或删除语言,而第二种方法可能需要在代码中进行更多处理。那么用户可以通过一种或多种语言过滤结果的性能,索引,运行报告等等呢?

据我所知,如果我必须为每个应用程序/语言对存储其他属性(例如应用程序中每种语言的%组合),那么第一种方法就不用了,所以这个问题不适用于那种情况。

1 个答案:

答案 0 :(得分:2)

您的第一种方法是将此信息存储在关系数据库中的“正确”方法。 “正确”方法有几个优点。我可以很容易地想到以下几点:

  • 对语言的查询可以使用索引。
  • 添加新语言很简单。
  • 为应用程序分配一种新语言很简单:只需插入一个新行而不是一堆小小的东西。
  • 您可以跟踪分配新语言的时间(通过CreatedAt列)。
  • 当您需要支持超过8/32/64或任何位/语言时,您不必考虑该怎么做。

基本上,位摆弄对关系数据库没有帮助(大多数情况下)。 SQL引擎通常不能为位提供非常好的操作。而且,更新/插入的费用通常是日志记录和I / O,而不是位的设置。

SQL中的底层数据结构以数据页为中心,而不是单个寄存器/本地缓存。关于在C / C ++等语言中运行良好的直觉可能无助于以大(或至少大)数据和并行处理为中心的环境。 SQL中的关键性能目标通常是减少磁盘读取次数,而不是本地内存的超级优化。