场景

我mysql里有3个表

1.车辆信息表carInfo

字段为:

carID,主键

2.终端信息表terminalID

字段为:

terminalID,主键

3.车辆与终端的中间表car_bind_terminal

carID,外键

terminalID,外键

任务(需求)

现在需要实现车辆与终端的一对一映射,让中间表里的carID和terminalID这两个字段都不能重复,否则添加数据时会失败。

比如,车辆与终端的中间表car_bind_terminal里边有这样一条数据,代表了车辆1号与终端1号的一对一映射。

carID    terminalID
1 1

现在我想要插入分别插入3条数据,分别是(1,2)、(2,1)和(2,2)。

carID    terminalID
1 1
1 2 插入失败,因为carID与第一条重复了
2 1 插入失败,因为terminalID与第一条重复了
2 2 插入成功,因为carID和terminalID都没有与第一条重复

理想中的最终结果应为:

carID    terminalID
1 1
2 2

行动(解决方案)

方案1:从代码层面解决(正确方案)

添加数据时,先检查数据在数据库中是否重复,若没有,则添加这条数据,否则返回添加失败。

缺点:写法太丑,需要对数据库进行两次操作。

方案2:设置成两个唯一索引(正确方案)

思路借鉴了这个网站的一对一的中间关系表的解决方案

将carID和terminalID设置为两个唯一索引,我这里用的是Navicat。

因为carID和terminalID是外键,本来就是两个一般索引,在这里我们只需要把这两个索引的类型从Normal设置成Unique就好了。

优点:以后业务变更,不再是一对一,可能变成一对多或是多对多,都能灵活更改。

缺点:多了个中间表,索引数也多了。

方案3:删掉中间表,把从表的主键作为主表的外键,并将外键设置成唯一索引(正确方案)

优点:比上个方案少了个中间表,索引也少一半(2变成1)。

缺点:若将来业务变更为多对多,就要大改。

方案4:设置成一个复合唯一索引(错误方案)

不要设置成复合唯一索引,因为它允许其中的部分字段重复。

不要像下图这样设置。

结果

成功解决,我用了方案2,因为改动工作量小。

总结

1.如果删除carInfo表里的1号车,car_bind_terminal里的(1,1)数据也会跟着删除。

2.就mysql来说(别的不清楚),设置外键时会自动添加一个一般索引(Navicat能看到),设置主键时会自动添加一个唯一索引(Navicat看不到,因为主键是特殊的唯一索引)。

3.复合主键允许其中的部分字段重复。比如复合主键(ID,Name),数据可以同时存在(1,张三)和(2,张三)。

参考

[数据库实体、关系(一对一实现方式、一对多实现方式、多对多实现方式)]:

https://blog.csdn.net/leilei7407/article/details/101037295

mysql如何让两个字段数据都不能重复?的更多相关文章

  1. sql server中如何将两个字段数据合并成一个字段显示(字段与字段添加特殊符号)

    之前,我在做统计数据时,需要一个字段显示某月的订单数量和订单金额,要求组合成一个字段,用括号组合. 统计出来的结果大概是这样的,首先我们来创建一些模拟数据 ---创建订单表--- create tab ...

  2. Mysql中让两个字段不同时相同的方法

    有时候我们会遇到这样的一种情况:有一些不同的专业,每个专业中有一些不同的学号,专业+学号能对应到个人.这时,应该如何在数据库中定义列,来保证专业+学号对应的学生的唯一性呢? 把学号定义成唯一(UNIQ ...

  3. MYSQL,触发器,实现两个表共用ID不重复

    前后台没有分开,为了区分前后台用户,所以分表,但是ID不能重复,因为关联了权限表. 这里实现后台用户表使用奇数ID 前台用户表使用偶数ID MYSQL 没有sequence SET @@auto_in ...

  4. 如何使用MySQL一个表中的字段更新另一个表中字段

    [本文出自:https://www.jb51.net/article/150323.htm] 这篇文章主要介绍了如何使用MySQL一个表中的字段更新另一个表中字段,需要的朋友可以参考下 1,修改1列 ...

  5. 如何将两个字段合成一个字段显示(oracle和sqlserver的区别)

    oracle中,如何将两个字段数据合并成一个字段显示,接下来看一下在sql server和pl/sql的区别 sql server中如何合并(用Cast()函数) --1.创建模拟的数据表--- cr ...

  6. orcl数据库查询重复数据及删除重复数据方法

    工作中,发现数据库表中有许多重复的数据,而这个时候老板需要统计表中有多少条数据时(不包含重复数据),只想说一句MMP,库中好几十万数据,肿么办,无奈只能自己在网上找语句,最终成功解救,下面是我一个实验 ...

  7. mysql的if用法解决同一张数据表里面两个字段是否相等统计数据量。

    MySQL的使用用法如下所示:格式:if(Condition,A,B)意义:当Condition为true时,返回A:当Condition为false时,返回B.作用:作为条件语句使用.mysql的i ...

  8. Mysql 如何查询两个时间段之间的数据?

    Mysql 如何查询两个时间段之间的数据?

  9. JDBC读写MySQL的大字段数据

    JDBC读写MySQL的大字段数据   不管你是新手还是老手,大字段数据的操作常常令你感到很头痛.因为大字段有些特殊,不同数据库处理的方式不一样,大字段的操作常常是以流的方式 来处理的.而非一般的字段 ...

随机推荐

  1. USBWebServer - 在U盘里搭一个Web服务器!

    文章选自我的博客:https://blog.ljyngup.com/archives/321.html/ 本文将介绍一款可以在U盘内直接搭建Web服务器的软件 软件可以免安装直接在U盘内运行,适合外出 ...

  2. tar命令详解及使用实例

    tar命令 [root@linux ~]# tar [-cxtzjvfpPN] 文件与目录 …. 参数: -c :创建压缩文件 -x :解开压缩文件 -t :查看tar包里面的文件! 上面3个参数只能 ...

  3. php 截取字符串长度 并 把超出规定长度的内容用...替代

    <?php header("content-type:text/html;charset=utf-8");#设置文件编码 error_reporting(E_ALL);#设置 ...

  4. CentOS安装-(CentOS7)最小化安装

    镜像:CentOS-7-x86_64-DVD-1908.iso 1.将安装光盘插入服务器,开机会读取系统安装程序,选择 Install CentOS 7 2.安装过程是图形界面,可以选择熟悉的语言执行 ...

  5. debian wget 报ERROR: The certificate of ‘xxx’ is not trusted.

    # wget https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz --2019-01-11 15:04:41-- https://w ...

  6. 大数相乘----C语言

    /* 大数相乘: 因为是大数,乘积肯定超出了能定义的范围,因此考虑用数组存储,定义三个数组,分别存储乘数,被乘数和积. 规则与平常手算一样,从个位开始分别与被乘数的每一位相乘,但是有一点不同的是:我们 ...

  7. 【Web性能权威指南】 PDF

    Web性能权威指南.pdf 网盘:https://545c.com/file/24657411-424998805     获取码:276922

  8. java设计模式4——原型模式

    java设计模式4--原型模式 1.写在前面 本节内容与C++语言的复制构造函数.浅拷贝.深拷贝极为相似,因此建议学习者可以先了解C++的该部分的相关知识,或者学习完本节内容后,也去了解C++的相应内 ...

  9. Android Studio无法下载sdk的问题

    参考自:解决Android Studio无法下载sdk的问题 国内网站无法登进google,android sdk无法下载. 尝试使用FQ,重装软件都没有成功. 最后找到了解决办法:http://pi ...

  10. 浅谈centos8与centos7

    距离centos8.0(现在已经更新到8.1了)的发布已经过去几个月了,作为一个刚刚接触过几个月centos的萌新来说,本文想通过实际的操作体验来说对比一下centos8代与7代 首先,centos8 ...