《MySQL:MySQL表的約束-主鍵/復合主鍵/唯一鍵/外鍵》

表的約束:表中一定要有各種約束,通過約束,讓未來插入數據庫表中的數據是符合預期的。約束本質是通過技術手段,倒逼程序員插入正確的數據。即,站在mysql的視角,凡是插入進來的數據,都是符合數據約束的!

約束的最終目標:保證數據的完整性和可預期性。

真正約束字段的是數據類型,但是數據類型約束很單一,需要有一些額外的約束,更好的保證數據的合法性。

空屬性

兩個值:null(默認的)和not null(不為空)

數據庫默認字段基本都為空,但是實際開發中,盡可能保證字段不為空,因為數據為空,沒辦法參與運算。

例:

創建一個班級表,包含班級名和班級所在的教室。

正常的邏輯是這樣的:

  • 如果沒有班級名,則不知道在哪個班級
  • 如果沒有教室,則不知道在哪上課

所以在設計數據庫表的時候,一定要在表中進行限制,滿足上面條件的數據就不能插入到表中。者就是約束!

如果對班級和教室不加約束,可以為空(默認的)。

插入數據的時候,沒有給班級名或教室也能插入成功,插入的數據不符合不符合預期。顯然這種不加約束的做法是不符合邏輯的。

對班級和教室進行約束,不能為空。

插入數據的時候,沒有給班級名或教室名,就插入失敗;能插入的數據一定是給了班級名和教室,一定是符合預期的。所以建表的時候一定要加約束。

defalut

如果設置了。用戶插入的時候,如果顯示的有插入的有具體的數據,就使用用戶插入的數據;如果沒有就用默認設置的。

如果設置了默認值,可以省略該字段,就使用默認值,只有設置了default的字段才能省略。

那么not null 和 default 有什么區別呢?

  • 如果沒有明確指定一列要插入,用的是default,如果建表中,對應的列默認沒有設置default,無法不直接插入。
  • default 和 not null 并不沖突,而是互相補充的。
  • not null:當用戶想插入的時候,無非插入的數據要么是 null,要么是合法數據,如果字段為 not null,插入 null 則報錯。
  • default:當用戶忽略了某一列的時候,如果該列設置了默認值則使用默認值,如果沒有設置,直接報錯。用于為列指定一個默認值。

總結:

  • 如果用戶想顯示的插入數據,就是 not null 在約束,如果為 not null ,則插入數據不能為null。
  • 如果用戶不顯示的插入數據,就是 default 在約束,如果沒有設置 default ,則該列不能直接插入

建t14表的時候,字段沒有指定 null 和 default,為什么也能直接插入呢?

MySQL會對sql指令優化。默認指定字段為 null、default 默認值也為 null。

列描述

列描述:comment,沒有實際含義,專門用來描述字段,會根據表創建的語句保存,用來給程序員或DBA來進行了解表字段。

zerofill

看下面這張表。

mysql會對sql語句做優化,將字段a int unsigned 類型優化為 int(10)unsigned;將字段b int 類型優化為 int(11)。10和11表示什么?其實沒有zerofill括號內的數字是沒有意義的。

括號內的數字表示數據的寬度。為什么int unsigned默認為10呢?

因為無符號整數表示-2147483648 到 2147483647,最大為21億多,10位就足夠將一個整數的數據位全部表示出來了;int 默認為11,因為有符號整數表示0 到 4294967295,最大為42億多,加上符號位11位,11位就足夠將一個有符號的整數的數據位全部表示出來了,

但是對列添加了zerofill屬性后,顯示的結果就有所不同了。修改t16a字段的屬性。

可以看到,本來應該顯示為1的,添加zerofill后,顯示成了0001,這就是zerofill屬性的作用,如果插入數據的寬度小于設定的寬度(這里設置的是4),自動填充0;如果插入寬度大于設定的值,顯示的還是它本身。

要注意的是,這只是最后顯示的結果,在MySQL中實際存儲的還是插入的數據本身

主鍵

primary key:用來唯一的約束該字段里面的數據,不能重復,不能為空,一張表中最多只有一個主鍵。

  • 創建表的時候直接在字段上指定主鍵

  • 主鍵約束:主鍵對應的字段不能重復,一旦重復,操作失敗

  • 刪除主鍵

  • 創建表時沒有指定主鍵,可以在創建表之后追加主鍵。如果創建表之后插入了數據,然后再指定某一個字段為主鍵時,必須要保證該字段數據不能重復

復合主鍵

在創建表的時候,在所有字段之后,使用primary key(主鍵字段列表)來創建主鍵,如果有多個字段作為主鍵,可以使用復合主鍵。

注意:一張表中只能有一個主鍵,但是不意味著,一個主鍵只能添加給一個字段。

id和course共同組成了一個主鍵。即,一個學生不能重復選同一門課程。

自增長

auto_increment:當對應的字段指定了auto_increment,插入數據的時候,該字段給值,則用該值;如果該字段不給值,會自動的被系統觸發,系統會從當前字段已經有的最大值+1,得到一個新的不同值,賦值給要插入數據的該字段。通常和主鍵搭配使用,作為邏輯主鍵。

如果建表的時候,不指定 auto_increment 的具體值,則從1開始。如果插入的數據被? auto_increment 指定的字段不給值,就從1自增。

如果插入的數據該字段有值,則使用該值。以后插入的數據,該字段如果不給值,則從該字段的最大值開始自增。

其實,插入一個數據的時候,表中就已經記錄了下次要插入的數據的該字段的值了。

唯一鍵

一張表中往往有很多字段需要唯一性,數據不能重復,但是一張表中只能有一個主鍵,此時,唯一鍵就可以解決表中有多個字段需要唯一性約束的問題。

唯一鍵的本質和主鍵產不多,唯一鍵允許字段為空,而且可以多個為空,空字段不做唯一性比較。

唯一鍵和主鍵的區別:

  • 主鍵更多的是標識記錄的唯一性。
  • 唯一鍵更多的是保證業務上,不要和別的信息出現重復。
假設一個場景
比如在公司,我們需要一個員工管理系統,系統中有一個員工表,員工表中有兩列信息,一個身份證號碼,一個是員工工號,我們可以選擇身份號碼作為主鍵。
而我們設計員工工號的時候,需要一種約束:而所有的員工工號都不能重復。具體指的是在公司的業務上不能重復,我們設計表的時候,需要這個約束,那么就可以將員工工號設計成為唯一鍵。
一般而言,我們建議將主鍵設計成為和當前業務無關的字段,這樣,當業務調整的時候,我們可以盡量不會對主鍵做過大的調整。

外鍵

外鍵用于定義主表和從表之間的關系:外鍵約束主要定義在從表上,主表必須是有主鍵約束或unique唯一鍵約束的。當定義外鍵之后,要求外鍵列數據必須在主表的主鍵列存在或為null。

foreign key ( 字段名 ) references 主表 ( )

案例:建立兩張表。我們來簡單實現學生的插入和班級的刪除,看看有什么問題。

  • 建立學生表和班級表。

  • 插入班級信息。

  • 插入學生信息。

按照我們設計的學生表來看,插入“103王五3”是沒有問題的,但是不符合邏輯,因為班級表中,只有兩個班級,班級號分別為1,2,沒有班級號為3的班級,顯然這種設計是有問題的。也就是不能插入一個不存在的班級。

  • 刪除班級信息。

如果刪除班級號1的班級,顯然也是不符合邏輯的,此時班級有學生,不能刪除班級。也就是不能刪除一個有學生的班級。

即,上面的設計是沒有約束的,會引發相關的不符合邏輯的問題。

此時,就引入了外鍵來解決上面的問題。學生依賴于班級,所以學生表為從表,班級表為主表。學生表中有班級號,班級表中也有班級號,所以班級號就可以作為關聯主表和從表的外鍵。

外鍵約束有兩個關鍵點:

  • 從表和主表的關聯關系
  • 產生外鍵約束

我們來重新設計表結構。

  • 先建立主表班級表。

  • 插入班級信息。

  • 再建立從表學生表。

  • 插入學生信息。

如果插入的學生信息,班級號在班級表中不存在,則報錯。即插入的班級一定是存在的。此時,外鍵班級號就讓從表和主表就有了關聯關系,同時產生了約束。

  • 刪除班級信息。

如果刪除的班級還有學生,就報錯,不讓刪除,班級中沒有學生才能刪除。即刪除的班級一定是沒有學生的。此時,外鍵班級號就讓從表和主表有了關聯關系,同時產生了約束。

這就約束了,但凡插入表中的數據、刪除表中的數據的操作,一定是合法的符合邏輯的操作。

至此,本篇一共總結了八種約束。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/902252.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/902252.shtml
英文地址,請注明出處:http://en.pswp.cn/news/902252.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Qt 創建QWidget的界面庫(DLL)

【1】新建一個qt庫項目 【2】在項目目錄圖標上右擊,選擇Add New... 【3】選擇模版:Qt->Qt設計師界面類,選擇Widget,填寫界面類的名稱、.h .cpp .ui名稱 【4】創建C調用接口(默認是創建C調用接口) #ifnd…

汽車免拆診斷案例 | 2011款雪鐵龍世嘉車刮水器偶爾自動工作

故障現象 一輛2011款雪鐵龍世嘉車,搭載1.6 L 發動機,累計行駛里程約為19.8萬km。車主反映,該車刮水器偶爾會自動工作,且前照燈偶爾會自動點亮。 故障診斷 接車后試車發現,除了上述故障現象以外,當用遙控器…

【Linux】NAT、代理服務、內網穿透

NAT、代理服務、內網穿透 一. NAT1. NAT 技術2. NAT IP 轉換過程3. NAPT 技術4. NAT 技術的缺陷 二. 代理服務器1. 正向代理2. 反向代理3. NAT 和代理服務器 內網穿透內網打洞 一. NAT NAT(Network Address Translation,網絡地址轉換)技術&a…

MobaXterm連接Ubuntu(SSH)

1.查看Ubuntu ip 打開終端,使用指令 ifconfig 由圖可知ip地址 2.MobaXterm進行SSH連接 點擊session,然后點擊ssh,最后輸入ubuntu IP地址以及用戶名

Spring Boot系列之使用Arthas Tunnel Server 進行遠程調試實踐

Spring Boot系列之使用Arthas Tunnel Server 進行遠程調試實踐 前言 在開發和運維 Java 應用的過程中,遠程診斷和調試是一個不可或缺的需求。尤其是當生產環境出現問題時,能夠快速定位并解決這些問題至關重要。Arthas 是阿里巴巴開源的一款強大的 Java…

圖像預處理-添加水印

一.ROI切割 類似裁剪圖片,但是原理是基于Numpy數組的切片操作(ROI數組切片是會修改原圖數據的),也就是說這個“裁剪”不是為了保存“裁剪”部分,而是為了方便修改等處理。 import cv2 as cv import numpy as npimg cv.imread(../images/dem…

數據結構——八大排序算法

排序在生活中應用很多,對數據排序有按成績,商品價格,評論數量等標準來排序。 數據結構中有八大排序,插入、選擇、快速、歸并四類排序。 目錄 插入排序 直接插入排序 希爾排序 選擇排序 堆排序 冒泡排序 快速排序 hoare…

吃透LangChain(五):多模態輸入與自定義輸出

多模態數據輸入 這里我們演示如何將多模態輸入直接傳遞給模型。我們目前期望所有輸入都以與OpenAl 期望的格式相同的格式傳遞。對于支持多模態輸入的其他模型提供者,我們在類中添加了邏輯以轉換為預期格式。 在這個例子中,我們將要求模型描述一幅圖像。 …

【Rust 精進之路之第10篇-借用·規則】引用 (``, `mut`):安全、高效地訪問數據

系列: Rust 精進之路:構建可靠、高效軟件的底層邏輯 作者: 碼覺客 發布日期: 2025年4月20日 引言:所有權的“限制”與“變通”之道 在上一篇【所有權核心】中,我們揭示了 Rust 如何通過所有權規則和移動 (Move) 語義來保證內存安全,避免了垃圾回收器的同時,也防止了諸…

劍指Offer(數據結構與算法面試題精講)C++版——day16

劍指Offer(數據結構與算法面試題精講)C版——day16 題目一:序列化和反序列化二叉樹題目二:從根節點到葉節點的路徑數字之和題目三:向下的路徑節點值之和附錄:源碼gitee倉庫 題目一:序列化和反序…

OpenCV 模板與多個對象匹配方法詳解(繼OpenCV 模板匹配方法詳解)

文章目錄 前言1.導入庫2.圖片預處理3.輸出模板圖片的寬和高4.模板匹配5.獲取匹配結果中所有符合閾值的點的坐標5.1 threshold 0.9:5.2 loc np.where(res > threshold): 6.遍歷所有匹配點6.1 loc 的結構回顧6.2 loc[::-1] 的作用6.2.1 為什么需要反轉…

產品經理學習過程

一:掃盲篇(初始產品經理) 階段1:了解產品經理 了解產品經理是做什么的、產品經理的分類、產品經理在實際工作中都會接觸什么樣的崗位、以及產品經理在實際工作中具體要做什么事情。 二:準備篇 階段2:工…

【消息隊列RocketMQ】一、RocketMQ入門核心概念與架構解析

在當今互聯網技術飛速發展的時代,分布式系統的架構設計愈發復雜。消息隊列作為分布式系統中重要的組件,在解耦應用、異步處理、削峰填谷等方面發揮著關鍵作用。RocketMQ 作為一款高性能、高可靠的分布式消息中間件,被廣泛應用于各類互聯網場景…

從“鏈主”到“全鏈”:供應鏈數字化轉型的底層邏輯

1. 制造業與供應鏈數字化轉型的必然性 1.1. 核心概念與戰略重要性 制造業的數字化轉型,是利用新一代數字技術(如工業互聯網、人工智能、大數據、云計算、邊緣計算等)對制造業的整體價值鏈進行根本性重塑的過程。這不僅涉及技術的應用&#…

x-ui重新申請ssl證書失敗

由于某些需要我們重新申請ssl證書,x-ui自動化腳本不能強制更新,根據x-ui倉庫源碼: https://github.com/vaxilu/x-ui/blob/main/x-ui.sh 在申請ssl證書的地方稍作修改,得到,運行下面的腳本就可以重新申請ssl證書&#…

Java NIO Java 虛擬線程(微線程)與 Go 協程的運行原理不同 為何Go 能在低配機器上承接10萬 Websocket 協議連接

什么是Java NIO? Java NIO(New Input/Output) 是Java 1.4(2002年)引入的一種非阻塞、面向緩沖區的輸入輸出框架,旨在提升Java在高性能和高并發場景下的I/O處理能力。它相比傳統的 Java IO(java…

go環境安裝mac

下載go安裝包:https://golang.google.cn/dl/ 找到對應自己環境的版本下載。 注意有二進制的包,也有圖形界面安裝的包。圖形界面直接傻瓜式點就行了。 二進制的按照下面操作: 1、下載二進制包。 2、將下載的二進制包解壓至 /usr/local目錄…

LVGL源碼(9):學會控件的使用(自定義彈窗)

LVGL版本:8.3 LVGL的控件各式各樣,每種控件都有自己的一些特性,當我們想要使用一個LVGL控件時,我們首先可以通過官網去了解控件的一些基本特性,官網鏈接如下: LVGL Basics — LVGL documentation&#xf…

《軟件設計師》復習筆記(1)——考試介紹【新】

目錄 一、考試介紹 證書價值 考試要求 二、【新】計算機與軟件工程知識 三、軟件設計 一、考試介紹 >考試科目>考題形式>考試時長>合格標準計算機與軟件工程知識75道單選題(每題1分,總分75分)2023年11月改革機試后&#…

MCU中的BSS和data都占用SRAM空間嗎?

在MCU中,BSS段和data段都占用SRAM空間,但它們的存儲方式和用途有所不同。? BSS段 BSS段(Block Started by Symbol)用于存儲未初始化的全局變量和靜態變量。這些變量在程序啟動時會被清零,因此它們不占用Flash空間&a…