场景

我mysql里有3个表

1.车辆信息表carInfo

字段为:

carID,主键

2.终端信息表terminalID

字段为:

terminalID,主键

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

carID,外键

terminalID,外键

任务(需求)

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

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

  1. carID terminalID
  2. 1 1

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

  1. carID terminalID
  2. 1 1
  3. 1 2 插入失败,因为carID与第一条重复了
  4. 2 1 插入失败,因为terminalID与第一条重复了
  5. 2 2 插入成功,因为carIDterminalID都没有与第一条重复

理想中的最终结果应为:

  1. carID terminalID
  2. 1 1
  3. 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. linux 学习操作小计

    屌丝最近在接触lamp开发 把工作中遇到的 问题和 一些常用的操作记下来.以便以后去翻阅 (1)linux下备份mysql数据库方法 #mysqldump -u root -p dbname > ...

  2. 谈下slot-scope

    Vue里有个slot插槽的概念,常用的一般是命名的slot和默认的slot, 这里谈下slot-scope,Vue2.6后改成v-slot slot-scope场景是父组件用子组件的数据,但是样式自己 ...

  3. tensorflow开发环境版本组合

    记录下各模块的版本 tensorflow 1.15.0       print tf.__version__ cuda 10.0.130            nvcc -v cudnn 7.6.4  ...

  4. 手动使用I2C协议写入24C02C

    刚尝试用AT89C52单片机使用IIC总线协议读写AT24C02C,我忽然想能否用手动调整开关的方式写入AT24C02C?于是,便尝试了一下,结果果然成功了. 关于IIC总线,这篇文章写的很详细:ht ...

  5. [Contract] Solidity address payable 转换与数组地址

    address payable  -->  address address payable addr1 = msg.sender; address addr2 = addr1; // 隐式转 a ...

  6. http报文解析

    http报文结构 报文首部 起始行 请求报文的起始行: 方法(method) request-URL version(http协议版本) 响应报文的起始行 HTTP响应码 请求头 通用首部 请求首部 ...

  7. 零基础Python应该怎样学习呢?(附视频教程)

    Python应该怎样学习呢? 阶段一:适合自己的学习方式 对于零基础的初学者来说,最迷茫的是不知道怎样开始学习?那这里小编建议可以采用视频+书籍的方式进行学习.看视频学习可以让你迅速掌握编程的基础语法 ...

  8. MySQL - SQL语句优化方法

    1.使用 show status 了解各种 SQL 的执行频率 mysql> show status like 'Com%'; 该命令可以查询 sql 命令的执行次数. 2.定位执行效率较低的 ...

  9. 高性能异步SRAM技术角度

    当前有两个不同系列的异步SRAM:快速SRAM(支持高速存取)和低功耗SRAM(低功耗).从技术角度看来,这种权衡是合理的.在低功耗SRAM中,通过采用特殊栅诱导漏极泄漏(GIDL)控制技术控制待机电 ...

  10. jdk-8u241各系统版本

    今天下载jdk8的时候汇总了linux/mac/windows操作系统的安装包 链接: https://pan.baidu.com/s/105wtrimc1liThGxsZIv7-A 密码: v8lc ...