MySQL中列属性(主键、唯一键和自增等)使用实践

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS Agent(兼容OpenClaw),2核4GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
简介: MySQL中列属性(主键、唯一键和自增等)使用实践

数据表中,真正约束字段的是数据类型。但是数据类型的约束很单一,需要有一些额外的约束,来更加保证数据的合法性。如主键、唯一、自增等。

查看表数据结构

  • 红色表示数据类型;
  • 蓝色表示列属性;


列属性(其实也是约束)有很多,大致如下:

NOT NULL/NULL,

DEFAULT,

PRIMARY KEY,

UNIKUE KEY,

AUTO_INCREMENT,

COMMENT


【1】空属性

其有两个值:null(默认值) 和 not null (不为空) 。虽然默认的数据库基本字段为空,但是生产环境中尽可能保证字段都不为空。空数据没有意义,且无法参加运算。

select 1+'hello',null,1+null;




【2】列描述

comment:描述,没有实际含义,为列增加文字说明,会随着表创建一起储存起来。

创建表的时候设置描述

CREATE TABLE `tb_sys_user` (
  `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '编号',
  `name` varchar(32) DEFAULT NULL COMMENT '名字',
  `mobile` varchar(12) DEFAULT NULL COMMENT '手机号',
  `user_code` varchar(32) DEFAULT NULL COMMENT '用户编码',
  `password` varchar(100) DEFAULT NULL COMMENT '密码',
  `sex` varchar(5) DEFAULT NULL COMMENT '性别',
  `age` int(5) DEFAULT NULL COMMENT '年龄',
  `address` varchar(50) DEFAULT NULL COMMENT '地址',
  `field1` varchar(255) DEFAULT NULL COMMENT '保存用户头像-saveName',
  `field2` varchar(255) DEFAULT NULL COMMENT '冗余字段2',
  `field3` varchar(255) DEFAULT NULL COMMENT '冗余字段3',
  `field4` varchar(255) DEFAULT NULL COMMENT '冗余字段4',
  `field5` varchar(255) DEFAULT NULL COMMENT '冗余字段5',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_mobile` (`mobile`) USING BTREE,
  UNIQUE KEY `unique_code` (`user_code`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COMMENT='用户表'

修改列的时候添加描述

alter table equipment.tb_sys_user modify column  
name varchar(32) DEFAULT NULL comment '名字'

【3】默认值

① default

某一种数据会经常性的出现某个具体的值,可以在一开始指定好,用户可以在使用的时候选择性的使用默认值或插入新数据。

create table my_default(
name VARCHAR(20) not null unique key ,
gender varchar(4) DEFAULT '男'
)charset utf8;
desc my_default;
# gender为null
insert into my_default values('tom',null);
# default,gender取默认值
insert into my_default values('lily',DEFAULT);
select * from my_default;

当不对gender列进行插入的时候,gender将会使用默认值

# 指定列,gender取默认值
insert into my_default (name) VALUE ('lir');
select * from my_default;

可见,指定列 与 values使用default 两种方式都可以使具有默认值的列,在插入数据的时候使用默认值。

【4】主键primary key

一张表只能有一个字段可以使用对应的键,用来唯一的约束该字段里面的数据,不能重复。主键本身一定不为空,且不允许重复。

① 列后面

create table my_default(
id int PRIMARY KEY,--使用关键字
name VARCHAR(20) not null unique key ,
gender varchar(4) DEFAULT '男'
)charset utf8;

② 表字段后面

在创建表的时候,在所有的字段之后使用 primary key(主键的字段 列表)来创建主键(如果有多个字段作为主键,称之为复合主键)

create table my_pri(
number char(10),
course char(10),
score TINYINT,
PRIMARY KEY(number,course)--复合主键
)charset utf8;
desc my_pri;

测试如下:

insert into my_pri VALUES('001','IT','10');--插入成功
insert into my_pri VALUES('001','IT','10');--插入失败
insert into my_pri VALUES('001','IT2','10');--插入成功

③ 创建表之后,为表追加主键

有两种方式:第一位修改表字段属性,第二直接追加。

第一种方式示例如下:

alter TABLE my_pri MODIFY number char(11) PRIMARY KEY

第二种方式示例如下:

alter table table_name add primary key(column) ;
## 增加复合主键
alter TABLE my_pri add PRIMARY KEY(number,course);
#使用关键字CONSTRAINT 且指定主键名字pk_score 
alter table my_pri add CONSTRAINT pk_score PRIMARY KEY(score)
#使用关键字CONSTRAINT 且使用默认名字 
alter table my_pri add CONSTRAINT  PRIMARY KEY(score)

drop删除主键:

#不能根据主键名字删除,因为只有一个主键
alter table my_pri drop PRIMARY KEY;

主键分类

在实际创建表的过程中,很少使用真实的业务 数据作为主键字段(业务主键,如课程号,学号。大部分时候是使用逻辑性字段(字段没有什么业务含义,值是什么都没有关系),将这种字段主键称之为逻辑主键。


【5】自动增长

① 自增长定义

auto_increment:当对应的字段,不给值、给默认值 、给null 值,会自动的被系统触发。


系统会从当前字段中已有的最大值进行+1操作,得到一个新的不同的字段,作为下一次插入数据是自增长字段的值。


若手动修改了auto_increment,且为向上修改,那么下一次值为auto_increment。自增长通常跟主键搭配。

自增长特征

① 任何一个字段要做自增长前提必须是一个索引;

② 自增长字段必须是整型数字;

③ 一个表至多有一个标识列

④ 标识列可以通过 SET auto_increment_increment=3;设置步长。

② 设置自增长属性

测试如下(创建失败),自增长字段必须是key(索引)

create table my_auto(
id int auto_increment ,
name varchar(20)
)charset utf8;

19cb750cd67c656fbb4e0a9b2219c83b.png

正确实例

create table my_auto(
id int primary key auto_increment ,
name varchar(20)
)charset utf8;

1fe61ea369174e128ceab689c0ec2f2c.png

③ 插入数据

insert into my_auto  values(null,'tom');
insert into my_auto  values('','tom2');--插入失败
insert into my_auto  values('null','tom3');--插入失败
insert into my_auto  values(DEFAULT,'tom4');

其中,第二、三将会插入失败–主键不能为空:


第一、四插入null 或者默认值,将会自动增长并插入:

如果自增长对应的字段输入了值,那么自增长失效。下一次插入数据,会获取最大值+1:

#指定id 为5
insert into my_auto  values(5,'tom5');
# tom6对应id应该为6
insert into my_auto  values(default,'tom6');
select * from my_auto;

a06f85df6d692452c5ceeed3c333c0c6.png

④ 修改自增长

自增长如果是设计到字段改变,必须先删除自增长,后增加(一张表只能有一个自增长)。修改当前自增长已存在的值,修改只能比最大值大,不能小(小不生效)。

语法如下:

alter table table_name auto_increment = 值 ;

测试向下修改:

#现在数据表已存在最大值7
alter table my_auto auto_increment=3;
show create table my_auto;
CREATE TABLE `my_auto` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8
--此时AUTO_INCREMENT=8 ,故向下修改无效

测试 向上修改:

#可以向上修改
alter table my_auto auto_increment=10;
show create table my_auto;
CREATE TABLE `my_auto` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8

插入数据测试,此时最新数据id为10:

insert into my_auto VALUES(null,'Lucy');
select * from my_auto ;


c9cade8ce59acb10aabc0a84305342ae.png

演示到这里,有没有一个疑问:为什么自增长是从1开始?

我们知道,所有系统的表现(如字符集,校对集)都是由系统内部的变量进行控制的。

查看自增长对应的变量:show VARIABLES LIKE '%auto_increment%'

auto_increment_increment 1 --步长值
auto_increment_offset    1 --起始值

f343a43dd191f21dd1cbd7959a31ab11.png

可以修改变量实现不同的效果。但是修改是对整个数据库进行修改而不是单张表,且修改是会话级别,关闭并重新打开链接,变量恢复默认值

set auto_increment_increment = 2;
show VARIABLES LIKE '%auto_increment%';

1d861c133fc611fb25fb95cc32af9c83.png

变量修改后,在第二次插入数据时候生效

因为修改变量并不会立即更新表选项的auto_increment,当再插入数据后,会更新auto_increment ,此时检测到步长已经改变,故之后插入数据会使用新的步长值。

insert into my_auto values(null,'Lucy12');
insert into my_auto values(null,'Lucy12');
select * from my_auto;

80b5fe69451633ab0abf2978b048d679.png

⑤ 删除自增长

自增长不能通过drop消除,只能通过modify column。需要注意的是,如果自增长对应的字段为主键,那么修改 列属性的时候,不要再加primary key ; 会被系统认为又定义一个主键,将会提示"Multiple primary key defined"

--错误,会被认为又定义一个主键;
alter table my_auto modify id int primary key;
--正确,且不会丢失掉 id 的主键
alter table my_auto modify id int ;

⑥ 标识列

又称为自增长列,含义:可以不用手动的插入值,系统提供默认的序列值。

可以通过 手动插入值,设置起始值

# 设置普通字段NAME自增
CREATE TABLE tab_identity(
  id INT  ,
  NAME FLOAT UNIQUE AUTO_INCREMENT,
  seat INT 
);

【6】唯一键

一张表往往有很多字段需要唯一性,数据不能重复;但是一张表只能有一个字段为主键,那么唯一键(unique key),就可以解决表中有多个字段需要唯一性约束的问题。

唯一键默认值允许自动为空,而且可以多个不同字段为空—空字段不参与唯一性比较。

① 增加唯一键

分为创建表和创建后两种方式:

① 创建表时(又分两种):

--第一种,字段增加
create table my_unique(
name varchar(4) unique key,
number varchar(20) unique key
)charset utf8;
--第二种,字段末尾增加
create table my_unique(
name varchar(4) ,
number varchar(20) ,
unique key name(name),--指定唯一约束名字
unique key(number)--使用默认名字
)charset utf8;

a4ac2de03817ddc74f5406e341cd92d7.jpg

② 创建表后(又分两种):

#创建表,不带唯一约束
create table my_unique(
name varchar(4) ,
number varchar(20) 
)charset utf8;
#第一种,modify column
alter table my_unique modify column name varchar(5) UNIQUE KEY;
#第二种 add constraint unique key,指定唯一约束名字为num_uk
alter TABLE my_unique add CONSTRAINT num_uk UNIQUE KEY(number);

② drop删除唯一约束

#根据指定约束名字删除,若创建的时候未指定名字,默认使用列名作为唯一约束名字。
alter table my_unique drop index num_uk;


CREATE TABLE `my_unique` (
  `name` varchar(5) DEFAULT NULL,
  `number` varchar(20) DEFAULT NULL,
  UNIQUE KEY `num_uk` (`number`),--唯一约束名字为num_uk
  UNIQUE KEY `name` (`name`)--唯一约束名字默认为列名
) ENGINE=InnoDB DEFAULT CHARSET=utf8

下面演示一个有趣的现象:

--创建表
create table my_unique(
name varchar(4) not null,--注意这里 not null
number varchar(20) 
)charset utf8;
--增加唯一约束
alter table my_unique modify column name  varchar(5) not NULL UNIQUE KEY;
--查看表结构
desc my_unique;

注意key那一列,显示 PRI 不是UNI!解释如下:该表没有主键;刚好是一个不为空的唯一键,性质和主键一样。故MySQL无法判断,显示了PRI。当表中已经存在主键,则会正常显示为UNI


③ 复合唯一约束

##第一种创建方式
create table my_unique(
name varchar(4) not null,
number varchar(20) ,
unique KEY na_um_un(name,number)--字段末尾创建,使用指定名
)charset utf8;
desc my_unique;

插入数据

insert into my_unique values('tom','1001');
insert into my_unique values('tom','1001');
  • 提示数据重复–约束名字为 na_um_un(创建时候指定的名字)

--第二种创建方式
--创建空表,不带约束
create table my_unique(
name varchar(4) not null,
number varchar(20) 
)charset utf8;
--增加复合约束
alter TABLE my_unique add CONSTRAINT num_na_uk UNIQUE KEY(number,name);
--查看表结构
desc my_unique;

  • 删除指定名字复合约束
alter table my_unique drop index num_na_uk;
  • 删除默认名字复合约束
  • 若不指定名字,那么复合约束名字为第一个字段名字
alter TABLE my_unique add CONSTRAINT UNIQUE KEY(number,name);
--查看表创建语句
show create TABLE my_unique;
CREATE TABLE `my_unique` (
  `name` varchar(4) NOT NULL,
  `number` varchar(20) DEFAULT NULL,
  UNIQUE KEY `number` (`number`,`name`)--这里,名字为number
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--删除复合约束
alter table my_unique drop index number;

另外,唯一键同样是索引的类型,故唯一键的添加删除可以如下:

ALTER TABLE `weight_num_curr_detail`
DROP INDEX `unque_store_brand` ;
ADD UNIQUE INDEX `unque_store_brand` (`store_code`, `brand_code`, `year_num`) USING BTREE ;


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
Ubuntu 关系型数据库 MySQL
容器技术实践:在Ubuntu上使用Docker安装MySQL的步骤。
通过以上的操作,你已经步入了Docker和MySQL的世界,享受了容器技术给你带来的便利。这个旅程中你可能会遇到各种挑战,但是只要你沿着我们划定的路线行进,你就一定可以达到目的地。这就是Ubuntu、Docker和MySQL的灵魂所在,它们为你开辟了一条通往新探索的道路,带你亲身感受到了技术的力量。欢迎在Ubuntu的广阔大海中探索,用Docker技术引领你的航行,随时准备感受新技术带来的震撼和乐趣。
552 16
|
存储 缓存 关系型数据库
MySQL为什么需要主键
本文介绍了MySQL中主键的重要性及最佳实践。主键用于唯一标识表中的每一行,其值必须唯一且不允许为空。主键有助于简化更新和删除操作,避免影响无关行。推荐使用与业务无关的自增ID作为Innodb表的主键,以优化存储结构、减少碎片并提高性能。此外,文章还提到不更新、不重用主键值以及避免使用可能变更的字段(如邮箱)作为主键的良好习惯。最后强调了紧凑索引结构对查询效率的关键作用。
408 0
MySQL为什么需要主键
|
人工智能 关系型数据库 MySQL
解决MySQL自增id用尽的问题
本文介绍了解决文章点击记录表(`article_click_record`)数据量激增问题的方案。由于用户量大,每天新增约400万条记录,导致表id接近溢出(2,100,000,000),且占用空间超320G。解决方案包括:1) 新建`article_click_record_new`表,将id类型改为BIGINT以避免溢出;2) 过渡阶段同时写入新旧表,待旧表id溢出后切换至新表;3) 定时清理过期数据或转移旧表内容。实现方式涉及修改相关接口和服务逻辑,确保业务平稳过渡。
325 5
|
SQL 关系型数据库 MySQL
PHP与MySQL的高效交互:从基础到实践####
本文深入探讨了PHP与MySQL数据库之间的高效交互技术,涵盖了从基础连接到高级查询优化的全过程。不同于传统的摘要概述,这里我们直接以一段精简代码示例作为引子,展示如何在PHP中实现与MySQL的快速连接与简单查询,随后文章将围绕这一核心,逐步展开详细讲解,旨在为读者提供一个从入门到精通的实战指南。 ```php <?php // 数据库配置信息 $servername = "localhost"; $username = "root"; $password = "password"; $dbname = "test_db"; // 创建连接 $conn = new mysqli($se
466 31
|
存储 关系型数据库 MySQL
MySQL主键谁与争锋:MySQL为何钟爱自增主键ID+UUID?
本文深入探讨了在MySQL中使用自增类型主键的优势与局限性。自增主键通过保证数据的有序性和减少索引维护成本,提升了查询和插入性能,简化了数据库管理和维护,并提高了数据一致性。然而,在某些业务场景下,如跨表唯一性需求或分布式系统中,自增主键可能无法满足要求,且存在主键值易预测的安全风险。因此,选择主键类型时需综合考虑业务需求和应用场景。
593 2
|
缓存 关系型数据库 MySQL
MySQL 索引优化与慢查询优化:原理与实践
通过本文的介绍,希望您能够深入理解MySQL索引优化与慢查询优化的原理和实践方法,并在实际项目中灵活运用这些技术,提升数据库的整体性能。
870 5
|
存储 关系型数据库 MySQL
PHP与MySQL动态网站开发:从基础到实践####
本文将深入探讨PHP与MySQL的结合使用,展示如何构建一个动态网站。通过一系列实例和代码片段,我们将逐步了解数据库连接、数据操作、用户输入处理及安全防护等关键技术点。无论您是初学者还是有经验的开发者,都能从中获益匪浅。 ####
|
关系型数据库 MySQL Java
MySQL索引优化与Java应用实践
【11月更文挑战第25天】在大数据量和高并发的业务场景下,MySQL数据库的索引优化是提升查询性能的关键。本文将深入探讨MySQL索引的多种类型、优化策略及其在Java应用中的实践,通过历史背景、业务场景、底层原理的介绍,并结合Java示例代码,帮助Java架构师更好地理解并应用这些技术。
502 2
|
监控 关系型数据库 MySQL
MySQL自增ID耗尽应对策略:技术解决方案全解析
在数据库管理中,MySQL的自增ID(AUTO_INCREMENT)属性为表中的每一行提供了一个唯一的标识符。然而,当自增ID达到其最大值时,如何处理这一情况成为了数据库管理员和开发者必须面对的问题。本文将探讨MySQL自增ID耗尽的原因、影响以及有效的应对策略。
791 3
|
存储 关系型数据库 MySQL
MySQL 8.0特性-自增变量的持久化
【11月更文挑战第8天】在 MySQL 8.0 之前,自增变量(`AUTO_INCREMENT`)的行为在服务器重启后可能会发生变化,导致意外结果。MySQL 8.0 引入了自增变量的持久化特性,将其信息存储在数据字典中,确保重启后的一致性。这提高了开发和管理的稳定性,减少了主键冲突和数据不一致的风险。默认情况下,MySQL 8.0 启用了这一特性,但在升级时需注意行为变化。
367 1

推荐镜像

更多