我可以使用VARCHAR作为PRIMARY KEY吗?

时间:2013-10-10 15:21:58

标签: mysql sql primary-key unique varchar

我有一张存储优惠券/折扣的表格,我想使用coupon_code列作为主键,VARCHAR

我的理由是,每个优惠券都有一个唯一的代码,我将运行的唯一命令是SELECT ... FROM ... WHERE coupon_code='..'

我不会进行任何连接或索引,并且我没有看到此表中有超过几百个条目。

在我看来,这样可以,但我不知道是否有任何我缺少/没有想过的东西。

4 个答案:

答案 0 :(得分:96)

当然,就你的RDBMS会让你这样做,你可以。但是,是否应该这样做的问题的答案是不同的:在大多数情况下,在数据库系统之外具有意义的值应该被选择为是一把钥匙。

如果您知道在建模的系统中该值是唯一的,则为表添加唯一索引或唯一约束是合适的。但是,您的主键通常应该是一些“无意义”的值,例如自动递增的数字或GUID。

这个的基本原理很简单:数据输入错误和看似不可更改的事情不经常发生变化。它们变得更难以修复用作主键的值。

答案 1 :(得分:18)

毯子“不,你不应该”是可怕的建议。这在很多情况下是完全合理的,具体取决于您的使用案例,工作负载,数据熵,硬件等。您不应该做的是做出假设。

应该注意的是,您可以指定一个限制MySQL索引的前缀,从而在扫描其余部分之前为您提供一些缩小结果的帮助。然而,随着时间的推移,这可能会变得不那么有用,因为你的前缀“填满”并变得不那么独特。

这很简单,例如:

CREATE TABLE IF NOT EXISTS `foo` (
  `id` varchar(128),
  PRIMARY KEY (`id`(4)),
)

另请注意,在列引号后,前缀(4)会出现

最后,您应该在使用之前阅读索引前缀的工作原理及其局限性:

http://dev.mysql.com/doc/refman/5.0/en/create-index.html

答案 2 :(得分:2)

这取决于具体的用例。

如果您的表是静态的并且只有一个简短的值列表(并且在DB的生命周期中这种情况发生变化的可能性很小),我建议使用这种结构:

jQuery('.cd-popup-trigger').click(function(){
     jQuery('.cd-popup-trigger').removeClass('active');
     jQuery(this).addClass('active');

});

当然,当您的表根本不是静态时,使用 INT 作为主键是最佳解决方案。

答案 3 :(得分:-1)

可以肯定。只需几百个条目,就会很快。

您可以添加唯一ID作为主键(int autoincrement)并将您的coupon_code设置为唯一。因此,如果您需要在其他表中执行请求,最好使用int而不是varchar