精华内容
下载资源
问答
  • Oracle | PL/SQL唯一索引(Unique Constraint)使用方法1 目标用演示样例演示怎样创建、删除、禁用和使用唯一性约束。2 什么是唯一性约束唯一性约束指表中一个字段或者多个字段联合起来可以唯一标识一条记录的约束。...

    Oracle | PL/SQL唯一索引(Unique Constraint)使用方法

    1 目标

    用演示样例演示怎样创建、删除、禁用和使用唯一性约束。

    2 什么是唯一性约束?

    唯一性约束指表中一个字段或者多个字段联合起来可以唯一标识一条记录的约束。

    联合字段中,可以包括空值。

    注:在Oracle中,唯一性约束最多能够有32列。

    唯一性约束能够在创建表时或使用ALTER TABLE语句创建。

    3 唯一性约束和主键的差别

    主键(Primary Key):全部组成主键的列都不能包括空值。

    唯一性约束(Unique Constraint):假设唯一性约束由多列组成,当中的部分列能够包括空值。

    Oracle中不容许在同样列上既创建主键又创建唯一性约束。

    4 创建表时定义唯一性约束

    1)语法:

    CREATE TABLE table_name

    (

    column1 datatype null/not null,

    column2 datatype null/not null,

    ...

    CONSTRAINT constraint_name UNIQUE (column1, column2,...,column_n)

    );

    2)基于单列的唯一性约束演示样例:

    create table tb_supplier

    (

    supplier_id number not null

    ,supplier_name varchar2(50)

    ,contact_name varchar2(50)

    ,CONSTRAINT tb_supplier_u1 UNIQUE (supplier_id)--创建表时创建唯一性约束

    );

    3)基于多列的唯一性约束演示样例:

    create table tb_products

    (

    product_id number not null,

    product_name number not null,

    product_type varchar2(50),

    supplier_id number,

    CONSTRAINT tb_products_u1 UNIQUE (product_id, product_name) --定义复合唯一性约束

    );

    5 使用ALTER TABLE语法创建唯一性约束

    1)语法

    ALTER TABLE table_name

    ADD CONSTRAINT constraint_name

    UNIQUE (column1, column2, ... , column_n);

    2)演示样例准备,先创建表

    drop table tb_supplier;

    drop table tb_products;

    create table tb_supplier

    (

    supplier_id number not null

    ,supplier_name varchar2(50)

    ,contact_name varchar2(50)

    );

    create table tb_products

    (

    product_id number not null,

    product_name number not null,

    product_type varchar2(50),

    supplier_id number

    );

    3)基于单列的唯一性约束

    alter table tb_supplier

    add constraint tb_supplier_u1

    unique (supplier_id);

    4)基于多列的唯一性约束

    alter table tb_products

    add constraint tb_products_u1

    unique (product_id,product_name);

    6 禁用唯一性约束

    1)语法:

    ALTER TABLE table_name

    DISABLE CONSTRAINT constraint_name;

    2)演示样例:

    ALTER TABLE tb_supplier

    DISABLE CONSTRAINT tb_supplier_u1;

    7 使用唯一性约束

    1)语法:

    ALTER TABLE table_name

    ENABLE CONSTRAINT constraint_name;

    2)演示样例:

    ALTER TABLE tb_supplier

    ENABLE CONSTRAINT tb_supplier_u1;

    8  删除唯一性约束

    1)语法:

    ALTER TABLE table_name

    DROP CONSTRAINT constraint_name;

    2)演示样例:

    ALTER TABLE tb_supplier DROP CONSTRAINT tb_supplier_u1;

    ALTER TABLE tb_products DROP CONSTRAINT tb_products_u1;

    ---------------------------------------------------------------------------------------------------------

    假设您们在尝试的过程中遇到什么问题或者我的代码有错误的地方,请给予指正,很感谢!

    联系方式:david.louis.tian@outlook.com

    版权@:转载请标明出处!

    ----------------------------------------------------------------------------------------------------------

    展开全文
  • 猿们好,我是honery,今天来给大家唠一唠如何避免数据库报唯一性约束的错误。一、问题的引出首先抛出一个问题,如何保证数据库表中的某列的值都不一样呢?相信大家很容易想到给该列加上唯一性约束,这样就能保证业务...

    猿们好,我是honery,今天来给大家唠一唠如何避免数据库报唯一性约束的错误。

    一、问题的引出

    首先抛出一个问题,如何保证数据库表中的某列的值都不一样呢?相信大家很容易想到给该列加上唯一性约束,这样就能保证业务逻辑的正确性了。实际的使用中,尤其高并发场景下,很容易出现插入同一条记录的情况,该情况下数据库会报违反唯一性约束的错误。总不能让数据库一直抛这个错误吧。于是我们想到可以在业务代码中加上该列值是否为空的判断,判断为空时再行插入,于是问题就解决了。

    问题真的解决了吗?说是,你就too young too simple了。有没考虑过高并发场景呢?如果多个线程同时在某次插入前去判空,显然判断的结果都是空,那么第一次插入成功后,后续的插入动作都会报违反数据库唯一性约束的错误。总不能让日志一直报错吧,该如何解决呢?

    二、问题的解决方案

    这个问题其实是个典型的问题,可以有很多种解决方案,小编这里就简单提供三种解决策略。方案很简单,猿们跟上思路~~

    2.1 通过锁机制,将查询和插入原子化

    相信很多小伙伴很容易就能想到这个方案,通过锁机制(如内置锁,synchronized)将记录是否存在的查询动作和插入新记录的动作放在一个同步锁中,实现的关键代码如下:

    @Transactional

    public synchronized void insertWhenIdIsEmpty(Qingmj qingmj) {

    log.info("进入时间:"+System.currentTimeMillis());

    log.info(qingmj.toString());

    Qingmj qingmj_old = qingmjMapper.getQingmjById(qingmj.getId());

    try {

    //等待10s,制造并发场景

    Thread.sleep(15000);

    } catch (InterruptedException e) {

    log.warn("睡眠等待过程异常",e);

    }

    if(qingmj_old==null) {

    log.info("数据准备插入中... ...");

    try {

    qingmjMapper.insert(qingmj);

    log.info("数据插入成功!");

    }catch(Exception e) {

    log.info("数据插入失败",e);

    }

    }else {

    log.info("约束键已存在,不再插入");

    }

    log.info("结束时间:"+System.currentTimeMillis());

    }

    [执行结果]:

    ef07d5a95982f5bb7e309a1e4e30ef27.png

    [结果分析]:

    从执行结果可知,通过锁机制将查询和插入原子化后,彻底的避免了插入重复数据的问题。但是带来了一个新问题,同步锁将两个业务动作锁在一起,强制执行过程串行化,会导致系统运行的性能较差,该如何优化呢?

    2.2 通过双重检查锁机制,优化串行化带来的性能问题

    所谓的双重检查锁机制,从名字不难看出其逻辑。它主要有两个技术点:一、将方法锁细化成代码块锁,尽量减少锁住的执行逻辑;二、执行两次判空逻辑,即在同步代码块中再加入一次判空检查。具体的代码实现如下:

    //@Transactional

    public void insertWhenIdIsEmpty(Qingmj qingmj) {

    log.info("进入时间:"+System.currentTimeMillis());

    log.info(qingmj.toString());

    Qingmj qingmj_old = qingmjMapper.getQingmjById(qingmj.getId());

    try {

    //等待10s,制造并发场景

    Thread.sleep(15000);

    } catch (InterruptedException e) {

    log.warn("睡眠等待过程异常",e);

    }

    if(qingmj_old==null) {

    synchronized (this) {

    Qingmj qingmj_old_2 = qingmjMapper.getQingmjById(qingmj.getId());

    if(qingmj_old_2==null) {

    log.info("数据准备插入中... ...");

    try {

    qingmjMapper.insert(qingmj);

    log.info("数据插入成功!");

    }catch(Exception e) {

    log.info("数据插入失败",e);

    }

    }else {

    log.info("约束键发现变为存在状态,不再插入");

    }

    }

    }else {

    log.info("约束键已存在,不再插入");

    }

    log.info("结束时间:"+System.currentTimeMillis());

    }

    [执行结果]:

    4d5c8b46465559396e9a5ab227b43354.png

    [结果分析]:

    引入双重检查锁机制,有效优化了同步方法锁性能较差的问题,是一种较为推荐的方法。这也是单例模式中懒汉模式的一种经典实现。代码中的事务注解不能在此处方法上加上,否则会适得其反,这也是锁与事务作用范围的一个角逐。好了,回到正题,解决违反数据库唯一性约束问题,能不能不加锁呢?答案是肯定的。

    2.3 通过巧用Redis的setnx特性,避免重复数据的插入

    我们要解决的问题是业务流程正常,但数据库会持续的报违反唯一性约束的问题。如何保留数据库的唯一性约束,维持业务流程正常,但同时不让数据库报上述异常呢?顺着这个思路我们可以想到能否在数据进入数据库之前就识别出重复数据的冲突呢?这样便可以解决上述问题了。有很多第三方的中间件可以帮我们做到这点,其中Redis就是一个例子。

    大家都用过Redis,知道Redis的setnx方法有个特点,当第一次插入某个key及其value值时会返回“1”;当后续继续插入该key的其他value值时会返回“0”,并插入失败。于是乎,我们在插入数据库之前,先将数据存入Redis当中,若Redis反馈为第一次插入则落地数据库中;若Redis反馈非第一次插入则不落地数据库。如此便巧妙解决了数据库报唯一性约束的问题了,而且!没有用到锁!具体实现如下:

    @Transactional

    public void insertWhenIdIsEmpty(Qingmj qingmj) {

    log.info("进入时间:"+System.currentTimeMillis());

    log.info(Thread.currentThread().getName() + " parameters:" + qingmj.toString());

    Qingmj qingmj_old = qingmjMapper.getQingmjById(qingmj.getId());

    try {

    //等待10s,制造并发场景

    Thread.sleep(15000);

    } catch (InterruptedException e) {

    log.warn("睡眠等待过程异常",e);

    }

    if(qingmj_old==null){

    if(redisUtil_test.setnx("constraint_id_"+qingmj.getId(), qingmj.getId()) == 1){//如果数据存在则返回0,不存在返回1

    log.info("数据准备插入中... ...");

    try {

    qingmjMapper.insert(qingmj);

    log.info("数据插入成功!");

    redisUtil_test.expire("constraint_id_"+qingmj.getId(), 1000);//设失效时间3秒

    }catch(Exception e) {

    redisUtil_test.del("constraint_id_"+qingmj.getId());//插入出异常则删除

    log.info("数据插入失败",e);

    }

    }else{

    log.info("并发情形,约束键已存在,不再插入");

    }

    }else{

    log.info("约束键已存在,不再插入");

    }

    log.info("结束时间:"+System.currentTimeMillis());

    }

    [执行结果]:

    ba755226bcda755b84b2a37592ebae20.png

    [结果分析]:

    通过巧用Redis的setnx特性有效解决了数据库持续报违反唯一性约束的错误。同时没有使用同步锁,大大提升了系统的性能。这种方法甚至在表字段未加唯一性约束的情况下,也能保证业务逻辑的正确性,非常巧妙且灵活。当然系统也必须要支持Redis才能采用这种方案啦。

    三、总结

    数据库违反唯一性约束问题,只是一个典型的小问题,解决方案特别多,大家都可以去借鉴。但是小编文中陈述的三种方案汇聚了解决这类问题的两个思路。其一是加锁,锁性能优化;其二是不加锁,在落地数据库之前提前引发数据冲突。方案虽说简单,但是值得回味的。

    展开全文
  • 本文主要给大家介绍了关于MySQL中唯一性约束与NULL的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。希望能帮助到大家。前言之前做的一个需求,简化描述下就是接受...

    本文主要给大家介绍了关于MySQL中唯一性约束与NULL的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。希望能帮助到大家。

    前言

    之前做的一个需求,简化描述下就是接受其他组的 MQ 的消息,然后在数据库里插入一条记录。为了防止他们重复发消息,插入多条重复记录,所以在表中的几个列上加了个唯一性索引。CREATE UNIQUE INDEX IDX_UN_LOAN_PLAN_APP ON testTable (A, B, C);

    这时 A,B,C 三列都是不允许 NULL 值的,唯一性约束也是 work 的。

    后来由于需求的变化,修改了以前的唯一性约束,又多加了一列。(至于为什么加就不赘述了)。ALTER TABLE testTable

    DROP INDEX IDX_UN_LOAN_PLAN_APP,

    ADD UNIQUE KEY `IDX_UN_LOAN_PLAN_APP` (A, B, C, D);

    新加的 D 是类型是 datetime, 允许为 NULL,默认值为 NULL。之所以默认值为 NULL,是考虑到不是所有记录都有这个时间的, 如果强行设置一个 Magic Value (比如'1970-01-01 08:00:00‘)当做默认值,看起来很奇怪。

    蓝后。。。就出问题了。加了 D 之后,唯一性约束基本就失效了。Insert into testTable (A,B,C,D) VALUES (1,2,3,NULL); --- OK

    Insert into testTable (A,B,C,D) VALUES (1,2,3,NULL); --- OK

    Insert into testTable (A,B,C,D) VALUES (1,2,3,NULL); --- OK

    上面的三条 SQL 都是可以执行成功的,数据库中会有多条一样的记录。可按照我们以前的构想,在执行后两条 SQL 时 应该抛出 ‘Duplicate key' 的异常的。

    后来查了一下,才发现其实 MySQL 官方文档上已经明确说了这一点, 唯一性索引是允许多个 NULL 值的存在的:A UNIQUE index creates a constraint such that all values in the index must be distinct. An error occurs if you try to add a new row with a key value that matches an existing row. For all engines, a UNIQUE index allows multiple NULL values for columns that can contain NULL.

    从下表中也可以看出来不管是采用什么类型的存储引擎,在建立 unique key 的时候都是允许多个 NULL 存在的。。。。

    a06021474de76ce1bfdc569a7d1c91d2.png

    细想想,其实也蛮合理,毕竟在 MySQL 中认为 NULL 代表着“未知”。 在 SQL 中,任何值与 NULL 的比较返回值都是 NULL 而不是 TRUE, 就算 NULL 与 NULL 的比较也是返回 NULL。

    所以只能 fix 了。。。解决办法也蛮简单粗暴的,直接把线上数据刷了一遍,将“1970-01-01 08:00:00”作为默认值,然后把那列改为不允许为 NULL 的了,咳咳。

    MySQL 官网上也有蛮多人讨论过这个问题,一部分人认为这是 MySQL 的 bug, 另一部分则认为是一个 feature,附上链接。

    MySQL Bugs: #8173: unique index allows duplicates with null values

    相关推荐:

    PHP中的类型约束

    MySQL中的约束与多表查询以及子查询的实例详解

    php中类型约束的思路代码分享

    展开全文
  • 唯一性约束可以确保唯一性,MySQL主键约束和唯一性约束都是索引,它们的区别是:mysql-workbench无法创建多字段唯一性约束,可以在命令行手工增加增加多字段唯一性性约束mysql>alter table cmd_end_regexp add ...

    MySQL主键约束和唯一性约束都是索引,它们的区别是:主键字段可以确保唯一性,但主键字段不能为NULL.唯一性约束可以确保唯一性,

    MySQL主键约束和唯一性约束都是索引,它们的区别是:

    mysql-workbench无法创建多字段唯一性约束,可以在命令行手工增加

    增加多字段唯一性性约束

    mysql>alter table cmd_end_regexp add constraint dev_series_uniq UNIQUE(dev_category_id,dev_series_id,dev_type_id);

    删除唯一性约束

    mysql>alter table cmd_end_regexp drop index dev_series_uniq;

    下面的内容可能也对你有帮助:

    CentOS 6.6下安装MySQL 5.6.24

    Linux下MySQL 5.6.23安装

    以下是小编为您精心挑选的MySQL相关内容,,看看是否有所帮助:

    CentOS 7下源码安装MySQL 5.6

    MySQL5.7.3.0安装配置图解教程

    Ubuntu 14.04下安装MySQL

    《MySQL权威指南(原书第2版)》清晰中文扫描版 PDF

    Ubuntu 14.04 LTS 安装 LNMP Nginx\PHP5 (PHP-FPM)\MySQL

    Ubuntu 14.04下搭建MySQL主从服务器

    Ubuntu 12.04 LTS 构建高可用分布式 MySQL 集群

    Ubuntu 12.04下源代码安装MySQL5.6以及Python-MySQLdb

    MySQL-5.5.38通用二进制安装

    本文永久更新链接地址:

    f68f2add0b68e4f9810432fce46917b7.png

    本文原创发布php中文网,转载请注明出处,感谢您的尊重!

    展开全文
  • 约束 全称完整性约束,它是关系数据库中的对象,用来存放插入到一个表中一列数据的规则,用来确保数据的准确性和一致性。索引 数据库中用的最频繁的操作是数据查询,索引就是为了加速表中数据行的检索而创建的一种...
  • 在使用Python从小熊同学的API中提取基金净值后,导入到SQLite数据库时,考虑到避免重复导入同一...经过查看菜鸟教程,多字段的唯一性约束需要在建表的时候就在代码中指定。因此代码如下: CREATE TABLE 产品库 ( ID
  • 通常业务系统的一些记录表都会有一些唯一性约束,例如相同用户下不允许重名;通常可以对指定列创建唯一性索引即可,例如: CREATE TABLE `novel` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `novel_id` bigint...
  • 问题:I want to have a unique constraint on a column ... 我想在要用GUID填充的列上具有唯一约束。 However, my data contains null values for this columns. 但是,我的数据包含此列的空值。 How do I create...
  • 展开全部建表时加上唯一性62616964757a686964616fe59b9ee7ad9431333366306465约束:CREATE TABLE `t_user` (`Id` int(11) NOT NULL AUTO_INCREMENT, -- 自增`username` varchar(18) NOT NULL unique, -- 唯一性约束`...
  • JPA教程 - JPA表唯一约束示例我们可以用@Table注释添加表约束。下表为名称列上的Person表添加了唯一约束。@Entity@Table(uniqueConstraints=@UniqueConstraint(columnNames="NAME"))public class Person {例子下面的...
  • 唯一性约束 可以为null但不能重复 添加unique 这样叫列级约束 如下代码所示,在定义时添加unique,此时添加了的字段均不能接受相同数据的赋值 mysql> create table t_user(id int,username varchar(255) unique,...
  • 1,可以使用laravel自带的验证器来进行数据库某一字段唯一性的验证(这个时候实际上是去数据库查,查到了就代表有,查不到就无)2,一般情况下,如果这个业务是比较关键的业务,并且有可能面对高并发的情况,那么 在...
  • 1、主键的创建方法一:直接在sql语句中声明字段主键约束create table table_name (id type[length] constraint pk_name primary key,name tyoe[length],age type[length],class_id);方法二:alter更改表添加约束alte...
  • 设置唯一性参考文章:Oracle之唯一性约束(UNIQUE Constraint)用法详解唯一性约束英文是Unique Constraint,它是指表中一个字段或者多个字段联合起来能够唯一标识一条记录的约束。联合字段中,可以包含空值。那唯一...
  • 展开全部常用五类约束:not null:非空约束,指定某列不为空unique: 唯一约束,指定某列和几列组合的数据不能重32313133353236313431303231363533e4b893e5b19e31333337613162复primary key:主键约束,指定某列的...
  • 使用Oracle的约束来实现。这里使用一个技巧。使用具有函数索引和唯一索引联合实现该需求。 如: create table tt1(a varchar2(10),b number); create Unique index ind_ab on tt1(decode(b,100,null,a),decode(b,...
  • 约束字面意思就是限制,比如我们每一个人的身份证号都是唯一的,不可能出现两个人,身份证是一样的,那么这里的唯一性我们就称之为一种约束,再比如:我们每个人都是有性别的,或男或女或其他,不可能出现一个人他...
  • mysql使用总结

    2021-03-04 01:34:11
    1,mysql唯一性约束:用alter命令,代码如下:(表名为user,字段为name)alter table user add unique key(`name`);2,mySQL中删除一个表中的某字段的unique key的语法:ALTER TABLE `table123212` DROP INDEX `name...
  • 一、现象及原因今天在PostgreSQL又遇到一个现象,应用代码报错:“ERROR: duplicate key value violates unique constraint ...”。最后查明,这是由于PostgreSQL把空串('')、空值(NULL)当作不同的值,从而影响了...
  • 一、完整性约束 1.MySQL支持的完整性约束 约束条件 描述 primary key 主键约束 unique 唯一约束 not null 非空约束 default 默认约束 auto_increment 自动增长约束 foreign key 外键约束 2.列级...
  • 我想在要用GUID填充的列上具有唯一约束。 但是,我的数据包含此列的空值。 如何创建允许多个空值的约束?这是一个示例方案 。 考虑以下模式:CREATE TABLE People (Id INT CONSTRAINT PK_MyTable PRIMARY KEY ...
  • 用mybatis执行select方法报java.sql.SQLIntegrityConstraintViolationException: ORA-00001: 违反唯一约束条件 (HR.SYS_C004152)异常信息如下:[code]### The error may exist in com/baizhi/dao/UserDao.java (best...
  • CREATE TABLE Persons ( P_Id int PRIMARY KEY AUTO_INCREMENT, LastName varchar(255), FirstName varchar(255), Address varchar(255), City varchar(255) )
  • 如何创建允许空的唯一约束?我希望在一个列上有一个唯一约束,我将用GUID填充该列。但是,我的数据包含此列的空值。如何创建允许多个空值的约束?这是一个示例场景..考虑一下这个模式:CREATETABLEPeople...
  • mysql唯一值创建代码

    2021-01-19 06:33:08
    介绍几种唯一值的获取或者生产方法:先建一个测试用的表tbl_user,有三个字段:Id、Name、Age,其中Id为主键。复制代码 代码示例:1: drop table if exists `tbl_user`;2: create table3: `tbl_user` (4: `Id` int(10)...
  • 唯一性约束4. PRIMARY KEY 约束5. 自增列:AUTO_INCREMENT6. FOREIGN KEY 约束7. CHECK 约束8. DEFAULT约束9. 面试 1. 约束(constraint)概述 1.1 为什么需要约束 数据完整性(Data Integrity)是指数据的精确性...
  • 我们想添加一个作用于数据库表的约束,在odoo中使用如下代码: _sql_constraints = [('code_unique', 'unique(name)', '猫猫不可重名!!!')] 但我们在制作的后期,发现名字不贴切,想更改.就需要在pg数据库里更改了: ...
  • mysql数据的完整性约束(完整)

    千次阅读 2020-12-21 23:14:16
    数据完整性约束是对关系性模型完整性规则做某种约束条件。主要是保证数据库内应用数据的正确性和一致性,防止数据库中存在不符合语义的,不正确的数据。关系模型中的三类约束:一,实体完整性二,参照完整性三,用户...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 104,351
精华内容 41,740
关键字:

唯一性约束代码