我可以在MySQL表中使用非数字主键吗?

时间:2014-09-28 19:23:46

标签: mysql sql natural-key

在我的Web应用程序中,用户可以定义文档并为其指定唯一名称,以标识该文档以及人类用于引用文档的友好名称。以下表模式为例:

|   id   |    name        |   friendly_name   |
-----------------------------------------------
|    2   |    invoice-2   |   Invoice 2       |

在此示例中,我使用id列作为主键,这是一个自动递增的数字。由于文档(name)已有自然ID,我也可以这样做:

|    name        |   friendly_name   |
--------------------------------------
|    invoice-2   |   Invoice 2       |

在此示例中,name是文档的主键。我们删除了id字段,因为它基本上只是name的副本,因为表格中的每个文档都必须具有唯一的name

这也意味着当我从外键关系中引用文档时,我必须将其称为document_name而不是document_id

关于此的最佳做法是什么?从理论上讲,我完全有可能使用VARCHAR作为主键,但是它是否有任何缺点,如性能开销?

2 个答案:

答案 0 :(得分:2)

关于这个主题有两种思想流派。

有些人强烈认为使用“自然键”作为实体表的主键是可取的,因为它比代理键具有明显的优势。

其他人认为“代理”键可以提供一些“自然”键可能不具备的理想属性。

让我们总结一下主键的一些最重要和最理想的属性:

  • minimal - 尽可能少的属性
  • simple - 本机数据类型,理想情况下是单列
  • available - 创建实体时,该值始终可用
  • 唯一 - 绝对没有重复,没有两行会有相同的价值
  • 匿名 - 携带隐藏的“有意义”信息
  • 不可变 - 一旦分配,永远不会被修改

(还有一些其他属性可以列出,但其中一些属性可以从上面的属性派生(非空,可以索引等)。


我将关于“自然”和“代理”键的两种思想打破为两个阵营中的“最佳”主键:

1)由于先前决定选择自然键作为主键而严重的人

2)那些尚未被这个决定焚烧的人。

答案 1 :(得分:0)

当然可以。

create table sometbl(
`name` varchar(250) NOT NULL PRIMARY KEY,
`friendly_name` varchar(400)
);

访问整数或varchar(除非它太长)键的时间没有任何区别。即使它有,它也不会成为你的主要瓶颈。只要将列声明为键,mysql就可以非常快速地访问它。

自动递增整数不能是主键。它只是行的序列号。当你看到真实物体时,你会看到它没有任何序列号。所以主键应该基于那些真实的属性。