场景

我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. python学习(7)关于列表操作相关命令以及浅复制深复制

    在python中,[]表示的是列表.列表有各种操作命令. 1.append()方法,添加一个元素到列表尾部. 注意append()方法与extend()方法有区别:list.append(object ...

  2. 线索二叉树C++实现

    #include<iostream> #include<stdlib.h> #define maxsize 100 using namespace std; typedef s ...

  3. 《自拍教程5》Python自动化测试学习思路

    前提:熟悉测试业务及流程 任何Python自动化测试的前提,都是必须先熟悉实际测试业务. 任何脱离实际测试业务的自动化都是噱头且无实际意义! 测试的基本流程基本是: 测试需求分析,测试用例设计与评审, ...

  4. [Redis-CentOS7]Redis安装(-)

    系统环境 CentOS Linux release 7.7.1908 (Core) yum安装 yum install redis Loaded plugins: fastestmirror Load ...

  5. centos7上安装docker社区版

    container(容器) docker(集装箱) 容器的优点 1. 启动速度快 2. 节省资源 3. 兼容性高 保证机器正常上网 #ping www.baidu.com CPU需要支持虚拟化 # g ...

  6. mybatis 通过配置父类数据源连接和关闭数据,进行junit单元测试

    来源:https://blog.csdn.net/Bigbig_lyx/article/details/80646005 解决问题,单元测试没经过单独配置,每个测试方法中要添加配置数据源 一:配置父类 ...

  7. Caliburn.Micro框架之Action Convertions

    首先新建一个项目,名称叫Caliburn.Micro.ActionConvertions 然后删掉MainWindow.xaml 然后去app.xaml删掉StartupUri这行代码 其次,安装Ca ...

  8. jquery二级导航

    效果图 直接放代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  9. alpine安装telnet等工具

    alpine确实是很精简,但是对于熟悉了centos和ununtu的个人来说,实在是不习惯. 因此,记录关于alpine的一些包安装,以及操作细节(逐渐补充). 1. telnet >>& ...

  10. opencv —— HoughCircles 霍夫圆变换原理及圆检测

    霍夫圆变换原理 霍夫圆变换的基本原理与霍夫线变换(https://www.cnblogs.com/bjxqmy/p/12331656.html)大体类似. 对直线来说,一条直线能由极径极角(r,θ)表 ...