AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 1910
Accepted
Jaco Briers
Jaco Briers
Asked: 2011-03-26 04:12:20 +0800 CST2011-03-26 04:12:20 +0800 CST 2011-03-26 04:12:20 +0800 CST

为什么使用 int 作为查找表的主键?

  • 772

我想知道为什么我应该使用一个 int 作为查找表的主键,而不是仅仅使用查找值作为主键(在大多数情况下是一个字符串)。

我知道如果使用 nvarchar(50) 而不是 int 链接到具有许多记录的表,则会使用更多空间。

另一方面,直接使用查找值基本上可以节省我们进行连接的时间。我可以想象如果总是需要加入,这将是一个很大的节省(我们正在开发一个网络应用程序,所以这很重要)。

使用 int 主键(特别是用于查找表)除了它是“标准操作”之外还有什么优势?

sql-server primary-key
  • 5 5 个回答
  • 10565 Views

5 个回答

  • Voted
  1. Best Answer
    Gaius
    2011-03-26T23:06:29+08:002011-03-26T23:06:29+08:00

    您的问题的答案是合乎逻辑的,而不是物理的 - 您查找的值可能会因业务原因而改变。例如,如果您按电子邮件地址索引您的客户,当电子邮件地址更改时会发生什么?显然,这不适用于所有查找表,但在整个应用程序中以相同方式执行此操作的好处是它使您的代码更简单。如果内部一切都是整数→整数关系,那么您就被覆盖了。

    只需阅读您对 Sandy 的评论 - 在这种情况下,您真正​​想要的是Check Constraint,而不是外键/查找表,例如:

    create table icecream (flavour varchar(10))
    go
    alter table icecream add constraint ck_flavour check (flavour in ('Orange', 'Pista', 'Mango'))
    go
    insert into icecream (flavour) values ('Orange')
    go
    insert into icecream (flavour) values ('Vanilla')
    go
    

    运行这个,你会得到:

    (1 row(s) affected)
    Msg 547, Level 16, State 0, Line 1
    The INSERT statement conflicted with the CHECK constraint "ck_flavour". The conflict occurred in database "GAIUSDB", table "dbo.icecream", column 'flavour'.
    The statement has been terminated.
    

    这是一种高效、高性能的方法,但缺点当然是添加新风格意味着代码更改。我建议不要在应用程序中执行此操作 - 因为您需要在连接到此数据库的每个应用程序中执行此操作,这是最简洁的设计,因为只有一个代码路径用于进行验证。

    • 23
  2. CoderHawk
    2011-03-26T04:57:36+08:002011-03-26T04:57:36+08:00

    “直接使用查找值”——这与查找表的实际目的有点矛盾。你为什么要保留这样一张桌子?如果不是查找。
    可能是我误解了你的问题。这是来自msdn的查找表定义

    查找表用于根据另一个表中的外键字段的值显示来自一个表的信息。例如,考虑一个销售数据库中的订单表。Orders 表中的每条记录都包含一个 CustomerID,指示哪个客户下了订单。CustomerID 是指向客户表中客户记录的外键。在显示订单列表(来自订单表)时,您可能希望显示实际的客户名称,而不是 CustomerID。由于客户名称在客户表中,并且您正在呈现来自 Orders 表的数据,因此您需要创建一个查找表,该表采用 Orders 记录中的 CustomerID 值,并使用该值来导航关系并返回更多可读,客户名称。

    您能详细说明查找表的目的吗?它是否用于存储一些静态数据,如下所示,并且这些记录不是其他表记录的输入?

    风味 表

    Orange  
    Pista  
    Mango
    

    如果以上是您的情况,那么我建议不要使用查找表;可能在您的 Web 应用程序中对这些列表值进行硬编码。这样可以避免不必要的数据库查询。

    • 7
  3. dba4life
    2011-03-26T08:25:23+08:002011-03-26T08:25:23+08:00

    由于您使用“专门针对查找表”来限定您的问题,因此答案可能被简化为“节省空间”。

    我认为如果您删除该限定符,您的问题就会变成“为什么使用代理键而不是自然键?” 我写了以下内容来支持代理键:

    “迁移一个整数值而不是一个更宽的复合键有很多好处。它在整个物理模型中提供了很好的一致性,与迁移复合键相比,总的来说节省了更多的空间,并减少了 I/O;尤其是在标准化模型。此外,它们简化了对模型和查询连接的理解。

    这在很大程度上就是为什么它“成为标准的事情”。不幸的副产品是人们抛出代理键并且不认为候选键是什么......但现在我们已经超出了你的问题:)

    • 7
  4. Susan Kennedy
    2012-03-07T17:38:27+08:002012-03-07T17:38:27+08:00

    我经常使用的原因之一是,如果有人在查找表中拼错了一个值,比如说 Oraneg 而不是 Orange,那么更改查找表中的值非常容易。

    具有数字主键的查找表只需要更改查找表中的值。

    使用这些值作为主键的查找表需要在查找表中以及在使用它的主表中的每条记录中进行更改。

    • 3
  5. Vojta Rylko
    2011-12-19T13:01:38+08:002011-12-19T13:01:38+08:00

    当您定义 ID 时,您也可以保证唯一性。但是,当您将例如电子邮件作为唯一标识符时,您会将唯一性责任转移到不受信任的第三方。

    • 2

相关问题

  • 字符与整数主键

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve