【问题标题】:With a reference table, should I use the ID or the text field?对于参考表,我应该使用 ID 还是文本字段?
【发布时间】:2014-10-27 19:34:32
【问题描述】:

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

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

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

【问题讨论】:

  • 如果 id 和 name 都是唯一的,您可以使用其中任何一个,但通常最好使用主键中的任何一个。但是,这取决于您的需要。您可以发布您的表格和遇到问题的查询吗?你可能会得到更好的答案。

标签: php mysql database-design logic


【解决方案1】:

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

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

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

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

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

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

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

    • 此表中只有 1 列,使其成为 varchar(或 text 而不是);
    • 将此列命名为与表相同;
    • 将此列设为主键。

    这样可以保持桌子干净且小巧。而且我更喜欢使用专用表而不是ENUMs。

  2. 如果我知道,条目的数量将会增加我需要在此过程中添加更多列,我会:

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

编辑: 对于这么小的事情,我认为根本不需要使用id 作为代理键。我怀疑这个表中的值会经常变化,如果他们会这样做的话。引入人工密钥的成本 - 必须加入此表以检查特定类型的条目。而自然的text 键将允许您避免这种情况并使用如下查询:

SELECT * FROM item WHERE item_type='type_a';

我建议看看这个问题:Is there a REAL performance difference between INT and VARCHAR primary keys?

最后,您应该了解自己的设计并对其进行性能测试。这会给你真正的知识,告诉你什么是最适合你的。

【讨论】:

    【解决方案2】:

    有两种不同的方式来设计表格:

    1. 使用自然键,即员工编号、国家代码等。
    创建表国家(代码 char(2),名称 varchar(100),...); 创建表员工(empno number(5), name varchar(100), ...); 创建表顺序 (orderno number(5), country_code char(2), ...);
    1. 使用技术 ID:
    创建表国家(id 号(9),代码 char(2),名称 varchar(100),...); 创建表员工(id 号(9),empno 号(5),名称 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”以提高程序的可读性。

    【讨论】:

    • 所以我可能有:id = 1, code = '月刊', description = '月刊'; id = 2、code = 'month-to-date'、description = 'Month-to-Date' 等,并检查 code 属性?
    • 是的。代码是您在程序中使用的一个简短常量。描述可以随时更改(也许有一天您甚至会切换到多种语言)。该 ID 在其他表中用作参考。
    【解决方案3】:

    如果你有这样的代码:

    TABLE ITEMS:
    id
    type_id
    name
    etc_etc
    
    ITEM_TYPES
    id
    name
    

    按 id 去。除非您有充分的理由,否则始终使用 int 列,最好使用索引列(例如您的主要 auto_incrementing ID 列)。这是一台计算机,计算机做的是数字,而不是文字:)

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

    【讨论】:

      猜你喜欢
      • 2011-04-15
      • 2021-04-27
      • 2014-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-18
      • 1970-01-01
      相关资源
      最近更新 更多