Database 在一个表中维护3个小列还是1个大列更好?

Database 在一个表中维护3个小列还是1个大列更好?,database,oracle,Database,Oracle,三个小数字列[Number1]>> OptionA | 0/1 OptionB | 0/1 OptionC | 0/1 或一个更大的字符串列[Varchar229]>> Options | OptionA=0/1|OptionB=0/1|OptionC=0/1 我不确定数据库处理表的方式,但我认为将三列保持为Number1比将一列保持为Varchar229要好 -编辑- 让我再解释一下情况: 我正在一个通用框架上工作,在这个框架中,所有传入/传出的请求/响应都会被跟踪,这些交互可以被引导到一

三个小数字列[Number1]>>

OptionA | 0/1
OptionB | 0/1
OptionC | 0/1
或一个更大的字符串列[Varchar229]>>

Options | OptionA=0/1|OptionB=0/1|OptionC=0/1
我不确定数据库处理表的方式,但我认为将三列保持为Number1比将一列保持为Varchar229要好

-编辑-

让我再解释一下情况:

我正在一个通用框架上工作,在这个框架中,所有传入/传出的请求/响应都会被跟踪,这些交互可以被引导到一个DB/File/JMS;现在,所有配置都是从一个表中加载的,该表有一个对应于输出类型的列,目前我使用DB=1 | FILE=1 | JMS=0作为该列的值,这样以后如果有人想为他们的模块添加该列,他们就可以很容易地理解发生了什么,在我的代码中,我编写了一个简单的逻辑,它将字符串按|拆分,然后使用异或运算符使用开关大小写在选项之间切换

所有的事情都已经完成了,但是我不喜欢一个大的列比三个小的好的想法,它会删除我正在做的拆分字符串

-编辑-


我终于弄清楚了,可能有一种情况,我们必须增加更多的选择;在这种情况下,如果按列添加数据,将导致修改表+更改实体+添加更多if's n all;另一方面,我最终用一个简单的位逻辑从中生成一个枚举,以在选项之间切换;这样,我需要修改枚举并为新选项添加一个新的处理程序,然后我们就可以开始了。

首先,如果我没有看错您的问题,您希望每个选项都有两个可能值中的一个,对吗

如果是这样,您可以:

每个选项都有一个单独的整数或布尔列 有一个选项列,它是一个由1和0组成的字符串,每个选项一个数字,例如001 使用整数“选项”列,并为每个选项使用位值,例如optionA==options&1、optionB==options&2等。 有些数据库有位向量数据类型,您可以使用它。对于mysql,有位数据类型,它可以存储长达64位的位字符串。
对于每一个,在代码复杂性和效率之间都会有一个折衷。问问自己,使用这些选项可以节省多少机器时间或存储空间?那么您可以节省多少时间?

首先,如果我没有看错您的问题,您希望每个选项都有两个可能值中的一个,对吗

如果是这样,您可以:

每个选项都有一个单独的整数或布尔列 有一个选项列,它是一个由1和0组成的字符串,每个选项一个数字,例如001 使用整数“选项”列,并为每个选项使用位值,例如optionA==options&1、optionB==options&2等。 有些数据库有位向量数据类型,您可以使用它。对于mysql,有位数据类型,它可以存储长达64位的位字符串。
对于每一个,在代码复杂性和效率之间都会有一个折衷。问问自己,使用这些选项可以节省多少机器时间或存储空间?在这种情况下,我建议使用3列方法,这不仅可以简化数据提取,而且如果您希望可以针对所有3列设置值,而不是仅限于一个VarChar2字段,则可以使用3列方法。如果选择单列VarChar2,那么使用substr命令或其他变体提取所需信息就相当简单了,尽管这对于Oracle db来说并不繁重,实际上,这会给服务器带来不必要的额外工作。

在这种情况下,我建议使用3列方法,这不仅可以简化数据提取,而且如果您希望可以针对所有3列设置值,而不是仅限于一个VarChar2字段。如果选择单列VarChar2,那么使用substr命令或其他变体提取所需信息就相当简单了,尽管这对于Oracle db来说并不繁重,实际上,这会给服务器带来不必要的额外工作。

在数据库中,使用一列存储多条数据可能是最糟糕的做法

违反第一范式至少有以下缺点:

更难查询。OptionA=1,OptionB=1,OptionC=0与子句9,1='1'和子句19,1='1'和子句19,1='0'。 不太灵活。当您需要添加另一个选项时会发生什么情况?添加新列很容易。添加新格式可能会打乱旧的查询。例如,如果有人试图阅读带有副词-1,1的OptionC。尽管这是使用第三个选项的一个很好的理由-一个单独的表。 无类型 安全这可能是一个非常微妙和棘手的问题。假设你写的是substroption,9,1=1,而不是substroption,9,1='1'。如果有人把格式弄错了,一个值可能会毁掉很多查询。更糟糕的是,由于访问路径不断变化,它只会间歇性地使少量查询崩溃。尽管您可以通过检查约束来防止这种情况。 较慢的查询。通常,在表达式或条件中完成的工作量对于查询来说并不是很大的成本。但是添加大量不必要的字符串操作可能会有所不同。 较少优化。Oracle只有能够理解您的数据,才能构建高效的查询计划。例如,假设OptionA的时间占0.99.9%。当筛选OptionA=0时,Oracle可以使用直方图对返回的行数进行非常准确的预测。但是对于substroption,9,1='1',你只能得到一个粗略的猜测。如果您有使用此列的复杂查询,您可能会花费大量时间尝试修复基数估计。尽管表达式统计数据可能对此有所帮助? 有时,反规范化是一个好主意。例如,如果您有TB的数据,并压缩表,则单个列可能占用更少的空间。但是如果你想节省空间,为什么不使用像000这样的格式呢


如果真的有很好的理由,那么肯定需要记录下来。可能在列上添加注释。

在数据库中,使用单个列存储多个数据段可能是最糟糕的做法

违反第一范式至少有以下缺点:

更难查询。OptionA=1,OptionB=1,OptionC=0与子句9,1='1'和子句19,1='1'和子句19,1='0'。 不太灵活。当您需要添加另一个选项时会发生什么情况?添加新列很容易。添加新格式可能会打乱旧的查询。例如,如果有人试图阅读带有副词-1,1的OptionC。尽管这是使用第三个选项的一个很好的理由-一个单独的表。 没有类型安全。这可能是一个非常微妙和棘手的问题。假设你写的是substroption,9,1=1,而不是substroption,9,1='1'。如果有人把格式弄错了,一个值可能会毁掉很多查询。更糟糕的是,由于访问路径不断变化,它只会间歇性地使少量查询崩溃。尽管您可以通过检查约束来防止这种情况。 较慢的查询。通常,在表达式或条件中完成的工作量对于查询来说并不是很大的成本。但是添加大量不必要的字符串操作可能会有所不同。 较少优化。Oracle只有能够理解您的数据,才能构建高效的查询计划。例如,假设OptionA的时间占0.99.9%。当筛选OptionA=0时,Oracle可以使用直方图对返回的行数进行非常准确的预测。但是对于substroption,9,1='1',你只能得到一个粗略的猜测。如果您有使用此列的复杂查询,您可能会花费大量时间尝试修复基数估计。尽管表达式统计数据可能对此有所帮助? 有时,反规范化是一个好主意。例如,如果您有TB的数据,并压缩表,则单个列可能占用更少的空间。但是如果你想节省空间,为什么不使用像000这样的格式呢


如果真的有很好的理由,那么肯定需要记录下来。也许可以在该列上添加注释。

不幸的是,Oracle不支持布尔值,我想用0/1表示3列,但我的上级说如果我使用1列会更好。。如果我这样做了,我不仅要保持一种向其他队友解释的格式,而且还需要一些编码来提取相关的值。但话说回来,我对数据库一无所知,所以我想要一些关于情况的详细解释。谢谢你的回复。问问你的前辈这个表可能有多少行。如果他说的值低于100万,那么优化可能不值得。该表有8列,包括1个大列。不幸的是,Oracle不支持布尔值,我想用0/1表示3列,但我的上级说如果我使用1列会更好。。如果我这样做了,我不仅要保持一种向其他队友解释的格式,而且还需要一些编码来提取相关的值。但话说回来,我对数据库一无所知,所以我想要一些关于情况的详细解释。谢谢你的回复。问问你的前辈这个表可能有多少行。如果他说的少于100万,那么优化可能不值得。该表有8列,包括1个大列。感谢解释,我编辑并添加了更多有关情况的信息:感谢解释,我编辑并添加了
有关情况的更多信息:这正是我的观点,但我如何让组织意识到这一点@DD_uu你能强调一下组织为什么要采用单列方法吗?他们的原因是什么,然后我们可以同意或解释为什么不同意?@DD_uu啊,我明白了,在这种情况下,单列方法将更容易集成更多的项目,但我会重新考虑如何存储它们,我建议不要使用A列etc,而是使用一个唯一的代码来标识每个列,然后可能在它们之间使用delimter,以便在需要查看当前内容时可以拆分它们;DB、文件、JMS等在我的枚举中的位置。这正是我的观点,但我如何让组织意识到这一点@DD_uu你能强调一下组织为什么要采用单列方法吗?他们的原因是什么,然后我们可以同意或解释为什么不同意?@DD_uu啊,我明白了,在这种情况下,单列方法将更容易集成更多的项目,但我会重新考虑如何存储它们,我建议不要使用A列etc,而是使用一个唯一的代码来标识每个列,然后可能在它们之间使用delimter,以便在需要查看当前内容时可以拆分它们;数据库、文件、JMS等在我的枚举中的位置。