我有一个用于存储优惠券/折扣的表,我想使用 coupon_code 列作为主键,即VARCHAR
.
我的理由是,每张优惠券都有一个唯一的代码,我将运行的唯一命令是SELECT ... FROM ... WHERE coupon_code='..'
我不会做任何连接或索引,而且我看不到这个表中有超过几百个条目。
在我看来,这会没问题,但我不知道是否有什么我遗漏/没有考虑的事情。
我有一个用于存储优惠券/折扣的表,我想使用 coupon_code 列作为主键,即VARCHAR
.
我的理由是,每张优惠券都有一个唯一的代码,我将运行的唯一命令是SELECT ... FROM ... WHERE coupon_code='..'
我不会做任何连接或索引,而且我看不到这个表中有超过几百个条目。
在我看来,这会没问题,但我不知道是否有什么我遗漏/没有考虑的事情。
当然可以,因为您的 RDBMS 会让您这样做。但是,您是否应该这样做的问题的答案是不同的:在大多数情况下,不应选择在数据库系统之外具有意义的值作为主键。
如果您知道该值在您正在建模的系统中是唯一的,那么向您的表添加唯一索引或唯一约束是合适的。但是,您的主键通常应该是一些“无意义”的值,例如自动递增的数字或 GUID。
这样做的理由很简单:数据输入错误和对看似不可更改的事物的不频繁更改确实会发生。它们变得更难修复用作主键的值。
毯子“不,你不应该”是可怕的建议。这在许多情况下是完全合理的,具体取决于您的用例、工作负载、数据熵、硬件等。您不应该做的是做出假设。
应该注意的是,您可以指定一个前缀来限制 MySQL 的索引,从而在扫描其余部分之前帮助您缩小结果范围。但是,随着您的前缀“填满”并变得不那么独特,这可能会随着时间的推移变得不那么有用。
这很简单,例如:
CREATE TABLE IF NOT EXISTS `foo` (
`id` varchar(128),
PRIMARY KEY (`id`(4))
)
另请注意,前缀(4)
出现在列引号之后。这4
意味着它应该使用可以作为id
.
最后,您应该在使用它们之前阅读索引前缀的工作原理及其限制:https ://dev.mysql.com/doc/refman/8.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作为主键是最好的解决方案。
肯定没问题。只有几百个条目,它会很快。
您可以添加一个唯一 id 作为主键(int autoincrement),并将您的 coupon_code 设置为唯一。因此,如果您需要在其他表中进行请求,最好使用 int 而不是 varchar