在我的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
作为主键,但是它是否有任何缺点,如性能开销?
答案 0 :(得分:2)
关于这个主题有两种思想流派。
有些人强烈认为使用“自然键”作为实体表的主键是可取的,因为它比代理键具有明显的优势。
其他人认为“代理”键可以提供一些“自然”键可能不具备的理想属性。
让我们总结一下主键的一些最重要和最理想的属性:
(还有一些其他属性可以列出,但其中一些属性可以从上面的属性派生(非空,可以索引等)。
我将关于“自然”和“代理”键的两种思想打破为两个阵营中的“最佳”主键:
1)由于先前决定选择自然键作为主键而严重烧的人
2)那些尚未被这个决定焚烧的人。
答案 1 :(得分:0)
当然可以。
create table sometbl(
`name` varchar(250) NOT NULL PRIMARY KEY,
`friendly_name` varchar(400)
);
访问整数或varchar(除非它太长)键的时间没有任何区别。即使它有,它也不会成为你的主要瓶颈。只要将列声明为键,mysql就可以非常快速地访问它。
自动递增整数不能是主键。它只是行的序列号。当你看到真实物体时,你会看到它没有任何序列号。所以主键应该基于那些真实的属性。