对于引用表,我应该使用ID还是文本字段


With a reference table, should I use the ID or the text field?

我有一个包含字段id和字段name的引用表item_type。在我的应用程序中,项目应根据其item_type进行不同的处理。

在我的应用程序代码中,我的条件逻辑应该检查id还是name?或者有其他最佳实践吗?

编辑:id将是主键,但name仍然是唯一的;这些将是下拉列表中的选项,并将确定用户要添加的项目类型。稍后,这些将决定如何处理项目。

这可能是一个棘手的情况。

  1. 假设您有这个问题,则表明您的设计没有指定您为这个特定表拥有哪些键。我认为这是一个不完整的设计,请重新访问此部分,并明确指定所有关系的所有密钥
  2. 如果您同时具有idname(好吧,name在我们传递时不是一个很好的列名称,因为它是一个保留字),我假设id是人为添加的,即此列不必用于描述您的数据。这就是所谓的代理密钥。你应该小心那些——它们不会让你免于重复!想象一个案例,你会有:

     id |   name
    ----+--------
      1 | type_a
      2 | type_b
      3 | type_a
    

    尽管您的id是这里的主键并且所有的值都是唯一的,但您仍然存在数据重复;

  3. 因此,必须在此处创建两个键:id列上的Primary和name列上的Unique。现在,这本身并不是一个糟糕的情况,但请确保您拥有两个

就我个人而言,我使用以下规则:

  1. 如果表是一个包含少量(最多10个)值的字典,我使用:

    • 该表中只有1列,使其成为varchar(或者更确切地说是text
    • 将该列与表中的名称相等
    • 将此列设为主键

    这样可以保持桌子的整洁和小巧。与ENUM相比,我更喜欢使用专用表格。

  2. 如果我知道的话,条目的数量会增长我需要添加更多的列,我会:

    • 创建一个专用的数字列,将其命名为<table_name>_id(例如customer_id),并使其成为主键
    • 在数据模型的其他地方使用此PK
    • 对实际数据创建唯一约束以避免数据重复(这是强制性的)

编辑:对于这么小的东西,我认为根本没有必要使用id作为代理密钥。我怀疑这个表中的值是否会经常更改,如果它们真的会更改的话。引入人工键的成本——为了检查特定类型的条目,必须才能联接到此表。而自然的text密钥将允许您避免这种情况,并使用以下查询:

SELECT * FROM item WHERE item_type='type_a';

我建议看看这个问题:INT和VARCHAR主键之间是否存在真正的性能差异?

最后,你应该了解你的设计,并对其进行性能测试。这将让你真正了解什么最适合你。

如何设计表有两种不同的方法:

  1. 使用自然键,如员工号码、国家代码等
创建表country(代码char(2),名称varchar(100),…);创建表employee(empno number(5),name varchar(100),…);创建表顺序(orderno number(5),country_code char(2),…);
  1. 使用技术ID:
创建表country(id number(9),code char(2),name varchar(100),…);创建表employee(id number(9),empno number(5),name varchar(100),…);创建表格顺序(id编号(9)、orderno编号(5)、id_country编号(9…);

在任何情况下,您都不会在程序中使用该名称。这只是您向用户显示的数据。你不能用它来访问记录。

至于技术ID:这些仅用于数据库内部的参考。只有当你所做的是关于联接时,你才会在你的程序中使用它们。例如:让用户从列表中选择一个国家,然后使用其ID访问在该国家下的订单。

当涉及到让你的程序知道代码时,你不应该使用任何一个。例如,当你想把英国区别于其他国家时,因为它是你的祖国,那么就使用它的代码"GB"。当然,你可以让你的程序选择国家/地区"GB"的ID,并将你的订单与该ID进行比较。只有在你的应用程序中永远不要有select ... from orders where id_country = 187这样的东西。

关于你的表格:在我的例子中,国家已经有了一个代码;你可以使用ISO代码。你的物品类型可能没有。所以你发明了一个代码。这可能是一个你甚至可以向用户展示的代码,所以他们可能会在一段时间后习惯它们,并开始谈论RC,而不是像以前那样谈论赛车。或者你对用户保留代码,只在程序中使用它们,所以他们永远看不到代码"RC",但对于所有程序来说,赛车都是RC。

所以你要么有

create table item_type (code char(2), name varchar(100), ...);

create table item_type (id number(9), code char(2), name varchar(100), ...);

并使用应用程序中的代码字段。

还有一句话:当使用自然键并让用户使用时,通常会使用短代码作为"RC",因为这些代码用于引用(外键),也很容易键入。当使用ID并仅在内部使用代码时,为了程序的可读性,您也可以使用长代码,如"RACING_CARS"。

如果您有这样的代码:

TABLE ITEMS:
id
type_id
name
etc_etc
ITEM_TYPES
id
name

按id执行。除非你有充分的理由,否则总是使用int列,优选的索引列(比如你的主自动递增id列)。这是一台电脑,电脑做数字,而不是文字:)

如果这还不够(应该):
假设您将类型添加为字符串而不是ID。您知道(有些忘记了)有几个地方引用了"青色"项目。一年后,你认为"Teal"会更好,所以你更新了表格。现在,您必须查看所有代码才能将所有"青色"更改为"青色"。在大环境下,这将失败
身份证更改的可能性要小得多。