MySQL的主键命名策略相关

 更新时间:2021年01月28日 12:01:49   作者:jeanron100  
这篇文章主要介绍了MySQL的主键命名策略的的相关资料,帮助大家更好的理解和使用MySQL数据库,感兴趣的朋友可以了解下

最近在梳理数据生命周期管理的细节时,发现了一个小问题,那就是MySQL的主键命名策略,似乎会忽略任何形式的自定义命名。

也就意味着你给主键命名为idx_pk_id这种形式,在MySQL里面会统一按照PRIMARY来处理。

当然我们可以在这个基础之上做一些拓展和补充。

首先来复现下问题,我们连接到数据库test,然后创建表test_data2.

mysql> use test

mysql> create table test_data2 (id int ,name varchar(30));

Query OK, 0 rows affected (0.05 sec)

接着创建一个主键,命名为idx_pk_id,从执行情况来看,MySQL是正常处理了。

mysql> alter table test_data2 add primary key idx_pk_id(id);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0

为了进一步对比,我们添加一个唯一性索引(辅助索引),来看看它们的差异。

mysql> alter table test_data2 add unique key idx_uniq_name(name);
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0

查看主键命名方法1:使用show indexes命令

要查看MySQL索引的信息,使用show indexes from test_data2就可以。

mysql> show indexes from test_data2\G
*************************** 1. row ***************************
    Table: test_data2
  Non_unique: 0
   Key_name: PRIMARY
 Seq_in_index: 1
 Column_name: id
  Collation: A
 Cardinality: 0
   Sub_part: NULL
    Packed: NULL
     Null: 
  Index_type: BTREE
   Comment: 
Index_comment: 
*************************** 2. row ***************************
    Table: test_data2
  Non_unique: 0
   Key_name: idx_uniq_name
 Seq_in_index: 1
 Column_name: name
  Collation: A
 Cardinality: 0
   Sub_part: NULL
    Packed: NULL
     Null: YES
  Index_type: BTREE
   Comment: 
Index_comment: 
2 rows in set (0.00 sec)

查看主键命名方法2:使用数据字典information_schema.statistics

使用命令的方式不够通用,我们可以使用数据字典information_schema.statistics来进行数据提取。

mysql> select *from information_schema.statistics where table_schema='test' and table_name='test_data2' limit 20 \G        
*************************** 1. row ***************************
TABLE_CATALOG: def
 TABLE_SCHEMA: test
  TABLE_NAME: test_data2
  NON_UNIQUE: 0
 INDEX_SCHEMA: test
  INDEX_NAME: PRIMARY
 SEQ_IN_INDEX: 1
 COLUMN_NAME: id
  COLLATION: A
 CARDINALITY: 0
   SUB_PART: NULL
    PACKED: NULL
   NULLABLE: 
  INDEX_TYPE: BTREE
   COMMENT: 
INDEX_COMMENT: 
*************************** 2. row ***************************
TABLE_CATALOG: def
 TABLE_SCHEMA: test
  TABLE_NAME: test_data2
  NON_UNIQUE: 0
 INDEX_SCHEMA: test
  INDEX_NAME: idx_uniq_name
 SEQ_IN_INDEX: 1
 COLUMN_NAME: name
  COLLATION: A
 CARDINALITY: 0
   SUB_PART: NULL
    PACKED: NULL
   NULLABLE: YES
  INDEX_TYPE: BTREE
   COMMENT: 
INDEX_COMMENT: 
2 rows in set (0.00 sec)

查看主键命名方法3:使用show create table 命令

如果查看建表语句,会发现主键名已经被过滤掉了。

mysql> show create table test_data2\G
*************************** 1. row ***************************
    Table: test_data2
Create Table: CREATE TABLE `test_data2` (
 `id` int(11) NOT NULL,
 `name` varchar(30) DEFAULT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `idx_uniq_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
有的同学可能想,是不是分别执行了create,alter语句导致处理方式有差异,我们可以一步到位,在create语句里面声明主键名。
CREATE TABLE `test_data3` (
 `id` int(11) NOT NULL,
 `name` varchar(30) DEFAULT NULL,
 PRIMARY KEY idx_pk_id(`id`),
 UNIQUE KEY `idx_uniq_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

这个时候查看建表语句,会发现结果和上面一样,主键名都是PRIMARY.

mysql> show create table test_data3\G    
*************************** 1. row ***************************
    Table: test_data3
Create Table: CREATE TABLE `test_data3` (
 `id` int(11) NOT NULL,
 `name` varchar(30) DEFAULT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `idx_uniq_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

查看主键命名方法4:查看约束命名

当然还有多种验证方式,比如我们使用约束的方式来命名,得到的主键名都是PRIMARY.

CREATE TABLE IF NOT EXISTS `default_test` (
 `default_test`.`id` SMALLINT NOT NULL AUTO_INCREMENT,
 `default_test`.`name` LONGTEXT NOT NULL,
CONSTRAINT `pk_id` PRIMARY KEY (`id`)
);

查看主键命名方法5:使用DML报错信息

当然还有其他多种形式可以验证,比如我们使用DML语句。

mysql> insert into test_data2 values(1,'aa');
Query OK, 1 row affected (0.02 sec)
mysql> insert into test_data2 values(1,'aa');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

以上的方法都可以让我们对这个细节有更深入的理解,当然我们可以再深入一些。

查看主键命名方法6:官方文档

官方文档里面其实包含了这个信息,但是不是很明显。

关于主键的描述,大体内容如下,有一条是专门做了声明,主键名为PRIMARY.

  • 一个表只能有一个PRIMARY KEY。
  • PRIMARY KEY的名称始终为PRIMARY,因此不能用作任何其他类型的索引的名称。
  • 如果您没有PRIMARY KEY,而应用程序要求您在表中提供PRIMARY KEY,则MySQL将返回没有NULL列的第一个UNIQUE索引作为PRIMARY KEY。
  • 在InnoDB表中,将PRIMARY KEY保持较短,以最小化辅助索引的存储开销。每个辅助索引条目都包含对应行的主键列的副本。
  • 在创建的表中,首先放置一个PRIMARY KEY,然后放置所有UNIQUE索引,然后放置非唯一索引,这有助于MySQL优化器确定使用哪个索引的优先级,还可以更快地检测重复的UNIQUE键。

查看主键命名方法7:源代码

在sql_table.cc 里面对主键名称做了定义声明。

const char *primary_key_name="PRIMARY";

顺着这条路,可以看到在不同层的实现中的一些逻辑情况。

小结:

通过这样的一些方式,我们对主键的命名情况有了一个整体的认识,为什么会采用PRIMARY这样一个命名呢,我总结了几点:

1)统一命名可以理解是一种规范

2)和唯一性索引能够区别开来,比如一个唯一性索引非空,从属性上来看很相似的,通过主键命名就可以区分出来,在一些特性和索引使用场景中也容易区分。

3)主键是一个表索引的第一个位置,统一命名可以在逻辑判断中更加清晰,包括字段升级为主键的场景等等。

4)在优化器处理中也会更加方便,提高MySQL优化器确定使用哪个索引的优先级。

以上就是MySQL的主键命名策略相关的详细内容,更多关于MySQL 主键命名策略的资料请关注脚本之家其它相关文章!

相关文章

  • MySQL不适合创建索引的11种情况示例分析

    MySQL不适合创建索引的11种情况示例分析

    这篇文章介绍了在MySQL中不适合创建索引的11种情况,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2025-02-02
  • 详解MySQL中InnoDB的存储文件

    详解MySQL中InnoDB的存储文件

    本篇是一篇关于MySQL专题知识点的内容,详细讲述了InnoDB的存储文件的相关内容,感兴趣的朋友学习下。
    2018-02-02
  • MySql获取当前时间并转换成字符串的实现

    MySql获取当前时间并转换成字符串的实现

    本文主要介绍了MySql获取当前时间并转换成字符串的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • mysql数据库在表中添加数据三种操作方式

    mysql数据库在表中添加数据三种操作方式

    这篇文章主要介绍了mysql数据库在表中添加数据三种方式,首先创建数据库和表,创建完成后就可以进行添加数据的操作了,本文结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-08-08
  • MySQL 升级方法指南大全

    MySQL 升级方法指南大全

    通常,从一个发布版本升级到另一个版本时,我们建议按照顺序来升级版本。例如,想要升级 MySQL 3.23 时,先升级到 MySQL 4.0,而不是直接升级到 MySQL 4.1 或 MySQL 5.0。
    2008-01-01
  • mysql日常锁表之flush_tables详解

    mysql日常锁表之flush_tables详解

    Flushtables和Flushtableswithreadlock是MySQL中的两个命令,用于关闭表对象和清空查询缓存,它们会等待所有正在运行的SQL请求执行结束,如果请求操作的表集合为{tables},则会阻塞其他会话对{tables}表上的所有操作,包括查询和写操作
    2024-11-11
  • MySQL 中的权限管理及验证流程

    MySQL 中的权限管理及验证流程

    这篇文章主要介绍了MySQL 中的权限管理及验证流程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 深入JDBC sqlserver连接写法的详解

    深入JDBC sqlserver连接写法的详解

    本篇文章是对JDBC sqlserver的连接写法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • mysql DISTINCT选取多个字段,获取distinct后的行信息方式

    mysql DISTINCT选取多个字段,获取distinct后的行信息方式

    这篇文章主要介绍了mysql DISTINCT选取多个字段,获取distinct后的行信息方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • MySQL curdate()函数的实例详解

    MySQL curdate()函数的实例详解

    这篇文章主要介绍了MySQL curdate()函数的实例详解的相关资料,希望通过本文能帮助到大家理解应用MysqL curdate()的使用方法,需要的朋友可以参考下
    2017-09-09

最新评论