主键应该始终是无符号的?

由于主键(标识符)不会低于0,我想它应该始终是无符号的?

MySQL支持可选的SERIAL数据types(大概是为了与PostgreSQL兼容,因为SERIAL不是标准的ANSI SQL)。 这种数据types只是简写,会创build一个BIGINT UNSIGNED

继续尝试:

 CREATE TABLE test.foo (foo_id SERIAL PRIMARY KEY); SHOW CREATE TABLE test.foo; CREATE TABLE `test`.`foo` ( `foo_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`foo_id`), UNIQUE KEY `foo_id` (`foo_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 

无论您是否声明有符号整数或无符号整数,都会得到相同数量的不同值: INT为2 32BIGINT为2 64 。 如果这个数字是无符号的,你会得到从0到最大值减1的值。 如果该号码已被签名,则可以从-max/2max/2-1获取值。 无论哪种方式,你都可以得到绝对数量不同的值。

但是由于AUTO_INCREMENT在默认情况下从零开始,并且在正方向上递增,所以利用正值比利用负值更方便。

但是,获得2倍的正面价值并不重要。 任何超过最大有符号整数值2 31 -1的表都有可能继续增长,所以你应该只为这些表使用BIGINT

即使删除了所有的行并每天重新加载它们, 实际上也不太可能分配超过2 63-1个主键值。

为什么你假设一个主键不会低于0? 这不是一个给定的。 我认为你是在混淆身份专栏。

在任何情况下,它都不应该有任何明显的差别,不pipe它是否是主键,都将数据types映射到列中所期望的数据types。

NO – 主键不会总是无符号的,例如:

  create table user_status ( status_id tinyint not null primary key, name varchar(64) not null, msg varchar(255) default null )engine=innodb; insert into user_status values (-99,'banned', 'Account banned'), (-2,'closed', 'Account closed'), (-1,'unverified', 'Account not verified'), (0,'suspended','Account suspended'), (1,'active', null); 

如果这是一个订单表,但是我会使用order_id int unsigned

因为主键(标识符)不会低于0

我从这个陈述中假设你的主键也是自动递增的。

如果是这样,那么确保列是无符号的是非常明智的,因为MySQL手册中描述的原因:

AUTO_INCREMENT列只有在只包含正值的情况下才能正常工作。 插入一个负数被认为是插入一个非常大的正数。 这样做是为了避免在数字从正面转换到负面时出现精度问题,并确保您不会意外地获得包含0的AUTO_INCREMENT列。

如果您将负数插入自动递增列,那么您可能是以错误的方式解决问题。