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

我有一个表来存储优惠券/折扣,我想使用coupon_code列作为主键,这是一个VARCHAR

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

我不会做任何连接或索引,而且我也没有看到这个表中有超过几百个条目。

在我看来,这将是好的,但我不知道是否有什么我失踪/没有考虑。

当然,你可以,在你的RDBMS将允许你这样做。 然而,对于是否应该这样做的问题的答案是不同的:在大多数情况下,不应将数据库系统之外具有含义的值作为主键。

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

这样做的基本原理很简单:数据input错误和对不可更改事物的偶发更改确实发生。 他们变得更难以解决作为主键使用的值。

一个毯子“不,你不应该”是可怕的build议。 在许多情况下,这是完全合理的,取决于你的用例,工作量,数据熵,硬件等等。你不应该做的是做出假设。

应该注意的是,你可以指定一个前缀,这将限制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

这取决于具体的用例。

如果你的表是静态的,并且只有一个简短的值列表(并且在DB的生命周期中这个数字会变化的可能性很小),我会推荐这样的结构:

 CREATE TABLE Foo ( FooCode VARCHAR(16), -- short code or shortcut, but with some meaning. Name NVARCHAR(128), -- full name of entity, can be used as fallback in case when your localization for some language doesn't exist LocalizationCode AS ('Foo.' + FooCode) -- This could be a code for your localization table...  ) 

当然,当你的表格不是静态的,使用INT作为主键是最好的解决scheme。

当然可以。 只有几百个参赛作品,速度会很快。

你可以添加一个唯一的ID作为主键(int autoincrement)和你的coupon_code设置为唯一。 所以如果你需要在其他表中做请求,最好使用int而不是varchar