Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用int连接而不是字符串列更好吗?_Sql_Database Design_Database Normalization - Fatal编程技术网

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

Sql 使用int连接而不是字符串列更好吗?,sql,database-design,database-normalization,Sql,Database Design,Database Normalization,假设我有一个状态为的用户,该用户的状态可以是“活动”、“暂停”或“不活动” 现在,在创建数据库时,我想知道。。。是否最好使用字符串值的列(应用枚举类型或规则),以便更容易查询和了解当前用户状态,或者是更好的联接,我应该联接到包含可能的用户状态的UserStatuses表中 当然,假设应用程序用户不能创建状态 编辑:一些澄清 我将不使用字符串连接,它将是对UserStatuses PK的int连接 我最关心的是性能 可能的状态是静态的,不会改变 在大多数系统上,它对性能几乎没有影响。就我个人而言,

假设我有一个状态为的用户,该用户的状态可以是“活动”、“暂停”或“不活动”

现在,在创建数据库时,我想知道。。。是否最好使用字符串值的列(应用枚举类型或规则),以便更容易查询和了解当前用户状态,或者是更好的联接,我应该联接到包含可能的用户状态的UserStatuses表中

当然,假设应用程序用户不能创建状态

编辑:一些澄清

  • 我将使用字符串连接,它将是对UserStatuses PK的int连接
  • 我最关心的是性能
  • 可能的状态是静态的,不会改变

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

    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或string是没有区别的。

    标准化背后的整个思想是防止数据重复(至少有一个概念)


    在这种情况下,一个用户一次(我假设)只能有一个状态,因此他们没有理由将其放在自己的表中。你只会把事情复杂化。如果出于某种原因,这些状态不是静态的,那么您将拥有一个单独的表的唯一原因是。也就是说,下个月你可以加上“有点活跃”和“可能不活跃”。这意味着,如果您没有将它们放在自己的表中,则需要更改代码以弥补这一点。您可以创建一个maintenace页面,用户可以在其中添加状态,然后需要您创建一个单独的表

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

    < P>一个要考虑的问题是这些状态值是否具有它们自己的属性。 例如,您可能希望使用与状态文本的字母顺序不同的默认排序顺序。您可能还希望以一种特定的方式处理其中两种状态,而不处理另一种状态,这可能是一个属性


    如果您有此需求,或者怀疑将来会有此需求,请将状态文本移动到另一个表中,并为它们使用整键值。

    我认为,总体而言,每个人都找到了您问题答案的重要组成部分。然而,它们都有优点,应该放在一起考虑,而不是分开考虑

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

  • 正如David Aldridge所建议的,您可能会发现规范化这个特定的数据点将带来更可控的最终用户体验。规范化状态字段还将允许您稍后在一个位置编辑状态标志,并使该更改在整个数据库中永久化。如果你的老板和我一样,那么你可能必须将非活动状态更改为关闭状态(然后在下周再次更改!),如果状态字段没有正常化,这将是更多的工作。通过规范化,也更容易强制引用完整性。如果状态键不在状态代码表中,则无法将其添加到主表中

  • 如果你在未来的查询中关注性能,那么有一些不同的事情要考虑。要收回状态,如果它是规范化的,您将向查询中添加一个联接。这种连接可能不会在任何大小的记录集中伤害到您,但我相信它会通过限制必须处理的原始文本量在更大的记录集中有所帮助。如果您主要关心的是查询数据时的性能,那么这里有一个关于如何优化查询的很好的资源:我想您会发现这里讨论的许多规则也适用于您在联接本身中强制执行的任何包含条件

    希望这有帮助


    Christopher

    对于具有数百万条记录、频繁查询和严格响应时间要求的表来说是不正确的。想想eBay或Amazon用户。@PM77-1您有什么建议?@svallory-我认为,是否规范数据库以及是否规范数据库的形式的决定只对相当大的数据集很重要,应该根据操作环境的要求做出。如果您需要对大量并发请求的分秒响应时间,您将使用较低的形式,或者根本不进行规范化。这将使维护变得有些复杂,并需要更多的存储空间,但在这种环境中,您可以做您必须做的事情。如果它是一个与有限数量的用户交互工作的普通业务应用程序,请选择第二或第三个表单。测量它并查看。我怀疑这会对实际的、真实的示例产生很大的影响,因为通常值是缓存的,并且您只对给定的查询使用子集。我默认从第三范式开始。非常感谢!这正是我想要的答案。顺便说一句,我没有任何额外的信息,只有一个字符串值,所以我甚至不需要连接到“stringLookup”表