使用int连接而不是字符串列更好吗?

时间:2013-11-13 21:40:14

标签: sql database-design database-normalization

假设我有一个具有状态的用户,并且用户的状态可以是“有效”,“暂停”或“无效”。

现在,在创建数据库时,我想知道......如果有一个包含字符串值的列(使用枚举类型或规则)会更好,这样查询和了解当前用户状态会更容易或者加入更好,我应该加入UserStatuses表,其中包含可能的用户状态?

假设,当然,应用程序用户无法创建状态。

修改:一些澄清

  1. NOT 使用字符串连接,它将是UserStatuses PK的int连接
  2. 我主要关心的是表现明智
  3. 可能的状态是静态的从不更改

5 个答案:

答案 0 :(得分:2)

在大多数系统上,它对性能几乎没有影响。就个人而言,为了清晰起见,我会使用一个短字符串,并按照你的建议将其加入到一个包含更多细节的表格中。

create table intLookup
(
pk integer primary key,
value varchar(20) not null
)
insert into intLookup (pk, value) values
(1,'value 1'),
(2,'value 2'),
(3,'value 3'),
(4,'value 4')

create table stringLookup
(
pk varchar(4) primary key,
value varchar(20) not null
)

insert into stringLookup (pk, value) values
(1,'value 1'),
(2,'value 2'),
(3,'value 3'),
(4,'value 4')



create table masterData
(
stuff varchar(50),
fkInt integer references intLookup(pk),
fkString varchar(4)references stringLookup(pk)
)
create index i on masterData(fkInt)
create index s on masterData(fkString)

insert into masterData
(stuff, fkInt, fkString)
select COLUMN_NAME, (ORDINAL_POSITION %4)+1,(ORDINAL_POSITION %4)+1 from INFORMATION_SCHEMA.COLUMNS
go 1000

这导致300K行。

select 
*
from masterData m inner join intLookup i on m.fkInt=i.pk

select 
*
from masterData m inner join stringLookup s on m.fkString=s.pk

在我的系统上(SQL Server) - 查询计划,I / O和CPU是相同的 - 执行时间相同。 - 查询表被读取并处理一次(在任一查询中)

使用int或字符串存在 NO 差异。

答案 1 :(得分:2)

我认为,作为一个整体,每个人都会遇到问题答案的重要组成部分。但是,它们都有好的观点,应该合在一起,而不是分开。

  1. 正如逻辑学家所提到的,通常认为健康量的标准化可以提高性能。但是,与logixologist相比,我认为您的情况是正常化的最佳时机。你的问题似乎是正常化的问题之一。在这种情况下,使用Santhosh建议的数字键然后返回到包含状态的解码的代码表将导致每个记录存储更少的数据。这种差异不会显示在一个小型Access数据库中,但它可能会显示在一个包含数百万条记录的表中,每条记录都有一个状态。

  2. 正如David Aldridge建议的那样,您可能会发现规范化此特定数据点将会带来更受控制的最终用户体验。规范化状态字段还允许您在以后的某个位置编辑状态标志,并使该更改在整个数据库中保持不变。如果你的老板和我的一样,那么你可能不得不将非活动状态更改为已关闭(然后在下周再次返回!),如果状态字段未规范化,这将更有效。通过规范化,实现参照完整性也更容易。如果状态代码表中没有状态键,则无法将其添加到主表中。

  3. 如果您担心将来查询时的性能,那么有一些不同的事情需要考虑。要撤消状态,如果已将其标准化,您将在查询中添加联接。在任何大小的记录集中,这种连接可能不会伤害到你,但我相信它会通过限制必须处理的原始文本量来帮助更大的记录集。如果您在查询数据时主要关注的是性能问题,那么这里有一个关于如何优化查询的优秀资源:http://www.sql-server-performance.com/2007/t-sql-where/我认为您会发现此处讨论的许多规则也适用于您执行的任何包含条件在连接本身。

  4. 希望这有帮助!

    克里斯托弗

答案 2 :(得分:1)

规范化背后的整个想法是防止数据重复(至少有一个概念)。

在这种情况下,一次只有一个用户(我假设)可以有这样的状态,所以他们没有理由把它放在自己的表中。你会简单地复杂化。你有一个单独的表的唯一原因是,如果由于某种原因这些状态不是静态的。意思是下个月你可以添加“活动排序”和“可能不活动”。如果您没有将它们放在自己的表中,这将意味着更改代码以弥补该问题。您可以创建一个维护页面,用户可以在其中添加状态,然后需要您创建一个单独的表。

答案 3 :(得分:1)

需要考虑的一个问题是这些状态值是否具有自己的属性。

例如,您可能希望默认排序顺序与状态文本的字母顺序不同。您可能还希望以特定方式处理两种状态,而不是对待另一种状态,这可能是一个属性。

如果您需要,或怀疑将来需要,请将状态文本移动到另一个表并使用整数键值。

答案 4 :(得分:0)

我建议使用0,1,2等整数值。如果这是固定的。在解释Reports中的结果时,我们可以将这些状态更改回字符串。