主键 订阅
主关键字(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不是码,但可以是码的组成属性,或者是任一候选码中的一个主属性。
收起全文
精华内容
下载资源
问答
  • 本节文章主要介绍了oracle删除主键查看主键约束及创建联合主键,示例代码如下,需要的朋友可以参考下
  • 什么是主键主键是表中唯一标识该表中每个元组(行)的列。主键对表实施完整性约束。表中只允许使用一个主键主键不接受任何重复值和空值。表中的主键值很少更改,因此在选择主键是需要小心,要选择很少发生更改...
  • MySQL索引之主键索引

    2020-12-15 16:43:01
    在MySQL里,主键索引和辅助索引分别是什么意思,有什么区别? 上次的分享我们介绍了聚集索引和非聚集索引的区别,本次我们继续介绍主键索引和辅助索引的区别。 1、主键索引 主键索引,简称主键,原文是PRIMARY KEY,...
  • 主键必须包含的值。主键列不能包含 NULL 值。每个表都应该有一个主键,并且每个表只能有一个主键主键约束操作包含了添加约束和删除约束,修改约束其实是添加约束或者删除约束。添加主键约束比较 简单,但是删除一...
  • 主要介绍了java实现数据库主键生成示例,需要的朋友可以参考下
  • Mybatis插入数据返回自增主键 Mybatis插入数据以后只会返回影响的数据库行数,如果是插入一条数据成功则返回1,失败返回零,插入多条返回插入成功的数量。 通过注解或者xml配置无法直接返回自增的主键。Mybatis插入...
  • 主要介绍了详解MyBatis中主键回填的两种实现方式,主键回填其实是一个非常常见的需求,特别是在数据添加的过程中,我们经常需要添加完数据之后,需要获取刚刚添加的数据 id,有兴趣的可以参考一下
  • mybatis自增主键文档

    2018-05-25 10:37:13
    mybatis进行插入操作时,如果表的主键是自增的,针对不同的数据库相应的操作也不同。基本上经常会遇到的就是 Oracle Sequece 和 Mysql 自增主键,至于其他的手动生成唯一主键的问题在这里就不讨论了,这里主要说明下...
  • 主要介绍了mybatis-plus实体类主键策略有3种(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • sql server创建复合主键的2种方法,需要的朋友可以参考一下
  • 主键自增长列在进行数据插入的时候,很有用的,如可以获取返回的自增ID值,接下来将介绍SQL Server如何设置主键自增长列,感兴趣的朋友可以了解下,希望本文对你有所帮助
  • 主要介绍了详解mybatis plus使用insert没有返回主键的处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • Hibernate复合主键

    2018-06-03 21:05:34
    一个简单的复合主键的做关联类的例子
  • PRIMARY KEY联合主键

    2020-12-14 09:32:40
    阅读指南基本概念创建表时定义主键约束修改表时定义主键约束删除主键约束 基本概念 主键(PRIMARY KEY)的完整称呼是“主键约束”; 作用:为了便于 DBMS 更快的查找到表中的记录; 分类:①单字段主键;②多字段...
  • 主要介绍了初探SQL语句复合主键与联合主键的相关内容,具有一定参考价值,这里给大家分享下,需要的朋友可以参考。
  • oracle 创建id主键序列的 脚本 及 使用方式 oracle 创建id主键序列的 脚本 及 使用方式
  • mybatis获取自增主键的值 ,mybatis获取自增主键的值!
  • 简单的建表联系,包括主键外键,帮助新手快速熟悉建表的语句操作
  • MybatisPlus中插入数据获取主键值示例代码MybatisPlus中插入数据获取主键值示例代码
  • JPA主键策略(针对数据库自增字段重置后无效检查项) JPA主键生成策略会影响数据库自增字段的重置
  • sqlserver在有数据情况下修改主键为自增 网上方法都有缺陷 自己写了一个版本,欢迎大家参考,不好用吗,大家都不评价
  • JPA_5_联合主键

    2016-05-30 22:22:17
    针对JPA资料进行整理,根据传智播客的教学视频,边看边写,文档包含了jpa的基本概念,相关注解解释,及一些增删改查的demo。本文档方便了对jpa的学习与复习,快速掌握基本操作。
  • 主键自增长表创建

    2017-07-06 21:21:39
    用于oracle新手解决表的主键如何实现自增长,表结构设计的示例
  • Oracle添加主键、删除主键、修改主键

    万次阅读 多人点赞 2019-04-01 16:48:43
    二、回归主题,主键的添加、删除等操作 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)关联 

     

    展开全文
  • oracle查询主键

    2014-10-11 12:04:48
    查询ORACLE的主键的执行脚本,能够查询到ORACLE中表的主键
  • 主键是Long型的id生成方法,Java实现.snowflake算法.
  • Hibernate联合主键,MyEclipse的例子
  • MySQL自增主键auto_increment原理; MySQL的innodb_autoinc_lock_mode参数说明; MySQL的AUTO-INC锁原理; 自增主键出现间隙不连续现象的定位;

    一、背景:

    1.1、业务描述与SQL:

    为了保存机器上报信息(业务需求是每个机器只需保存最新的一条记录),原 SQL 语句如下(其中,machineId 的为唯一索引,t_report_pad 的 id 为 bigint 类型的自增主键):

    insert into t_report_pad
        (machine_id,pad_device_model,app_version,app_version_code,pad_version,pad_version_code,upgrade_status,reason,create_time,update_time) 
    values
        (#{machineId},#{padDeviceModel},#{appVersion},#{appVersionCode},#{padVersion},#{padVersionCode},#{upgradeStatus},#{reason},now(),now())

    这种情况下,当同一个 machine_id 多次发送 SQL 的时候,会造成唯一主键冲突问题,从而导致后面的机器信息添加不了,为了解决这种情况,业务中使用了 insert … on duplocate key update 语句优化原有语句,修改后的 SQL 语句如下,自此业务功能正常使用。

    insert into t_report_pad 
        (machine_id,pad_device_model,app_version,app_version_code,pad_version,pad_version_code,upgrade_status,reason,create_time,update_time)
    values
        (#{machineId},#{padDeviceModel},#{appVersion},#{appVersionCode},#{padVersion},#{padVersionCode},#{upgradeStatus},#{reason},now(),now())
    ON DUPLICATE KEY UPDATE
        pad_device_model=#{padDeviceModel},
        app_version=#{appVersion},
        pad_version=#{padVersion},
        pad_version_code=#{padVersionCode},
        app_version_code=#{appVersionCode},
        upgrade_status=#{upgradeStatus},
        reason=#{reason},
        update_time=now()

    1.2、问题 - 数据类型转换异常:

    运行一段时间之后,发现 t_report_pad 表中的自增主键 id 的值已经超过 int 类型的最大值,并且由于业务代码中使用 int 类型进行接收,从而导致业务功能出现异常(这里代码和 MySQL 中 ID 的类型不一致是因为, DBA 事前已经先修改了 ID 的数据类型,但是开发人员忘记同步修改代码中 Java 对象的类型),于是紧急修复了一个版本解决线上问题。

    1.3、深入分析:

    (1)现象:

    深入分析之后,发现 DB 表中的数据量只有 600W 条,但是自增主键 ID 却高达 21 亿,并且很多自增主键都不连续,那为什么会出现这种现象呢?是不是代码中存在bug?亦或是MySQL 中的自增主键步长设置有问题?亦或是其他?本着打破砂锅问到底的心态,查询多方资料之后,最终终于找到这种现象的原因:对于这种自增主键出现间隙的情况,既不是代码的bug,也不是DB参数设置的问题,而是 mysql 中 为了优化高并发下 auto_increment 自增主键获取的性能,而默认配置的一种算法模式(该算法模式通过 innodb_autoinc_lock_mode 参数配置)导致的,特别是在使用 insert ... on duplicate key update 语法的时候,很容易出现主键间隙,是一种正常的使用现象。

    (2)分析过程:

    ① 分析过程1 - 查看代码中业务逻辑是否正常:查看 SQL 语句中是否手动设置了 ID 列的值,从上面的 SQL 语句可以很容易看出,并没有手动设置 id 的值,默认都是使用自增主键生成的数值。接着查看代码中是否存在删除表中对应的行记录,从而导出出现主键间隙的情况,经查看也不存在。

    ② 分析过程2 - 查看自增主键的步长设置:

    输入:

    show session variables like 'auto_increment%'

    结果如下:

    结果显示 DB 的自增主键的步长设置正常,默认都是自增 1,所以主键间隙问题也不是由这种情况导致的。

    ③ 分析过程3 - 自增主键的算法模式设置(最终定位到的问题所在):

    该参数只要由 innodb_autoinc_lock_mode 参数影响,具体看文章的第二、三部分

     

    二、MySQL 的 auto_increment 详解:

    1、auto_increment 的基本特性:

    MySQL的中 auto_increment 类型的属性主要用于为一个表中记录自动生成 ID。

    (1)当插入记录时,如果为 auto_increment 数据列明确指定了一个数值,则会出现两种情况:

    • 情况一:如果插入的值与已有编号重复,则会出现报错异常,因为 auto_increment 数据列的值必须是唯一的;
    • 情况二:如果插入的值大于已有编号,则会把该插入到数据列中,并使在下一个编号将从这个新值开始递增。也就是说,会跳过一些编号。

    (2)如果自增序列的最大值被删除了,则在插入新记录时,该值被重用。

    (3)如果使用 update 命令更新自增列,列值与已有的值重复,则会出错。如果大于已有值,则下一个编号从该值开始递增。

    2、关于 MySQL 的 auto_increment  所带来的锁表操作:

    (1)在 MySQL 5.1.22 前,MySQL 的 "insert-like" 会在执行语句的过程中使用一个表级的自增锁(AUTO-INC Lock)将整个表锁住,直到整个语句结束(而不是事务结束)。在此期间会阻塞其他的 insert-like、update 等语句,所以推荐使用程序将这些语句分成多条语句,一一插入,减少单一时间的锁表时间。

    insert-like语句:insert,insert … select,replace,replace … select,load data,insert ... values(),values()

    (2)在 MySQL 5.1.22 之后,MySQL 进行了改进,引入了参数 innodb_autoinc_lock_mode,通过这个参数控制 MySQL 的锁表逻辑。

    3、MySQL 的 innodb_autoinc_lock_mode 参数说明:

    innodb_autoinc_lock_mode 参数可用于配置自动增量锁定算法的模式,从而进行在可预测的自动递增值序列和插入操作的最大并发性之间进行权衡。

    3.1、insert 语句的 分类:

    前面提到了 insert-like 语句,就是指所有可以向表中增加行的语句,再进行细分的话,还可以分成三种类型:

    • (1)simple inserts:通过分析 insert 语句可以预先确定要插入的行数,包括 insert、insert ... values()、values() 语句
    • (2)bulk inserts:通过分析 insert 语句不能确定插入数量,包括 insert … select、replace … select、load data 语句。
    • (3)mixed-mode inserts:不确定是否需要分配 auto_increment id,如 insert into t (id,name) values (1,'a'),(null,'b'),(5,'c') 以及 insert… on duplicate key update。对于后者,它的最坏情况实际上是在 insert 语句后面又跟了一个 update,其中 auto_increment 列的分配值不一定会在 update 阶段使用

    3.2、innodb_autoinc_lock_mode 模式说明:

    • 0:这个表示 tradition,即传统模式(每次都会产生表锁)
    • 1:这个表示 consecutive,即连续模式(会产生一个轻量锁,simple insert 会获得批量的锁,保证连续插入)
    • 2:这个表示 interleaved,即交错模式(不会锁表,来一个处理一个,并发最高)

    (1)tradition 模式(innodb_autoinc_lock_mode=0):

    这种方式和 MySQL 5.1.22 之前一样,主要是提供一个向后兼容的能力。在该模式下,所有 insert 语句都要在开始执行的时候获得一个表级的 auto_inc 锁,直到语句结束(不是事务结束)时才释放这把锁,保证自增长值的分配是可预见、连续性、可重复性的,并确保给任何给定语句分配的自动递增值是连续的。但是由于  auto_inc 锁 需要一直保持到语句的结束,造成并发性较差。

    在主从复制的安全性方面,在 statement-based replication 的情况下,这意味着当在从服务器上复制SQL语句时,自动增量列使用与主服务器上相同的值。因为在该模式下,多个INSERT语句的执行结果是确定性的,SLAVE 可以再现与 MASTER 相同的数据,保证基于语句复制的安全性。

    (2)consecutive 模式(innodb_autoinc_lock_mode=1):

    MySQL 5.1.22 之后版本的默认模式,并发度相对加高,这个模式的好处是 auto_inc 锁在特定情况下不需要一直保持到语句的结束,只要语句得到了相应的值后就可以提前释放锁。这种模式下:

    • simple inserts:由于可以预先获得要插入的数量,通过在 mutex 互斥量的控制下获得所需数量的自动递增值来避免表级 auto-inc 锁,然后一次性分配足够的 auto_increment id,只锁住分配id的过程,而不是整个语句的操作过程。
    • bulk inserts:因为不能确定插入的数量,因此使用和以前的模式相同的表级锁定。innoDB 在处理每个SQL时一次性为 auto_increment 列分配新值
    • mixed-mode inserts:通过分析语句获得最坏情况下需要插入的数量,然后一次性分配足够的 auto_increment id,同样只会锁住分配id的过程。但这种方式下,会分配过多的id,而导致“浪费”。
    • 比如 insert into t1 (id,c2) values  (1,’a'), (null,’b'), (5,’c'), (null,’d');会一次性的分配4个id,而不管用户是否指定了部分id;
    • insert … on duplocate key update 一次性分配,而不管将来插入过程中是否会因为 duplicate key 而仅仅执行 update 操作。

    在主从复制的安全性方面,无论是 statement-based 还是 row-based 方式,该模式也都可以保证基于语句的主从复制的安全。

    (3)interleaved 模式(innodb_autoinc_lock_mode=2):

    该模式下,所有的 insert-like 语句都不会使用表级 auto-inc 锁,这种模式是来一个分配一个,只锁住 id 分配的过程,并且可以同时执行多个语句,是性能最好和最可扩展的锁定模式。它和 innodb_autoinc_lock_mode = 1 的区别在于,不会预分配多个。

    由于可以同时为多个语句生成自增长值(即跨语句交叉编号),可能会造成同一个语句插入的行生成的 auto_incremant 值不连续,也就是存在间隙。比如执行 “bulk inserts” 时,则在给任何给定语句分配的自动递增值中可能存在间隙。但是如果执行的是语句是 “simple inserts”,其中要插入的行数可提前知道,那么不会有间隙。

    最后在主从复制replication的安全性方面,当 binlog_format 为 statement-based 时(简称 SBR,statement-based replication),则会存在问题,因为是来一个分配一个,当并发执行时,“bulk inserts” 在分配时会同时向其他的 insert 分配,从而出现主从不一致(从库执行结果和主库执行结果不一样),因为 binlog 只会记录开始的insert id。但是如果 binlog_format 为 row-based 则不会出现问题。

    3.3、innodb_autoinc_lock_mode 的主从安全性问题总结:

    (1)主从的安全性:如果 binlog_format 使用基于行的或混合模式的复制,则所有自动增量锁定模式都是安全的,因为基于行的复制对SQL语句的执行顺序不敏感(混合模式会在遇到不安全的语句是使用基于行的复制模式),所以可以设置 innodb_autoinc_lock_mode = 2 可以获得更好的并发度。但是当 binlog_format 是基于语句复制 statement-base 的情况下,可设置 innodb_autoinc_lock_mode = 1,保证复制安全的同时,获得简单insert语句的最大并发度

    (2)innodb_autoinc_lock_mode 参数的设置是针对 innoDB 存储引擎,在 myisam 引擎情况下,无论什么样自增id锁都是表级锁。

     

    三、导致自增长列存在间隙的情况:

    通过上面文章的描述,最终可以确定导致自增主键出现间隙的原因在于,mixed-mode inserts 中的 insert… on duplicate key update,它的最坏情况实际上是在 insert 语句后面又跟了一个 update,其中 auto_increment 列的分配值不一定会在 update 阶段使用,从而导致自增主键间隙出现。

    1、为了防止出现同样的线上问题,有什么解决方案呢:

    (1)对于旧表的主键类型,在修改 DB 表中的字段类型的时候,必须同步修改代码中的对象属性类型

    (2)后续对于新表的主键类型,直接设置为 bigint,原因在于:

    • 当 mysql 表中的数据量较少时,int 类型的主键 与 bigint 类型的主键,对 DB 的性能与存储压力可以忽略不计。
    • 假如表中的数据比较多但还未达到 int 的最大值 21 亿时,但是出现了 DB 性能或者磁盘存储压力,靠使用 int 代替 bigint 类型带来的提升其实是微乎其微的。
    • 当 mysql 表中的数据量超过21亿时,int 类型的主键升级为 bigint 类型是必须的。

    (3)不使用uuid 的原因:

    一般情况下,MySQL数据库对于主键,推荐使用自增ID,因为在MySQL的 InnoDB 存储引擎中,主键索引是聚簇索引,主键索引的B+树的叶子节点按照顺序存储了主键值及数据,如果主键索引是自增ID,只需要按顺序往后排列即可,如果是UUID,ID是随机生成的,在数据插入时会造成大量的数据移动,产生大量的内存碎片,造成插入性能的下降。除此之外,UUID占用空间较大,建立的索引越多,造成的影响越大。

    2、其他导致自增列存在间隙的情况:

    (1)如果生成自动递增值的事务回滚,那些自动递增值将丢失。 一旦为自动增量列生成了值,无论是否完成 “insert-like” 语句以及包含事务是否回滚,这些值都不能回滚,也就是这种丢失的值不被重用。 因此,存储在表的 auto_increment 列中的值可能存在间隙。

    (2)如果用户在 insert 中为 auto_increment  指定 null 或者 0,InnoDB会将该行视为未指定值,并为其生成新值。

    (3)如果手动为 auto_increment 列分配了一个负值,则不会触发自动增量机制的行为。

    (4)DB 自增主键的步长设置

     

     

    参考文章:

    https://blog.csdn.net/fwkjdaghappy1/article/details/7663331

    https://blog.csdn.net/ashic/article/details/53810319

    展开全文
  • sql 主键自增

    2013-04-08 19:28:22
    在mysql中,直接把表的主键设为auto_increment类型,在MS SQLServer中,如果把表的主键设为identity类型, 在Oracle中,可以为每张表的主键创建一个单独的序列,然后从这个序列中获取自动增加的标识符,把它赋值给...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 614,796
精华内容 245,918
关键字:

主键