mysql如何讓兩個字段數據都不能重復?


場景

我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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM