主键、唯一键与唯一索引的区别

一般,我们看到术语“索引”和“键”交换使用,但实际上这两个是不同的。索引是存储在数据库中的一个物理结构,键纯粹是一个逻辑概念。键代表创建来实施业务规则的完整性约束。索引和键的混淆通常是由于数据库使用索

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

一般,我们看到术语“索引”和“键”交换使用,但实际上这两个是不同的。索引是存储在数据库中的一个物理结构,键纯粹是一个逻辑概念。键代表创建来实施业务规则的完整性约束。索引和键的混淆通常是由于数据库使用索引来实施完整性约束。

 

接下来我们看看数据库中的主键约束、唯一键约束和唯一索引的区别。

SQL> select * from v$version;

 

 

BANNER

——————————————————————————–

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 – Production

PL/SQL Release 11.2.0.1.0 – Production

CORE    11.2.0.1.0      Production

TNS for Linux: Version 11.2.0.1.0 – Production

NLSRTL Version 11.2.0.1.0 – Production

 

SQL> create table test (          

  2  id int,

  3  name varchar2(20),

  4  constraint pk_test primary key(id))

  5  tablespace users;

 

Table created.

 

SQL> select constraint_name, constraint_type from user_constraints;

 

CONSTRAINT_NAME                C

—————————— –

PK_TEST                        P

 

在test表中,我们指定了ID列作为主键,Oracle数据库会自动创建一个同名的唯一索引:

SQL> select index_name, index_type, uniqueness, tablespace_name

  2  from user_indexes

  3  where table_owner=’SCOTT’

  4  and table_name = ‘TEST’;

 

INDEX_NAME           INDEX_TYPE           UNIQUENES TABLESPACE_NAME

——————– ——————– ——— ——————————

PK_TEST              NORMAL               UNIQUE    USERS

 

此时,如果我们再试图在ID列上创建一个唯一索引,Oracle会报错,因为该列上已经存在一个唯一索引:

SQL> create unique index idx_test_uk on test(id);

create unique index idx_test_uk on test(id)

                                        *

ERROR at line 1:

ORA-01408: such column list already indexed

即使创建非唯一索引也不行:

SQL> create index idx_test_id on test(id);

create index idx_test_id on test(id)

                                 *

ERROR at line 1:

ORA-01408: such column list already indexed

 

 

那么唯一键约束的情况是怎样的呢?

SQL> drop table test purge;

 

Table dropped.

 

SQL> create table test(

  2  id int,

  3  name varchar2(20),

  4  constraint uk_test unique(id));

 

Table created.

 

SQL> select constraint_name, constraint_type from user_constraints;

 

 

CONSTRAINT_NAME                C

—————————— –

UK_TEST                        U

 

查看此时的索引情况:

SQL> select index_name, index_type, uniqueness, tablespace_name

  2  from user_indexes

  3  where table_owner=’SCOTT’

  4  and table_name = ‘TEST’;

 

INDEX_NAME           INDEX_TYPE           UNIQUENES TABLESPACE_NAME

——————– ——————– ——— ——————————

UK_TEST              NORMAL               UNIQUE    USERS

Oracle同样自动创建了一个同名的唯一索引,而且也不允许再在此列上创建唯一索引或非唯一索引。

 

 

 

我们知道,主键约束要求列值非空(NOT NULL),那么唯一键约束是否也要求非空呢?

SQL> insert into test values(1, ‘Sally’);

 

1 row created.

 

SQL> insert into test values(null, ‘Tony’);

 

1 row created.

 

SQL> insert into test values(null, ‘Jack’);

 

1 row created.

 

SQL> select * from test;

 

        ID NAME

———- ——————–

         1 Sally

           Tony

           Jack

从实验结果来看,唯一键约束并没有非空要求。

 

接下来我们看看唯一索引对列值的非空要求有什么不同。

SQL> drop table test purge;

 

Table dropped.

 

SQL> create table test(

  2  id int,

  3  name varchar2(20));

 

Table created.

 

SQL> create unique index idx_test_id on test (id);

 

Index created.

 

SQL> insert into test values(1, ‘Sally’);

 

1 row created.

 

SQL> insert into test values(null, ‘Tony’);

 

1 row created.

 

SQL> insert into test values(null, ‘Jack’);

 

1 row created.

 

SQL> select * from test;

 

        ID NAME

———- ——————–

         1 Sally

           Tony

           Jack

通过实验,我们看出唯一索引与唯一键约束一样对列值非空不做要求。

 

如果我们让主键约束或者唯一键约束失效,Oracle自动创建的唯一索引是否会受到影响?

SQL> drop table test purge;

 

Table dropped.

 

SQL> create table test(

  2  id int,

  3  name varchar2(20),

  4  constraint uk_test unique(id));

 

Table created.

 

SQL> select index_name, index_type, uniqueness from user_indexes;

 

INDEX_NAME                     INDEX_TYPE                  UNIQUENES

—————————— ————————— ———

UK_TEST                        NORMAL                      UNIQUE

 

SQL> alter table test disable constraint uk_test;

 

 

Table altered.

 

SQL> select index_name, index_type, uniqueness from user_indexes;

 

no rows selected

当主键约束或者唯一键约束失效时,Oracle会删除隐式创建的唯一索引。

 

如果我们先创建唯一索引,再创建主键或者唯一键约束,情况又会怎样呢?

SQL> drop table test purge;

 

Table dropped.

 

SQL> create table test(

  2  id int,

  3  name varchar2(20));

 

Table created.

 

SQL> create unique index idx_test_id on test (id);

 

Index created.

 

SQL> select index_name, index_type, uniqueness

  2  from user_indexes

  3  where table_owner = ‘SCOTT’

  4  and table_name = ‘TEST’;

 — 何问起 hovertree.com 

 

INDEX_NAME                     INDEX_TYPE                  UNIQUENES

—————————— ————————— ———

IDX_TEST_ID                    NORMAL                      UNIQUE

 

SQL> alter table test add constraint uk_test unique (id);

 

Table altered.

 

SQL> select index_name, index_type, uniqueness

  2  from user_indexes

  3  where table_owner = ‘SCOTT’

  4  and table_name = ‘TEST’;

 

INDEX_NAME                     INDEX_TYPE                  UNIQUENES

—————————— ————————— ———

IDX_TEST_ID                    NORMAL                      UNIQUE

 

SQL> select constraint_name, constraint_type

  2  from user_constraints

  3  where table_name = ‘TEST’;

 

CONSTRAINT_NAME                C

—————————— –

UK_TEST                        U

 

SQL> alter table test disable constraint uk_test;

 

Table altered.

 

SQL> select constraint_name, constraint_type, status

  2  from user_constraints

  3  where table_name = ‘TEST’;

 

CONSTRAINT_NAME                C STATUS

—————————— – ——–

UK_TEST                        U DISABLED

 

SQL> select index_name, index_type, uniqueness, status

  2  from user_indexes

  3  where table_owner = ‘SCOTT’

  4  and table_name = ‘TEST’;

 

INDEX_NAME                     INDEX_TYPE                  UNIQUENES STATUS

—————————— ————————— ——— ——–

IDX_TEST_ID                    NORMAL                      UNIQUE    VALID

 

实验结果表明,先创建的唯一索引不受约束失效的影响。

 

总结如下:

(1)主键约束和唯一键约束均会隐式创建同名的唯一索引,当主键约束或者唯一键约束失效时,隐式创建的唯一索引会被删除;

(2)主键约束要求列值非空,而唯一键约束和唯一索引不要求列值非空;

(3)相同字段序列不允许重复创建索引

http://www.cnblogs.com/roucheng/

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/120518.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • oracle number类型 p、s参数说明[通俗易懂]

    oracle number类型 p、s参数说明[通俗易懂] oraclenumber类型采用科学计数法表示,p表示有效数字的个数,s表示精度;如果定义字段类型为number(p,s)则该字段所能表示的最大正数是(10p-1)*10-s最小负数-(10p-1)*10-s;所有该范围之间的数字均可根据精度四舍五入后插入该字段;否则将会报错。  

    2022年7月24日
    5
  • 光栅投影中Gamma校正

    光栅投影中Gamma校正学习郑东亮达飞鹏《提高数字光栅投影测量系统精度的gamma校正技术》一文后,对其中的关键技术进行了解析。摄像机获得的实际灰度图像:其中是整个系统的gamma值,是预编码值(需要根据实验进行选择),是幅度调制(保证归一化),是背景光强,和是由系统确定的值(需要通过投射不同的灰度图进行解算)。gamma校正的目的:选择一个合适的预编码值,使得,从而使系统的gamma失真得以消除或者减…

    2022年6月22日
    22
  • 记录下关于调用RAR解压缩的问题

    记录下关于调用RAR解压缩的问题

    2021年9月15日
    46
  • PahoMQTT_mqtt安装

    PahoMQTT_mqtt安装1.安装npminstall paho-mqtt-s2.初始化constPahoMQTT=require(‘paho-mqtt’)constname=newDate().getTime()+’client’constclient=newPahoMQTT.Client(‘www.100link.net’,Number(61615),nam…

    2025年6月15日
    0
  • Docker(三) 通过gitlab部署CICD「建议收藏」

    Docker(三) 通过gitlab部署CICD「建议收藏」文章目录Docker(三)docker通过gitlab部署CICD一、部署gitlab1.1拉取gitlab镜像1.2运行gitlab镜像1.3配置1.4若发生502报错二、CI2.1Runner搭建2.2注册Runner2.3样例测试2.3.1新建maven-tomcat项目2.3.2创建.gitlab-ci.yml2.3.3编写Dockerfile文件2.3.4编写docker-compose.yml文件三、CD3.1安装Jenkins3.2配置目标服务器及Gitla

    2022年5月2日
    124
  • 跨境电商erp源码java大卖先生_erp 开源

    跨境电商erp源码java大卖先生_erp 开源1订单管理本模块支持多平台订单自动下载同步以及多帐号多店铺订单管理,方便用户对销售进行科学、直观的分类管理。包括订单处理,包装验货,称重出库,智能交运,交运日志,快速拣货,快速发货等子模块。2商品管理(SKU)商品管理模块,提供对亚马逊店逊商品进行线下管理的功能,包括但不限于中文名称、英文名称,售价等相应管理3.采购管理采购管理主要对于商品采购、入库、及供应商的设置,并于商品细分,包括采购管理、入库管理和供应商管理模块。4.物流管理此模块主要提供用户设置速…

    2022年9月20日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号