精华内容
下载资源
问答
  • 前言不知道大家没有遇到这么一种业务场景,在业务中有个唯一约束A,当该业务进行逻辑删除后(设置标记为删除状态),再往唯一约束列插入相同的值时,此时会报Duplicate entry,但在业务上,该值时必须要插入的。...

    前言

    不知道大家有没有遇到这么一种业务场景,在业务中有个唯一约束A,当该业务进行逻辑删除后(设置标记为删除状态),再往唯一约束列插入相同的值时,此时会报Duplicate entry,但在业务上,该值时必须要插入的。今天我们就来聊聊处理这种业务场景的几种思路

    解决思路

    方案一:不采用逻辑删除,直接物理删除

    方案二:新建历史表

    主表进行物理删除,同时将删除的记录保存到历史表中

    方案三:取消表的唯一约束,同时引入redis来保证唯一约束

    取消表的唯一约束,在项目中引入redis,通过redis来判重,新增时往redis set记录,删除时,删除redis记录

    方案四:变更删除标记为时间戳

    将删除状态不以0,1表示,而是以时间戳为值,然后将删除状态为与之前的唯一约束A重新组成唯一联合约束index(A、del_flag),删除时变更del_flag的时间戳

    方案五:保留删除标记,同时新建一个字段del_unique_key

    保留删除状态位,再新增一个字段del_unique_key,该字段默认值为0,字段类型和大小与主键id保持一致,同时与原先的唯一约束重新组成联合唯一约束index(A,del_unique_key),业务进行逻辑删除,变更del_unique_key的值为该删除行的主键id

    方案的取舍

    方案一得从业务的角度上考虑了,如果物理删除,对业务无损,那就无所谓了。方案二等于需要删除的记录的表都需要有历史表,如果仅仅是用来实现记录删除记录,感觉有点大材小用。方案三引入redis,虽然也可以解决问题,但是又额外增加复杂度,同时还得保证redis和数据库的一致性。方案四和方案五其实实现的思路是一样,不过如果已经是在线上跑的业务,还是推荐用第五种方案,毕竟新增字段正常对已有的业务影响相对较小,如果是第四种方案,直接将标志位修改为时间戳,可能还会涉及改业务。如果是新增业务,第四种和第五种方案比较推荐

    展开全文
  • 突然看到数据库表设计中的几个属性,记录一下 restrict--限制,指的是如果字表引用父表的某个字段的值,那么不允许直接删除父表的该值; cascade--级联,删除父表的某条记录,子表中引用该值的记录会自动被删除; ...

    突然看到数据库表设计中的几个属性,记录一下

    restrict--限制,指的是如果字表引用父表的某个字段的值,那么不允许直接删除父表的该值;
    cascade--级联,删除父表的某条记录,子表中引用该值的记录会自动被删除;
    no action--无参照完整性关系,有了也不生效。

     

    在就是想到字段唯一性约束的添加

     

     

    Mysql设置某字段唯一
     
    1.建表时加上唯一性约束
     
    CREATE TABLE `t_user` (
    `Id` int(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(18) NOT NULL unique,
    `password` varchar(18) NOT NULL,
    PRIMARY KEY (`Id`)  www.2cto.com  
    ) ENGINE=InnoDB AUTO_INCREMENT=1018 DEFAULT CHARSET=gbk;
     
    2.给已经建好的表加上唯一性约束
    ALTER TABLE `t_user` ADD unique(`username`);
     
    mysql主键索引和唯一索引
     
    1.主键一定是唯一性索引,唯一性索引并不一定就是主键;
    2.一个表中可以有多个唯一性索引,但只能有一个主键;
    3.主键列不允许空值,而唯一性索引列允许空值。
     

    在PowerDesigner中设置字段唯一约束 --相当于unique

    1.双击Table,弹出Table Properties窗口
    2.添加一个新的索引
    3.选择unique,把索引设置为唯一索引
    4.双击索引所在的行,弹出索引属性窗口(Index Properties)
    5.双击添加列按钮,弹出Selection窗口
    6.选择索引包含的表的列,并单击OK
     
    展开全文
  • 直到天前同事给我脚本来约束某个字段的唯一性,用的是唯一键约束,这问题又萦绕脑中了。看似区别,又没发现什么大的区别!实际上也没多大区别,还是测试看看吧。 USE [DemoDB] GO CREATE TABLE [dbo]....

    以前也想了解到底有什么区别,但是搁着又忘记了,因为我们很少用唯一键约束。直到几天前同事给我个脚本来约束某个字段的唯一性,用的是唯一键约束,这问题又萦绕脑中了。看似有区别,又没发现什么大的区别!实际上也没多大区别,还是测试看看吧。


    USE [DemoDB]
    GO
    
    CREATE TABLE [dbo].[TableUniqueKey](
    	id int not null,
    	name varchar(20) null
    )
    GO
    CREATE TABLE [dbo].[TableUniqueIndex](
    	id int not null,
    	name varchar(20) null
    )
    GO
    
    INSERT INTO [dbo].[TableUniqueKey]
    SELECT 1,'KK' UNION ALL
    SELECT 2,NULL UNION ALL
    SELECT 3,NULL 
    GO
    INSERT INTO [dbo].[TableUniqueIndex]
    SELECT 1,'KK' UNION ALL
    SELECT 2,NULL UNION ALL
    SELECT 3,NULL 
    GO
    

    以两个表分表创建唯一键和唯一索引,字段 name 中都有重复值 null。



    现在创建唯一键约束 和 创建唯一索引 ,错误!

    /*创建唯一键约束 和 创建唯一索引*/
    
    --	创建唯一键约束
    ALTER TABLE [dbo].[TableUniqueKey] ADD CONSTRAINT [IX_TableUniqueKey_name] UNIQUE ([name] ASC)--默认非聚集索引
    GO
    ALTER TABLE [dbo].[TableUniqueKey] ADD CONSTRAINT [IX_TableUniqueKey_name] UNIQUE NONCLUSTERED([name] ASC)
    GO
    
    --	创建唯一索引
    CREATE UNIQUE NONCLUSTERED INDEX [IX_UniqueIndex_name] ON [dbo].[TableUniqueIndex]([name] ASC)
    GO
    

    Msg 1505, Level 16, State 1, Line 1
    The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.TableUniqueKey' and the index name 'IX_TableUniqueKey_name'. The duplicate key value is (<NULL>).
    Msg 1750, Level 16, State 0, Line 1
    Could not create constraint. See previous errors.

    The statement has been terminated.


    Msg 1505, Level 16, State 1, Line 1
    The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.TableUniqueIndex' and the index name 'IX_UniqueIndex_name'. The duplicate key value is (<NULL>).

    The statement has been terminated.


    可以看到,都提示有重复值,重复值 为 NULL 值。现在删除重复值。

    DELETE FROM [dbo].[TableUniqueKey] WHERE ID = 3
    DELETE FROM [dbo].[TableUniqueIndex] WHERE ID = 3
    

    创建唯一键约束:

    --	创建唯一键约束
    ALTER TABLE [dbo].[TableUniqueKey] ADD CONSTRAINT [IX_TableUniqueKey_name] UNIQUE NONCLUSTERED([name] ASC)
    GO

    查看相关信息:

    SELECT * FROM sys.check_constraints WHERE parent_object_id = OBJECT_ID('TableUniqueKey')
    SELECT * FROM sys.key_constraints WHERE parent_object_id = OBJECT_ID('TableUniqueKey')
    SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID('TableUniqueKey')


    创建唯一键约束,同时创建同名的唯一非聚集索引, 同时创建同名统计信息; 唯一键约束靠唯一索引来约束。


    若对唯一键生成的索引直接删除,错误!

    --对索引删除,错误!
    DROP INDEX [IX_TableUniqueKey_name] ON [dbo].[TableUniqueKey] 
    GO

    Msg 3723, Level 16, State 5, Line 1
    An explicit DROP INDEX is not allowed on index 'dbo.TableUniqueKey.IX_TableUniqueKey_name'. It is being used for UNIQUE KEY constraint enforcement.

    正确删除方法,删除表约束。

    --	删除约束,正确!
    ALTER TABLE [dbo].[TableUniqueKey] DROP CONSTRAINT [IX_TableUniqueKey_name]
    GO


    现在对另一张表创建唯一索引。

    --	创建唯一索引
    CREATE UNIQUE NONCLUSTERED INDEX [IX_UniqueIndex_name] ON [dbo].[TableUniqueIndex]([name] ASC)
    GO


    创建唯一索引, 同时创建同名统计信息

    --对索引删除!
    DROP INDEX [IX_UniqueIndex_name] ON [dbo].[TableUniqueIndex] 
    GO




    现在重新创建:

    ALTER TABLE [dbo].[TableUniqueKey] ADD CONSTRAINT [IX_TableUniqueKey_name] UNIQUE NONCLUSTERED([name] ASC)
    GO
    CREATE UNIQUE NONCLUSTERED INDEX [IX_UniqueIndex_name] ON [dbo].[TableUniqueIndex]([name] ASC)
    GO

    对比相关信息:

    SELECT * FROM sys.check_constraints WHERE parent_object_id = OBJECT_ID('TableUniqueKey')
    SELECT * FROM sys.check_constraints WHERE parent_object_id = OBJECT_ID('TableUniqueIndex')
    
    SELECT * FROM sys.key_constraints WHERE parent_object_id = OBJECT_ID('TableUniqueKey')
    SELECT * FROM sys.key_constraints WHERE parent_object_id = OBJECT_ID('TableUniqueIndex')
    
    SELECT object_name(object_id),name,index_id,type_desc,is_unique,is_unique_constraint
    FROM sys.indexes WHERE object_name(object_id) IN ('TableUniqueKey','TableUniqueIndex')
    



    唯一键约束 [TableUniqueKey] 不是 check 约束,是属于一种为 UNIQUE_CONSTRAINT 的约束。而他们的索引都有唯一性约束。


    此外,还可以通过以下检查他们的区别:

    EXEC sp_helpconstraint 'TableUniqueKey' 
    EXEC sp_helpconstraint 'TableUniqueIndex' 
    
    EXEC sp_helpindex 'TableUniqueKey' 
    EXEC sp_helpindex 'TableUniqueIndex' 
    
    
    --	EXEC sp_help 'TableUniqueKey' 
    --	EXEC sp_help 'TableUniqueIndex' 


    对比索引描述中,唯一键 比 唯一 索引多了 unique key

    --唯一键不出错
    EXEC sp_help [IX_TableUniqueKey_name]
    EXEC sp_helpindex [IX_TableUniqueKey_name]
    EXEC sp_helpconstraint [IX_TableUniqueKey_name]
    
    --唯一索引出错
    EXEC sp_help [IX_UniqueIndex_name]
    EXEC sp_helpindex [IX_UniqueIndex_name]
    EXEC sp_helpconstraint [IX_UniqueIndex_name]
    

    上面可以看出,唯一不同的是: 唯一键 比 唯一索引 多了一种叫做 "unique key" 的约束


    现在禁用索引:

    --禁用索引/约束(均可被禁用)
    ALTER INDEX [IX_TableUniqueKey_name] ON [dbo].[TableUniqueKey] DISABLE
    ALTER INDEX [IX_UniqueIndex_name] ON [dbo].[TableUniqueIndex] DISABLE
    

    插入重复数据:

    --插入重复值,正常
    INSERT INTO [dbo].[TableUniqueKey] SELECT 3,NULL 
    INSERT INTO [dbo].[TableUniqueIndex]SELECT 3,NULL

    数据都能正常插入,约束或索引被禁用了。对于唯一键约束,也是禁用索引吗?

    函数 ObjectProperty()的参数 CnstIsDisabled 可以确认约束是否被禁用。

    SELECT ObjectProperty(object_id('IX_TableUniqueKey_name'),'CnstIsDisabled')

    结果为 0 ,即约束没有被禁用,也就是说禁用的是索引,唯一键约束中,唯一性是依赖于其默认创建的唯一索引来约束的!


    现在重建索引:

    --删除重复
    DELETE FROM [dbo].[TableUniqueKey] WHERE ID = 3
    DELETE FROM [dbo].[TableUniqueIndex] WHERE ID = 3
    
    /*对索引的更改*/
    --重建索引
    ALTER INDEX [IX_TableUniqueKey_name] ON [dbo].[TableUniqueKey] REBUILD
    ALTER INDEX [IX_UniqueIndex_name] ON [dbo].[TableUniqueIndex] REBUILD
    
    
    --更改部分索引参数
    ALTER INDEX [IX_TableUniqueKey_name] ON [dbo].[TableUniqueKey] SET ( ALLOW_ROW_LOCKS = ON )
    GO
    ALTER INDEX [IX_UniqueIndex_name] ON [dbo].[TableUniqueIndex] SET ( ALLOW_ROW_LOCKS = ON )
    GO
    

    两种索引其实还是可以更改一下参数的。使用窗口打开查看,唯一键约束的索引有些是不能更改的。





    唯一键约束的索引不能像正常的索引使用太多的索引参数,因为唯一键约束与其索引同在。而单独创建的唯一索引可以设置更多的参数,如 PAD_INDEX, FILLFACTOR, IGNORE_DUP_KEY, DROP_EXISTING, STATISTICS_NORECOMPUTE, and SORT_IN_TEMPDB 。



    总的来说,其实唯一键键约束唯一索引功能是一样的: "唯一性" + "索引"

    唯一键键约束 只是作为一种独特的约束(如主键约束,唯一键约束,check约束,外键约束 的一种),以约束的形式管理.但是同时又自动创建了唯一非聚集索引,也就有了索引的性能和部分功能.实际上唯一键约束是用唯一索引来约束的。


    唯一索引 就是一种索引,它对某字段进行唯一性检查,同时可以设置各种参数,非常灵活。


    那么我们在创建列的唯一性时,到底使用哪一种较好呢?(个人理解)

    唯一键约束在表中是必定存在的约束的,唯一键约束的索引存在于一个分区中,并且不会像索引那样可以更改。因为索引可以随时改动(当然也不会经常改动),索引个人建议还是用唯一索引更灵活。管理约束还得管理索引,而管理索引,一个就好了。但是对于一些高可用性,也要注意索引是否在其他地方也存在。


    更多参考:Unique Constraints and Unique Indexes


    展开全文
  • 首先我们来想象一下,前篇文章在我们操作数据库的过程中,自由度是很高的,想给哪个赋值就给哪个赋值,但是这样子,就会造成我们所创建的数据库数据不完整,例如我创建一学生信息表,你可能添加时候忘了添加学号...

    首先我们来想象一下,前几篇文章在我们操作数据库的过程中,自由度是很高的,想给哪个赋值就给哪个赋值,但是这样子,就会造成我们所创建的数据库数据不完整,例如我创建一个学生信息表,你可能添加时候忘了添加学号、忘了添加名字、忘了添加成绩等等,因此我们就需要利用约束来创建我们的表,对表中的数据进行限定,保证数据的正确性有效性完整性

    1. 非空约束

    非空约束顾名思义就是约束它不能为空,也就是必填项,其所使用的关键字NOT NULL,关于该非空约束有三种操作,为方便讲解,以下的语句均是对bound1表中的NAME项进行操作:

    • 创建表时添加非空约束:CREATE TABLE bound1(id INT,NAME VARCHAR(8) NOT NULL);
    • 创建常规表后再添加非空约束:ALTER TABLE bound1 MODIFY NAME VARCHAR(8) NOT NULL;
    • 删除非空约束:ALTER TABLE bound1 MODIFY NAME VARCHAR(8);

    下面来操作一下,这里先新建一个表,添加一个数据看看

    CREATE TABLE bound1(id INT,NAME VARCHAR(8) NOT NULL);
    INSERT INTO bound1(id,NAME) VALUES(1,"amy");
    SELECT * FROM bound1;
    

    在这里插入图片描述
    ok,这项数据是可以成功添加的,那么下面我们来添加一下只有id的项看看是否能够成功

    INSERT INTO bound1(id) VALUES(2);
    

    在这里插入图片描述
    显然是不行的,我们可以把非空约束删掉再试一次

    ALTER TABLE bound1 MODIFY NAME VARCHAR(8);
    INSERT INTO bound1(id) VALUES(2);
    SELECT * FROM bound1;
    

    在这里插入图片描述
    去掉非空约束后便可以正常添加了,如果,此时你又想把非空约束加回去行不行呢?我们来试试

    ALTER TABLE bound1 MODIFY NAME VARCHAR(8) NOT NULL;
    

    在这里插入图片描述
    咦,怎么不行?语句错了吗?其实没有,出现该问题的原因是你的表中的NAME项已经有一个NULL值存在,不符合非空约束,因此需要把该项删除才能成功添加非空约束

    换言之,添加约束的前提是该表中对应的数据需要符合该约束,随后介绍的约束也是如此

    2. 唯一约束

    唯一约束,同样也是字面意思,用于约束该项的值不与已存在的值重复,更贴近生活的例子是学生的学号、自然人的身份证号、机动车号牌等,同样的,该约束也是有三种操作,以下的语句均是对bound2表中的id项进行操作:

    • 创建表时添加唯一约束:CREATE TABLE bound2(id INT UNIQUE,NAME VARCHAR(8));
    • 创建常规表后再添加唯一约束:ALTER TABLE bound2 MODIFY id INT UNIQUE;
    • 删除唯一约束:ALTER TABLE bound2 DROP INDEX id;

    看到删除唯一约束时可能有同学会参考上一节中的删除非空约束想用MODIFY进行修改,但其实删除唯一约束用MODIFY是不行的,必须使用这里所介绍的DROP

    国际惯例,还是来操作一下,这里先新建一个表,添加一个数据看看

    CREATE TABLE bound2(id INT UNIQUE,NAME VARCHAR(8));
    INSERT INTO bound2(id,NAME) VALUES(1,"amy");
    SELECT * FROM bound2;
    

    在这里插入图片描述
    下面再给他添加一个重复的id看看可不可以

    INSERT INTO bound2(id,NAME) VALUES(1,"john");
    

    在这里插入图片描述
    结果你肯定也猜到是不行的,另外约束的删除和新增的效果和步骤跟上一节一样,这里不再重复演示了

    3. 主键约束

    什么叫主键约束呢?主键约束的精粹在于“”,正所谓一山不能容二虎,既然是“”,那就必须是“唯一”的,另外,“”的位置也是不可或缺的,因此也必须是“非空”的,那么综上所述,主键约束的含义就是非空且唯一,同样的,该约束也是有三种操作,以下的语句均是对bound3表中的id项进行操作:

    • 创建表时添加主键约束:CREATE TABLE bound3(id INT PRIMARY KEY,NAME VARCHAR(8));
    • 创建常规表后再添加主键约束:ALTER TABLE bound3 MODIFY id INT PRIMARY KEY;
    • 删除主键约束:
    ALTER TABLE bound3 DROP PRIMARY KEY;-- 去除主键约束后其还是非空约束
    ALTER TABLE bound3 MODIFY id INT;-- 因此需要再次去除非空约束
    

    是不是感觉这个删除又有点特别?对,就是这么特别,它需要执行两条语句才能把主键约束的项变成普通项,若只执行第一条语句它只会把主键约束变成非空约束

    好啦,下面来操作一下吧,这里先新建一个表,添加一个数据看看

    CREATE TABLE bound3(id INT PRIMARY KEY,NAME VARCHAR(8));
    INSERT INTO bound3(id,NAME) VALUES(1,"amy");
    SELECT * FROM bound3;
    

    在这里插入图片描述
    没毛病,那下面再来添加一个重复id,一个空id的项看看是否能够成功

    INSERT INTO bound3(id,NAME) VALUES(1,"john");
    

    在这里插入图片描述

    INSERT INTO bound3(NAME) VALUES("kc");
    

    在这里插入图片描述
    显然都是不行的,一个提示为不能重复,一个提示为不能为空,下面再来体验一下这个特别的删除,这里先执行前面介绍的第一条删除语句

    ALTER TABLE bound3 DROP PRIMARY KEY;
    

    然后添加一个重复id的项看看

    INSERT INTO bound3(id,NAME) VALUES(1,"john");
    SELECT * FROM bound3;
    

    在这里插入图片描述
    显然添加成功了,下面再来看看添加一个空id

    INSERT INTO bound3(NAME) VALUES("kc");
    

    在这里插入图片描述
    这报错就来了,因此这就是我前面所说的,第一条删除语句只把主键约束变成了非空约束,若需要变成普通项,则还需要执行第二条语句

    ALTER TABLE bound3 MODIFY id INT;
    

    再添加那个空id数据试试看

    INSERT INTO bound3(NAME) VALUES("kc");
    SELECT * FROM bound3;
    

    在这里插入图片描述
    这时候就可以成功添加了,同样的,若此时想重新添加主键约束,必须要把表中重复的与的项删除才可以

    自动增长

    自动增长是针对主键约束中为数值类型的列服务的,有什么情况下需要用到自动增长呢?例如学生的学号,我们都知道学号是有规律增长的,因此我们可以使用AUTO_INCREMENT关键字实现该值的自动增长,该操作同样有三种,以下的语句均是对bound4表中的id项进行操作:

    • 创建表时添加主键约束并且添加自动增长:CREATE TABLE bound4(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(8));
    • 创建主键约束表后再添加自动增长:ALTER TABLE bound4 MODIFY id INT AUTO_INCREMENT;
    • 删除自动增长:ALTER TABLE bound4 MODIFY id INT;

    注意,删除自动增长语句取消了自动增长,其仍然是主键约束,接下来还是演示时间,这里先新建一个表,添加一个数据看看

    CREATE TABLE bound4(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(8));
    INSERT INTO bound4(id,NAME) VALUES(1,"amy");
    SELECT * FROM bound4;
    

    在这里插入图片描述
    下面来添加一个空id项看看能不能实现自动增长

    INSERT INTO bound4(NAME) VALUES("kc");
    SELECT * FROM bound4;
    

    在这里插入图片描述
    显然我们的id没有赋值,但它可以实现自动增长赋值,下面我来接连添加两条数据,一个给id赋值,一个不给id赋值,那么你感觉不给id赋值的会跟着哪个数值实现自动增长呢?

    INSERT INTO bound4(id,NAME) VALUES(5,"john");
    INSERT INTO bound4(NAME) VALUES("jam");
    

    你觉得自动增长的一项是6还是跟回之前的数字是3呢?下面来揭开谜底
    在这里插入图片描述
    显然是跟着最后的一项数值实现自动增长的

    4. 外键约束

    外键约束就没有前面几项约束理解起来那么简单了,但也不要怕,还是挺容易明白的,首先我们来看一个数据表
    在这里插入图片描述
    你会发现,这里研发部都在广州,销售部都在深圳,那么两项都写出来,显得这个数据库都有点繁杂,即有冗余的部分,有没有办法可以解决呢?有的,我们可以把它分开两个表,一个储存人员信息与部门代号,一个储存部门的详细信息,同时也要让他们之间产生关联

    为什么要产生关联呢?例如举一个简单的例子,假如我公司只有两个部门,代号分别是1和2,但是你在添加人员信息时候写错了部门代号为5,这样子就会添加了错误的数据,那么产生关联后有什么作用呢?假如你让两个表产生了关联,那么当你添加错误代号时候就会报错提醒你不能成功添加

    总的来说,外键约束就是让表与表之间产生关系,从而保证数据的正确性,同样的,其相关操作也是三种:

    • 创建表时添加外键约束:
      CREATE TABLE 表名(列名1 数据类型1, 列名2 数据类型2, ... , 列名n 数据类型n, CONSTRAINT 外键名称 FOREIGN KEY(副表列名) REFERENCES 主表名(主表列名));
    • 创建普通表后再添加外键约束:
      ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY(副表列名) REFERENCES 主表名(主表列名);
    • 删除外键约束:
      ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;

    注意

    • 要分清楚上面所提到的主表副表,副一定是受到主的限制的,副表主表之间也是如此,还是以员工表和部门表为例子,一定是先有部门才有员工归属到这个部门,因此,员工表是副表,部门表是主表,再直白一点说,以上三条语句的都是副表上进行操作的
    • 语句中的外键名称,其实就是你给这个副表与主表的关系起个名,你喜欢起什么名字都行,记住就好

    搞清楚之后,我们来新建一个,bound5是部门表(主表),bound6是员工表(副表),添加一下数据

    CREATE TABLE bound5(id INT PRIMARY KEY AUTO_INCREMENT,department VARCHAR(8),city VARCHAR(8));
    CREATE TABLE bound6(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(8),department INT,CONSTRAINT 5and6 FOREIGN KEY (department) REFERENCES bound5(id));
    INSERT INTO bound5(department,city) VALUES("研发部","广州"),("销售部","深圳");
    INSERT INTO bound6(NAME,department) VALUES("张三",1),("李四",2),("王五",1),("赵六",1),("田七",2),("何八",2);
    

    然后分别来看看两个表
    在这里插入图片描述
    在这里插入图片描述
    对了,教你一种方法看看有没有成功添加外键约束
    在这里插入图片描述
    在这里插入图片描述
    好啦,那我们前面所说的约束作用怎么体现出来呢?注意看,部门表中只有两个部门,编号是1和2,那么下面我们往员工表上添加两个部门编号为5的员工信息看看能不能成功

    INSERT INTO bound6(NAME,department) VALUES("吴九",5),("陈十",5);
    

    在这里插入图片描述
    显然是不可以的,那么如果我在部门表加上编号为5的部门之后再试试呢?

    INSERT INTO bound5(id,department,city) VALUES(5,"人事部","上海");
    

    在这里插入图片描述

    INSERT INTO bound6(NAME,department) VALUES("吴九",5),("陈十",5);
    

    在这里插入图片描述
    毫无意外地添加成功了,那这时候集团老板觉得这个部门编号太跳脱了,应该改回3,可不可以呢?

    UPDATE bound5 SET id=3 WHERE id=5; 
    

    在这里插入图片描述
    对不起,不可以,这是为啥呢?因为关联了呀,要是你改了编号,我那些写着部门编号是5的员工不就不属于任何部门了吗?那我裁掉这个部门总行了吧,试试看

    DELETE FROM bound5 WHERE id=5;
    

    在这里插入图片描述
    怎么还是不行?同样道理嘛,部门裁掉之后员工也是无家可归了呀,不过别担心,还有高级操作可以让两个表产生联动,下面来看看级联操作

    级联操作

    级联操作,说白了就是来解决刚才说到的两个痛点的,级联操作可以实现同步更新同步删除,它的语法也很简单,ON UPDATE CASCADE表示同步更新ON DELETE CASCADE表示同步删除,需要哪个就写哪个,下面来看一下:
    ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY(副表列名) REFERENCES 主表名(主表列名) ON UPDATE CASCADE ON DELETE CASCADE;

    让我们来添加级联操作再看看刚刚的更改部门编号能否成功

    ALTER TABLE bound6 ADD CONSTRAINT 5and6 FOREIGN KEY (department) REFERENCES bound5(id) ON UPDATE CASCADE ON DELETE CASCADE;
    UPDATE bound5 SET id=3 WHERE id=5;
    

    在这里插入图片描述
    在这里插入图片描述
    显然更改了部门表后员工表也自动同步更改了,那么删除操作是怎么样的呢?再来试试看

    DELETE FROM bound5 WHERE id=3;
    

    在这里插入图片描述
    在这里插入图片描述
    显然部门表中的部门被删除了,员工表中的相关员工也被自动删除了,即使级联操作可以给我们带来便利,但是在不是非常确定表表之间产生的连带关系的时候,我们还是要谨慎操作这一特性

    至此,约束的相关内容也全部介绍完啦,下篇文章中将会介绍多表关系

    展开全文
  • 1、保证唯一性2、是否允许为空3、一表可以多少4、是否允许组合保证唯一性两者都保证字段值的唯一性。建一学生表create table student(id int PRIMARY key, #主键name VARCHAR(20) NOT NULL,#非空seat int ...
  • 在mysql设计表中,有个概念叫做约束什么是约束约束英文:constraint约束实际上就是表中数据的限制条件约束种类mysql的约束大概分为以下种:非空约束(not null)唯一性约束(unique)主键约束(primary key) PK外键约束...
  • 假设你有个产品表,我们可能使用了好次:CREATE TABLE products (product_no integer PRIMARY KEY,name text,price numeric);假设你存储这些产品的订单的表。我们想保证订单表只包含实际存在的产品。因此...
  • 总结一下,数据库完整性约束几个列子 正文 一、静态完整性:Create Table CreateTable三种功能:定义关系模式、定义完整性约束和定义物理存储特性 定义完整性约束条件: 列完整性 表完整性 Col_constr列约束 ...
  • 主键约束(Primay Key Coustraint) 唯一性,非空性,实体完整性约束主键不能为空在一张表中,用来唯一标识一条记录的字段集,叫做主关键字或者主关键码,简称主键(或主码),这里说"字段集"是因为主键可能用一字段...
  • mysql约束

    2019-01-19 16:57:00
    主键约束(Primay Key Coustraint) 唯一性,非空性,实体完整性约束主键不能为空在一张表中,用来唯一标识一条记录的字段集,叫做主关键字或者主关键码,简称主键(或主码),这里说"字段集"是因为主键可能用一字段...
  • ※ 主键约束 :primary key※ 唯一性约束:unique key※ 外键约束:foreign key※ 非空约束:not null(null)※ 自增约束:auto_increment※ 默认值约束:default二、 主键约束:一表只能主键,当建表时忘记...
  • 主键常常与外键构成参照完整性约束,防止出现数据不一致。主键可以保证记录的唯一和主键域非空,数据库管理系统对于主键自动生成唯一索引,所以主键也是一特殊的索引。2、外键(foreign key)是用于建立和加强两表...
  • 1、保证唯一性2、是否允许为空3、一表可以多少4、是否允许组合保证唯一性两者都保证字段值的唯一性。建一学生表create table student( id int PRIMARY key, #主键 name VARCHAR(20) NOT NULL,#非空 seat int...
  • 1、保证唯一性2、是否允许为空3、一表可以多少4、是否允许组合保证唯一性两者都保证字段值的唯一性。建一学生表create table student( id int PRIMARY key, #主键 name VARCHAR(20) NOT NULL,#非空 seat int...
  • Mysql之数据完整性约束与表维护语句

    千次阅读 2017-03-23 23:43:30
    2.主键约束PRIMARY KEY,一TABLE中只能存在一主键约束,保证记录的唯一性,可以配合AUTO_INCREMENT使用,自动增1 3.唯一约束UNIQUE KEY,一TABLE中可以针对列设置多唯一约束,目的是使得该列的内容不重复
  • 数据库中的约束,顾名思义即是对插入数据库中的数据进行限定,这么做的目的是为了...外键约束下面分别为大家介绍这约束:一、主键约束:primary key特点:主键修饰的字段,非空且唯一,一张表中只能主键...
  • 表的约束

    2019-06-22 22:13:58
    真正约束字段的是数据类型,但是数据类型约束很单一,需要一些额外的约束,更好的保证数据的合法,从业务逻辑角度保证数据的正确。比如一人的身份证号,要求是唯一的。 null/not null, default, comment...
  • SQL 约束

    2018-12-14 23:19:24
    SQL中的约束 ...主键和UNIQUE都提供了唯一性约束,但主键拥有自定义的唯一性约束。 每表中可以拥有多UNIQUE约束的列,但主键只能。 设置约束的种方法 1. 创建表时,key varchar(20) uniq...
  • MySQL的几个概念:主键,外键,索引,唯一索引 概念: 主键(primary key) 能够唯一标识表中某一行的属性或属性组。一个表只能一个主键,但可以多个候选索引。主键常常与外键构成参照完整性约束,防止出现数据不...
  • 数据库中的约束,顾名思义即是对插入数据库中的数据进行限定,这么做的目的是为了...外键约束下面分别为大家介绍这约束:一、主键约束:primary key特点:主键修饰的字段,非空且唯一,一张表中只能主键...
  • 今天我们一起使用一下主要的几个约束,null/not null,default, comment, zerofill,primary key,auto_increment,unique。 1、空属性 两个取值,null(默认)和not null(此列属性不允...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 218
精华内容 87
关键字:

唯一性约束有几个