使用参考表,我应该使用ID还是文本字段?

时间:2014-10-27 19:34:33

标签: php mysql database-design logic

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

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

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

3 个答案:

答案 0 :(得分:1)

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

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

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

    尽管您的id是主键,但它的所有值都是唯一的,但您仍然有数据重复;

  3. 因此,您必须在此处创建2个密钥:id列上的主要内容和name列上的唯一身份。 现在,这本身并不是一个糟糕的情况,但要确保你有两个键。
  4. 就个人而言,我使用以下规则:

    1. 如果table是一个小(最多10)个值的字典,我使用:

      • 此表中只有1列,使其成为varchar(或text而非);
      • 将此列同等地命名为表格;
      • 将此列设为主键。

      这使桌子保持干净小巧。我更喜欢在ENUM s上使用专用表格。

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

      • 创建一个专用数字列,将其命名为<table_name>_id(例如customer_id),并将其设为主键;
      • 在数据模型的其他地方使用此PK;
      • 在实际数据上创建唯一约束以避免数据重复(这是必需的)。
    3. 修改 我认为没有必要使用id作为代理键来完成这么小的事情。我怀疑这个表中的值会经常变化,如果他们会这样做的话。引入人工密钥的成本 - 加入此表是必须以检查某种类型的条目。而自然text键将允许您避免这种情况,并使用如下查询:

      SELECT * FROM item WHERE item_type='type_a';
      

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

      最后 - 你应该知道你的设计,你应该对它进行性能测试。这将为您提供最适合您的真实知识。

答案 1 :(得分:0)

如果你有这样的代码:

TABLE ITEMS:
id
type_id
name
etc_etc

ITEM_TYPES
id
name

转到id。除非你有充分的理由,否则总是使用int列,最好的索引列(列在你的主要auto_incrementing ID列)。它是一台计算机,计算机做数字,而不是单词:)

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

答案 2 :(得分:0)

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

  1. 使用自然键,即员工编号,国家/地区代码等
  2.    create table country (code char(2), name varchar(100), ...);
       create table employee (empno number(5), name varchar(100), ...);
       create table order (orderno number(5), country_code char(2), ...);
    
    1. 使用技术ID:
    2.    create table country (id number(9), code char(2), name varchar(100), ...);
         create table employee (id number(9), empno number(5), name varchar(100), ...);
         create table order (id number(9), orderno number(5), id_country number(9), ...);
      

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

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

      当您的程序知道代码时,您也不应该使用它们。例如,当你想对待与其他国家不同的英国时,因为它是你的祖国,那么使用它的代码&#39; GB&#39;。当然,您可以让您的计划选择国家/地区的ID&#39; GB&#39;并将您的订单与该ID进行比较。只在您的应用中永远不会有select ... from orders where id_country = 187这样的内容。

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

      所以你要么

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

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

      并使用您应用中的代码字段。

      还有一个注意事项:当使用自然键并让用户使用它们时,通常会使用短代码作为&#39; RC&#39;因为它们用于引用(外键)并且也很容易输入。当使用ID并且仅在内部使用代码时,您也可以使用长代码,例如&#39; RACING_CARS&#39;为了您的程序可读性。