主键 订阅
主关键字(primary key)是表中的一个或多个字段,它的值用于唯一的标识表中的某一条记录。在两个表的关系中,主关键字用来在一个表中引用来自于另一个表中的特定记录。主关键字是一种唯一关键字,表定义的一部分。一个表的主键可以由多个关键字共同组成,并且主关键字的列不能包含空值。主关键字是可选的,并且可在 CREATE TABLE 或 ALTER TABLE 语句中定义。 展开全文
主关键字(primary key)是表中的一个或多个字段,它的值用于唯一的标识表中的某一条记录。在两个表的关系中,主关键字用来在一个表中引用来自于另一个表中的特定记录。主关键字是一种唯一关键字,表定义的一部分。一个表的主键可以由多个关键字共同组成,并且主关键字的列不能包含空值。主关键字是可选的,并且可在 CREATE TABLE 或 ALTER TABLE 语句中定义。
信息
外文名
primary key
简    称
主键
作    用
保持实体的完整性
介    绍
一个表只有一个主关键词
中文名
主关键词
主关键字概念
主关键字(主键,primary key)是被挑选出来, 作表的行的唯一标识的候选关键字。一个表只有一个主关键字。主关键字又可以称为主键。 主键可以由一个字段,也可以由多个字段组成,分别称为单字段主键或多字段主键。又称主码。并且它可以唯一确定表中的一行数据,或者可以唯一确定一个实体。设K是关系模式R(U,F)中的属性或属性组,K’是K的任一真子集。若K→U,而不存在K’→U,则K为R的候选码(Candidate Key)Ø 若候选码多于一个,则选其中的一个为主码(Primary Key);Ø 包含在任一候选码中的属性,叫做主属性(Primary Attribute);Ø 不包含在任何码中的属性称为非主属性(Nonprime Attribute)或非码属性(Nonkey Attribute)Ø 关系模式中,最简单的情况是单个属性是码,称为单码(Single Key);最极端的情况是整个属性组是码,称为全码(All-Key)。签约(演员名,制片公司,电影名)外码:设有两个关系R和S,X是R的属性或属性组,并且X不是R的码,但X是S的码(或与S的码意义相同),则称X是R的外部码(Foreign Key),简称外码或外键。如:职工(职工号,姓名,性别,职称,部门号)部门(部门号,部门名,电话,负责人)其中职工关系中的“部门号”就是职工关系的一个外码。在此需要注意,在定义中说X不是R的码,并不是说X不是R的主属性,X不是码,但可以是码的组成属性,或者是任一候选码中的一个主属性。
收起全文
精华内容
参与话题
问答
  • Navicat Navicat中怎么设置主键自增长?

    Navicat  Navicat   中怎么设置主键自增长? mysql

    点击设计表,然后

    出现如下菜单

    展开全文
  • MySQL自增主键详解

    万次阅读 多人点赞 2019-06-02 10:02:16
    一、自增值保存在哪儿? 不同的引擎对于自增值的保存策略不同 1.MyISAM引擎的自增值保存在数据文件中 2.InnoDB引擎的自增值,在MySQL5.7及之前的版本,自增值保存在内存里,并没有持久化。每次重启后,第一次打开表...

    一、自增值保存在哪儿?

    不同的引擎对于自增值的保存策略不同

    1.MyISAM引擎的自增值保存在数据文件中

    2.InnoDB引擎的自增值,在MySQL5.7及之前的版本,自增值保存在内存里,并没有持久化。每次重启后,第一次打开表的时候,都会去找自增值的最大值max(id),然后将max(id)+步长作为这个表当前的自增值

    select max(ai_col) from table_name for update;
    

    在MySQL8.0版本,将自增值的变更记录在了redo log中,重启的时候依靠redo log恢复重启之前的值

    二、自增值修改机制

    如果字段id被定义为AUTO_INCREMENT,在插入一行数据的时候,自增值的行为如下:

    1.如果插入数据时id字段指定为0、null或未指定值,那么就把这个表当前的AUTO_INCREMENT值填到自增字段

    2.如果插入数据时id字段指定了具体的值,就直接使用语句里指定的值

    假设,某次要插入的值是X,当前的自增值是Y

    1.如果X<Y,那么这个表的自增值不变

    2.如果X>=Y,就需要把当前自增值修改为新的自增值

    新的自增值生成算法是:从auto_increment_offset(初始值)开始,以auto_increment_increment(步长)为步长,持续叠加,直到找到第一个大于X的值,作为新的自增值

    三、自增值的修改时机

    创建一个表t,其中id是自增主键字段、c是唯一索引,建表语句如下:

    CREATE TABLE `t` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `c` int(11) DEFAULT NULL,
      `d` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `c` (`c`)
    ) ENGINE=InnoDB;
    

    假设,表t里面已经有了(1,1,1)这条记录,这时再执行一条插入数据命令:

    insert into t values(null, 1, 1); 
    

    执行流程如下:

    1.执行器调用InnoDB引擎接口写入一行,传入的这一行的值是(0,1,1)

    2.InnoDB发现用于没有指定自增id的值,获取表t当前的自增值2

    3.将传入的行的值改成(2,1,1)

    4.将表的自增值改成3

    5.继续执行插入数据操作,由于已经存在c=1的记录,所以报Duplicate key error(唯一键冲突),语句返回

    对应的执行流程图如下:
    在这里插入图片描述
    在这之后,再插入新的数据行时,拿到的自增id就是3。出现了自增主键不连续的情况

    唯一键冲突和事务回滚都会导致自增主键id不连续的情况

    四、自增锁的优化

    自增id锁并不是一个事务锁,而是每次申请完就马上释放,以便允许别的事务再申请

    但在MySQL5.0版本的时候,自增锁的范围是语句级别。也就是说,如果一个语句申请了一个表自增锁,这个锁会等语句执行结束以后才释放

    MySQL5.1.22版本引入了一个新策略,新增参数innodb_autoinc_lock_mode,默认值是1

    1.这个参数设置为0,表示采用之前MySQL5.0版本的策略,即语句执行结束后才释放锁

    2.这个参数设置为1

    • 普通insert语句,自增锁在申请之后就马上释放
    • 类似insert … select这样的批量插入数据的语句,自增锁还是要等语句结束后才被释放

    3.这个参数设置为2,所有的申请自增主键的动作都是申请后就释放锁

    为了数据的一致性,默认设置为1
    在这里插入图片描述
    如果sessionB申请了自增值以后马上就释放自增锁,那么就可能出现这样的情况:

    • sessionB先插入了两行数据(1,1,1)、(2,2,2)
    • sessionA来申请自增id得到id=3,插入了(3,5,5)
    • 之后,sessionB继续执行,插入两条记录(4,3,3)、(5,4,4)

    当binlog_format=statement的时候,两个session是同时执行插入数据命令的,所以binlog里面对表t2的更新日志只有两种情况:要么先记sessionA的,要么先记录sessionB的。无论是哪一种,这个binlog拿到从库执行,或者用来恢复临时实例,备库和临时实例里面,sessionB这个语句执行出来,生成的结果里面,id都是连续的。这时,这个库就发生了数据不一致

    解决这个问题的思路:

    1)让原库的批量插入数据语句,固定生成连续的id值。所以,自增锁直到语句执行结束才释放,就是为了达到这个目的

    2)在binlog里面把插入数据的操作都如实记录进来,到备库执行的时候,不再依赖于自增主键去生成。也就是把innodb_autoinc_lock_mode设置为2,同时binlog_format设置为row

    如果有批量插入数据(insert … select、replace … select和load data)的场景时,从并发插入数据性能的角度考虑,建议把innodb_autoinc_lock_mode设置为2,同时binlog_format设置为row,这样做既能并发性,又不会出现数据一致性的问题

    对于批量插入数据的语句,MySQL有一个批量申请自增id的策略:

    1.语句执行过程中,第一次申请自增id,会分配1个

    2.1个用完以后,这个语句第二次申请自增id,会分配2个

    3.2个用完以后,还是这个语句,第三次申请自增id,会分配4个

    4.依次类推,同一个语句去申请自增id,每次申请到的自增id个数都是上一次的两倍

    insert into t values(null, 1,1);
    insert into t values(null, 2,2);
    insert into t values(null, 3,3);
    insert into t values(null, 4,4);
    create table t2 like t;
    insert into t2(c,d) select c,d from t;
    insert into t2 values(null, 5,5);
    

    insert … select,实际上往表t2中插入了4行数据。但是,这四行数据是分三次申请的自增id,第一次申请到了id=1,第二次被分配了id=2和id=3,第三次被分配到id=4到id=7

    由于这条语句实际上只用上了4个id,所以id=5到id=7就被浪费掉了。之后,再执行insert into t2 values(null, 5,5),实际上插入了的数据就是(8,5,5)

    这是主键id出现自增id不连续的第三种原因

    五、自增主键用完了

    自增主键字段在达到定义类型上限后,再插入一行记录,则会报主键冲突的错误

    以无符号整型(4个字节,上限就是23212^{32}-1)为例,通过下面这个语句序列验证一下:

    CREATE TABLE t ( id INT UNSIGNED auto_increment PRIMARY KEY ) auto_increment = 4294967295;
    INSERT INTO t VALUES(NULL);
    INSERT INTO t VALUES(NULL);
    

    第一个insert语句插入数据成功后,这个表的AUTO_INCREMENT没有改变(还是4294967295),就导致了第二个insert语句又拿到相同的自增id值,再试图执行插入语句,报主键冲突错误

    推荐资料

    https://time.geekbang.org/column/article/80531

    展开全文
  • 二、回归主题,主键的添加、删除等操作 1.有命名主键 1)有命名主键的添加 2)有命名主键的删除 3)有命名主键的修改 2.无命名主键 1)无命名主键的创建 2)无命名主键的删除 3)无命名主键的修改 附加: ...

     

    目录

    一、前提

    二、回归主题,主键的添加、删除等操作

    1.有命名主键

    1)有命名主键的添加

    2)有命名主键的删除

    3)有命名主键的修改

    2.无命名主键

    1)无命名主键的创建

    2)无命名主键的删除

    3)无命名主键的修改

    附加:

    user_constraints 和user_cons_columns表的作用及其联系 

     

    一、前提

    主键解释:

           一个表的唯一关键字 比如一个学生表 学号不能重复且唯一 ,学号就是关键字,即为主键。

    区别于外键:

           外键就是跟其他表联系的字段 ,还是比如有一张学生表 还有一张选课表,这个时候要修改学生表中的学号 ,选课表里对应的就也得变,这样就需要给选课表加学号作为外键约束,这样当你修改学号时 所有外键关联的就都改了

    二、回归主题,主键的添加、删除等操作

    1.有命名主键

    1)有命名主键的添加

    ①建表时添加主键(yy为主键“ID”的主键名称)

    CREATE TABLE table_test(
    
    id INT NOT NULL,       --注意:主键必须非空
    
    name VARCHAR(20) NOT NULL,
    
    address VARCHAR(20),
    
    constraint yy PRIMARY KEY(id)
    
    );

    ②建表后添加主键

    alter table table_test add constraint yy primary key(id);
    公式:alter table 表名 add constraint yy primary key(主键1,主键2);

    2)有命名主键的删除

    ALTER TABLE table_test DROP CONSTRAINT yy;
    公式:ALTER TABLE 表名DROP CONSTRAINT 主键名;

    3)有命名主键的修改

    需先删除主键,再进行添加

    2.无命名主键

    1)无命名主键的创建

    ①建表时添加主键(主键“ID”的主键名称需要查询出来,下文有方法)

    CREATE TABLE table_test(
    
    id INT NOT NULL,       --注意:主键必须非空
    
    name VARCHAR(20) NOT NULL,
    
    address VARCHAR(20),
    
    PRIMARY KEY(id)
    
    );

    ②建表后添加主键

    alter table table_test add primary key (id);
    公式:alter table 表名 add primary key(主键字段1,主键字段2...); 

    2)无命名主键的删除

    ①先查出来主键名(constraint_name),user_cons_columns表会在文末给出解释

    SELECT t.* from user_cons_columns t where t.table_name  = 'TABLE_TEST' and t.position is not null;
    公式:SELECT t.* from user_cons_columns t where t.table_name  = '表名' and t.position is not null;   --表名必须大写,如:TABLE_TEST

    ②再执行删除的SQL

    ALTER TABLE table_test DROP CONSTRAINT SYS_C0056038;  
    公式:ALTER TABLE 表名 DROP CONSTRAINT 主键名;

    3)无命名主键的修改

    需先删除主键,再进行添加

    附加:

    user_constraints 和user_cons_columns表的作用及其联系 


            user_constraints:是表约束的视图,描述的是约束类型(constraint_type)是什么,属于哪些表(table_name),如果约束的类型为R(外键)的话,那么r_constraint_name字段存放的就是被引用主表中的主键约束名。   
            user_cons_columns:是表约束字段的视图,说明表中的和约束相关的列参与了哪些约束。这些约束有主键约束,外键约束,索引约束.
            两者可以通过(owner,constraint_name,table_name)关联 

     

    展开全文
  • 自增主键

    万次阅读 2020-09-15 23:09:42
    在InnoDB存储引擎中,主键索引是作为聚簇索引存在的,也就是说,主键索引的B+树叶子节点上存储了主键索引以及全部的数据(按照顺序),如果主键索引是自增ID,那么只需要不断向后排列即可,如果是UUID,由于到来的ID与原来的...

          在InnoDB存储引擎中,主键索引是作为聚簇索引存在的,也就是说,主键索引的B+树叶子节点上存储了主键索引以及全部的数据(按照顺序),如果主键索引是自增ID,那么只需要不断向后排列即可,如果是UUID,由于到来的ID与原来的大小不确定,会造成非常多的数据插入,数据移动,然后导致产生很多的内存碎片,进而造成插入性能的下降.

     

        总之,在数据量大一些的情况下,用自增主键性能会好一些

    展开全文
  • 1、UUID mysql生成uuid: SELECT UUID(); UUID主键的好处: UUID主键的缺点: 2、主键自动增长 ...分布式情况下的主键可以采用第三方组件,如MyCat等。 ...
  • 复合主键与联合主键

    万次阅读 多人点赞 2017-05-02 17:05:57
    一、复合主键  所谓的复合主键 就是指你表的主键含有一个以上的字段组成,不使用无业务含义的自增id作为主键。 比如  create table test ( name varchar(19), id number, value varchar(10), primary ...
  • 首先说明 键字=码字,所以 主键=主码=主关键字,候选键=候选码=候选关键字... 所谓关系键,指的是一个表中的一个(或一组)属性,用来标识该表的每一行或与另一个表产生联系。 话不多说,上图:  相信这个图...
  • oracle主键和复合主键(联合主键

    千次阅读 2019-09-02 17:57:03
    1.主键和复合主键,查询性能相同(索引高度相同,恰当的运用索引) 2.主键和复合组件,(update,insert)性能不同(因为复合主键会用更多的块来创建索引,所以update,insert性能低) 复合主键的原理 ...
  • 文章目录定义主键使用SSMS工具定义主键使用SQL方式定义主键方式一:在创建数据表的时候定义主键方式二:修改数据表定义主键删除主键使用SSMS工具删除主键方式一:在对象资源管理器中删除主键方式二:在表设计器中...
  • MySQL删除主键、添加主键约束

    万次阅读 2018-09-21 11:43:28
    将原自增长主键值整体+1000 、 起始值1000 、 最大ID5000 执行更新语句报错、主键重复 UPDATE table_name SET id= id+1000; 解决方法 设置为不自动增长:alter table table_name modify id int(11); 或者alter ...
  • Oracle主键保证了单条记录的唯一性,设置了主键的表在插入数据的时候比没有设置主键的表速度更快一些,在给某一张表设置或者更改主键之前,先检查下当前表时候已经设置了主键,可以按照如下步骤进行操作 1、查询某个...
  • 数据库分库分表(sharding)系列(二) 全局主键生成策略

    万次阅读 多人点赞 2012-07-03 09:40:05
    本文将主要介绍一些常见的全局主键生成策略,然后重点介绍flickr使用的一种非常优秀的全局主键生成方案。关于分库分表(sharding)的拆分策略和实施细则,请参考该系列的前一篇文章:数据库分库分表(sharding)系列(一)...
  • 逻辑主键和物理主键

    千次阅读 2018-07-04 08:37:26
    物理主键,可以在系统中由... 在大项目中,一般用物理主键,方便数据库的迁移,因为在数据迁移过程中可能物理主键会存在这样或那样的问题,这时我们就可以选择放弃原有的物理主键,只移动数据内容并生成新的物理主键。...
  • 修改主键&删除主键

    千次阅读 2018-01-08 14:29:02
    注意:我们是没有办法更新主键的,主键必须先删除后添加。 更新主键(name字段添加主键) 1.先删除主键:alter table 表名 drop primary key; 给name字段添加主键 查看表的...
  • SQLServer数据库设置主键主键自增

    万次阅读 2019-06-21 07:36:34
    在想要设置主键的那一行,右击就会出现如下图所示的页面,点击设置主键 如何设置主键自增 在设计表的页面的下方,有一个标识规范,(是标识),后面点击是,默认是否,就可以了 ...
  • 逻辑主键、业务主键和复合主键

    千次阅读 2018-07-17 00:09:49
    主键(PRIMARY KEY):表通常具有包含唯一标识表中每一行的值的一列或一组列。这样的一列或多列称为表的主键 (PK),用于强制表的实体完整性。 外键(FOREIGN KEY):外键 (FK) 是用于建立和加强两个表数据之间的链接的...
  • 谈谈企业信息系统数据库设计是使用id主键还是uuid逻辑主键或业务主键
  • 在我们开发的过程中,总感觉一张表就一个主键。但是事情往往没有我们想象的那么简单,一张表其实也是可以有多个主键。 如上图所示,其实说多个主键也不对,可以说是复合主键。意思为 这2个字段都不是唯一的,2个...
  • 主键索引和主键索引的区别是:非主键索引的叶子节点存放的是主键的值,主键索引的叶子节点存放的是整行数据。其中,非主键索引又称为二级索引,主键索引又称为聚簇索引。 根据这两种结构我们来进行下查询,看看...
  • mysql的复合主键创建及删除

    万次阅读 2019-06-19 21:22:26
    摘要: mysql的联合主键:用2个字段(或者多个字段,后面具体都是用2个字段组合)来确定一条记录,说明,这2个字段都不是唯一的,2个字段可以分别重复,这么设置的好处,可以很直观的看到某个重复字段的记录条数。...
  • Mysql主键选择之UUID和自增主键

    万次阅读 2018-03-29 11:44:03
    引言之前有段时间用postgresql 数据库,在上云之后,从自增主键变为uuid,感觉uuid全球唯一,很方便。最近用mysql,发现mysql主键都是选择自增主键,仔细比较一下,为什么mysql选择自增主键,有什么不同。在mysql5.0...
  • Mysql增加主键或者修改主键的sql语句

    万次阅读 2018-07-31 10:43:37
    Mysql增加主键或者更改表的列为主键的sql语句 添加表字段 alter table table1 add transactor varchar(10) not Null; alter table table1 add id int unsigned not Null auto_increment primary key 修改某个表...
  • 数据库主键

    2018-07-27 19:52:26
    主键:用来唯一确定一 条记录的字段作用:保证数据的唯一-性特点: 1.唯一性,2.不能为空分类: 1.逻辑主键( 1.自增字段。2.GUIP ) 2.业务主键(业务逻辑中出现的字段作为主键) 3.组合主键(联合主键)选择主键的策略:...
  • 逻辑主键 与 业务主键

    千次阅读 2016-03-10 22:21:31
    逻辑主键 与 业务主键@(数据库)[笔记|2016.03.10]逻辑主键 与 业务主键 逻辑主键 业务主键 总结 提示对逻辑主键、业务主键和复合主键的思考 —— 资料来源 逻辑主键存在用户或维护人员误录入数据到业务主键中的问题...
  • MySQL主键

    千次阅读 2018-06-27 11:21:50
    MySQL主键设计 一. MySQL主键设计原则 MySQL主键应当是对用户没有意义的。 MySQL主键应该是单列的,以便提高连接和筛选操作的效率(当然复合主键是可以的,只是不建议) 永远也不要更新MySQL主键 MySQL主键不应...
  • Oracle主键和联合主键

    千次阅读 2019-04-03 08:11:59
    在oracle数据库中,一张表中的每一行数据被称为一条记录。一条记录通常都是由多个字段所组成的...不能重复不是指两条记录不完全相同,而是指能够通过某个字段唯一区分出不同的记录,这个字段被称为主键。 假如我把...
  • 关于业务主键和逻辑主键

    千次阅读 2017-11-03 22:00:52
    业务主键(自然主键):在数据库表中把具有业务逻辑含义的字段作为主键,称为“自然主键(Natural Key)”。 逻辑主键(代理主键):在数据库表中采用一个与当前表中逻辑信息无关的字段作为其主键,称为“代理主键...
  • UUID做主键,其他字段相同,插入100万条数据,用了3.5个小时 自增主键,其他字段相同,插入相同的100万条数据,用了16分钟 2.查询方面 UUID做主键,select count() from info 查询数量花了2.86秒 自增主键,...

空空如也

1 2 3 4 5 ... 20
收藏数 96,626
精华内容 38,650
关键字:

主键