MySQL (三)

来源:http://www.cnblogs.com/xuweiweiailixing/archive/2017/08/21/7402347.html
-Advertisement-
Play Games

1 欄位屬性 主鍵、唯一鍵和自增長。 1.1 主鍵 主鍵:primary key,一張表中只能有一個欄位可以使用對應的鍵,用來唯一的約束該欄位裡面的數據,不能重覆。 一張表只能有最多一個主鍵。 1.1.1 增加主鍵 在SQL操作中歐有多種方式可以給表增加主鍵,大體分為三種: 方案1:在創建表的時候, ...


1 欄位屬性

  • 主鍵、唯一鍵和自增長。

1.1 主鍵

  • 主鍵:primary key,一張表中只能有一個欄位可以使用對應的鍵,用來唯一的約束該欄位裡面的數據,不能重覆。
  • 一張表只能有最多一個主鍵。

 

1.1.1 增加主鍵

  • 在SQL操作中歐有多種方式可以給表增加主鍵,大體分為三種:

 

  • 方案1:在創建表的時候,直接在欄位之後,跟primary key關鍵字(主鍵本身不能為空)。
-- 增加主鍵
create table my_pri(
   id int primary key,
   name varchar(20) not null comment '姓名'
)charset utf8;

    • 優點:非常直接;缺點:只能使用一個欄位作為主鍵。  

 

  • 方案2:在創建表的時候,在所有的欄位之後,使用primary key(主鍵欄位列表)來創建主鍵,如果有多個欄位作為主鍵,可以是複合主鍵。
create table my_pri2(
   number char(10) comment '學號',
   course char(10) comment '課程代碼:3901+0000',
   score tinyint unsigned default 60 comment '成績',
   -- 增加主鍵限制:學號和課程代碼應該是唯一的
   primary key (number,course)
)charset utf8;

 

  • 方案3:當表已經創建好之後,額外追加主鍵:可以通過修改表欄位屬性,也可以直接追加。
alter table 表名 add primary key (欄位列表);

  • 前提:表中欄位對應的數據本身是獨立的(不重覆)。

 

1.1.2 主鍵約束

  • 主鍵對應的欄位中的數據不允許重覆,一旦重覆,數據操作失敗(增和該)。

 

1.1.3 主鍵更新 & 刪除主鍵

  • 沒有辦法更新主鍵:主鍵必須先刪除,才能增加。
drop table 表名 drop primary key;

 

1.1.4 主鍵分類

  • 在實際創建表的過程中,很少使用真實業務數據作為主鍵欄位(業務主鍵,如學號、課程號)。
  • 大部分的時候,是使用邏輯性的欄位(欄位沒有業務含義,值是什麼都沒有關係),將這種欄位主鍵稱為邏輯主鍵。

 

1.2 自動增長

  • 自增長:當對應的欄位,不給值,或者給預設值,或者給null的時候,會自動的被系統觸發,系統會從當前欄位中的已有的最大值+1操作,得到一個新的不同的欄位。
  • 通常自動增長和主鍵搭配。

 

1.2.1 新增自增長

  • 自增長特點:auto_increment
    • 任何一個欄位要做自增長必須前提是本身是一個索引(key一欄有值)。

    • 自增長必須是數字。  

    • 一張表最多只能有一個自增長。  

 

1.2.2 自增長使用

  • 當自增長被給定的值為null或者預設值的時候,會觸發自動增長。

 

1.2.3 修改自增長

  • 自增長如果是涉及到欄位改變:必須先刪除自增長,後增加(一張薄只能有一個自增長)。

 

  • 修改當前自增長已經存在的值:修改只能比當前已有的自增長的最大值大,不能小(小不生效)。
-- 修改表選項的值
alter table 表名 auto_increment = 值;

 

  • 思考:為什麼自增長是從1開始?為什麼每次都是自增1呢?
    • 所有系統的變現(如字元集、校對集)都是系統內部的變數進行控制的。
    • 查看自增長對應的變數:show variables like 'auto_increment%';  

  • 可以修改變數實現不同的效果,但是修改是針對整個資料庫的修改,而不是單張表,不建議修改。
-- 不建議修改
set auto_increment_increment = 5;

 

1.2.4 刪除自增長

  • 自增長是欄位的一個屬性:可以通過modify來進行修改(保證欄位沒有auto_increment即可)
alter table 表名 modify 欄位 類型;

 

1.3 唯一鍵

  • 一張表往往有很多欄位需要具有唯一性,數據不能重覆;但是一張表中只能有一個主鍵,所以唯一鍵就可以解決表中有多個欄位需要唯一性的約束。

 

  • 唯一鍵的本質和主鍵差不多,唯一鍵預設的允許自動為空,而且可以多個為空。

 

1.3.1 增加唯一鍵

  • 基本上和主鍵差不多:三種方案。

 

  • 方案一:在創建表的時候,欄位之後直接跟unique/unque key。

 

  • 方案二:在所有的欄位之後增加unique key(欄位列表);--複合唯一鍵

 

  • 方案三:在創建表之後增加唯一鍵。

 

1.3.2 唯一鍵約束

  • 唯一鍵與主鍵本質相同,唯一的區別就是唯一鍵預設允許為控控,而且是多個為空。
  • 如果唯一鍵也不允許為空,那麼與主鍵的約束作用是一致的。

 

1.3.3 更新唯一鍵&刪除唯一鍵

  • 更新唯一鍵:先刪除唯一鍵,再增加唯一鍵。

 

  • 刪除唯一鍵,預設使用欄位名作為索引名字
alter  table 表名 drop index 索引名字;

 

2 索引

  • 幾乎所有的索引都是建立在欄位之上。

 

  • 系統根據某種演算法,將已有的數據(未來可能新增的數據),單獨建立一個文件:文件能夠實現快速的匹配數據,並且能夠快速的找到對應表中的記錄。

 

  • 索引的意義:
    • 提升查詢數據的效率。
    • 約束數據的有效性(唯一性等)。  

 

  • 增加索引的前提條件:索引本身會產生索引文件(有時候可能比數據文件還打),會非常消耗磁碟空間。

 

  • 如果某個欄位需要作為查詢條件經常使用,那麼可以使用索引。
  • 如果某個欄位需要進行數據的有效性約束,也可以使用索引(主鍵、唯一鍵)。

 

  • MySQL中提供了多種索引。
    • 主鍵索引 primary key
    • 唯一索引 unique key
    • 全文索引 fulltext index
    • 普通索引 index

 

  • 全文索引:針對文章內部的關鍵字進行索引。
  • 全文索引最大的問題在於如何確定關鍵字。

 

3 關係

  • 將實體與實體的關係,反應到最終資料庫表的設計上來。將關係分成三種:一對一,一對多和多對多。

 

3.1 一對一

  • 一對一:一張表的一條記錄一定只能和另一張表的一條記錄進行對應;反之亦然。

 

  • 學生表:姓名、性別、年齡、身高、體重、婚姻、籍貫、家庭住址、緊急聯繫人。
id 姓名 性別 年齡 身高 體重 籍貫 家庭住址 緊急聯繫人 婚姻
                   
                   

 

 

 

 

  • 表設計成以上這種形式,是符合要求的。其中姓名、性別、年齡、身高、體重是常用數據,但是婚姻、籍貫、住址和緊急聯繫人屬於不常用數據。如果每次查詢都是查詢所有數據,不常用的數據就會影響效率,實際又不用。

 

  • 解決方案:將常用的和不常用的信息分離存儲,分成兩張表。
  • 學生常用信息表
id 姓名 性別 年齡 身高 體重
           
           

 

 

 

  • 學生不常用信息表
籍貫 家庭住址 緊急聯繫人 婚姻
       
       

 

 

 

  • 但是如果我有時候又需要使用不常用信息怎麼辦?
    • 為了保證不常用信息和常用信息一定能夠對應上,我們唯有找到一個具有唯一性的欄位來共同連接兩張表。--主鍵欄位  
  • 所以,學習不常用信息表修改如下  
id 婚姻 籍貫 家庭住址 緊急聯繫人
         
         

 

 

 

 

  • 綜上所述,一個常用表中的一條記錄,永遠只能在一張不常用表中匹配一條記錄;反過來,一個不常用表中的一條記錄在常用表中也只能匹配一條記錄。

 

3.2 一對多

  • 一對多:一張表中的一條記錄可以對應另外一張表中的多條記錄,反過來,另一張表的一條記錄只能對應第一張表的一條記錄,這種關係就是一對多或多對一。

 

  • 學生和班級的關係:
  • 學生表
id 姓名 年齡 性別
       
       

 

 

 

  • 班級表
id 班級名字
   
   

 

 

 

  • 我們知道,一個學生只能屬於一個班級,而一個班級卻有多個學生,一對多。

 

  • 但是以上設計:解決了實體的設計表問題,但是沒有解決關係問題:學生找不到班級,班級沒有學生。

 

  • 解決方案:在某一張表中增加一個欄位,能夠找到另一張表中的記錄。如何做到呢?在學生表中增加一個欄位指向班級表,因為學生表的記錄只能匹配到一個班級的記錄。
  • 學生表
id 姓名 性別 年齡 班級id
        班級主鍵
        班級主鍵

 

 

 

3.3 多對多

  • 多對多:一張表(A)的一條記錄能夠對應另外一張表(B)的多條記錄;同時B表中的一條記錄也能對應A表中的多條記錄。

 

  • 老師教學:;老師和學生
  • 老師表
t_id 姓名 性別 工資
1 A 6000
2 B 8000

 

 

 

  • 學生表
s_id 姓名 性別 分數
1 張三 59
2 李四 95

 

 

 

 

  • 以上設計方案:實現了實體的設計,但是沒有維護實體的關係。
  • 一個老師教過多個學生,一個學生也被多個老師教多。

 

  • 解決方案:不管在那張表中增加欄位,都會出現問題:該欄位要保存多個數據,而且是與其它表有關係的欄位,不符合表的設計規範,增加一張新表,專門維護兩張表之間的關係。
  • 中間關係表:老師與學生的關係
T_ID S_ID
1 1
1 2
2 1
2 2

 

 

 

 

 

  • 增加了中間表之後:中間表與老師表形成了一對多的關係,而且中間表是多表,維護了能夠唯一找到一表的關係。

 

4 範式

  • 範式:是離散數學中的知識,是為瞭解決一種數據的存儲與優化的問題(保存數據的存儲之後,凡是能夠通過關係尋找出來的數據,堅決不再重覆存儲,起終極目標是為了減少數據冗餘)。

 

  • 範式:是一種分層結構的規範,分為6層:每一層都比上一層更加嚴格。

 

  • 六層範式:1NF、2NF、3NF、4NF、5NF和6NF,其中1NF要求最低,6NF要求最高。

 

  • MySQL屬於關係型資料庫:有空間浪費,而範式致力於節省存儲空間。所以,在設計資料庫的時候,會利用範式來指導設計。但是資料庫不單是解決空間問題,還要保證效率;而範式只為解決空間問題,所以資料庫的設計不可能完全按照範式的要求實現,所以一般情況下,只有前三種範式需要滿足。

 

  • 範式在資料庫的設計當中是有指導意義,但是不是強制規範。

 

4.1 第一範式 1NF

  • 第一範式:在設計表存儲數據的時候,如果表中設計的欄位存儲的數據,在取出來使用之前還需要額外的處理(拆分),那麼就說表的設計不滿足第一範式。
  • 第一範式:屬性不可再分,欄位保證原子性。

 

  • 講師代課表
講師 性別 班級 教室 代課時間 代課時間(開始時間、結束時間)
朱元璋 java001班 B23 30天 2014-02-17 2014-05-05
朱元璋 java002班 C15 30天 2014-05-05 2014-05-30
李世民 Linux003班 C15 15天 2016-02-21 2014-06-20

 

 

 

 

  • 上表的設計不存在問題,但是如果需求是將數據查出來之後,要求一個老師從什麼時候開始上課,到什麼時候結束課程,此時需要將代課時間進行拆分,不符合第一範式,因為數據不具有原子性,可以再拆分。

 

  • 解決方案::將代課時間拆成兩個欄位就可以了。

 

4.2 第二範式 2NF

  • 第二範式:在數據表設計的過程中,如果有複合主鍵,且表中有欄位並不是由整個主鍵來確定,而是依賴主鍵的某個欄位(主鍵的部分),存在欄位依賴主鍵部分的問題,稱之為部分依賴。第二範式就是要解決表設計不允許出現部分依賴。
姓名 性別 班級 教室 代課時間 開始時間 結束時間
朱元璋 java001班 C01 30天 2014-02-27 2014-05-05
朱元璋 java002班 B23 30天 2014-03-21 2014-05-30
李世民 Linux003班 A15 15天 2014-06-01 2014-06-20

 

 

 

 

  • 在上面的表中:因為講師沒有辦法作為獨立主鍵,需要結合班級才能作為主鍵(複合主鍵:一個老師在一個班永遠只帶一個階段的課)。代課時間、開始時間和結束時間欄位都與當前的代課主鍵(講師和班級):但是性別並不依賴班級,教室不依賴講師,性別隻依賴講師,教室只依賴班級,出現了性別和教室依賴主鍵的一部分:即部分依賴。

 

  • 解決方案:取消複合主鍵,使用邏輯主鍵。

 

4.3 第三範式 3NF

  • 要滿足第三範式,必須滿足第二範式。
  • 第三範式:理論上講,一張表中的所有欄位都應該直接依賴主鍵(邏輯主鍵除外),如果表設計中存在一個欄位,並不直接依賴主鍵,而是通過某個非主鍵依賴,最終實現依賴主鍵,把這種不是直接依賴主鍵,而是依賴非初見欄位的依賴關係稱之為傳遞依賴。第三範式就是解決傳遞依賴的問題。

 

  • 講師代課表
id 講師 性別 班級 教室 代課時間 開始時間 結束時間
1 朱元璋 java01班 A03 30天 2014-02-27 2014-05-05
2 朱元璋 Linux02班 B23 30天 2014-03-21 2014-05-30
3 李世民 java001班 A03 30天 2014-06-01 2014-06-20

 

 

 

 

  • 以上設計方案中,性別依賴講師存在,講師依賴主鍵;教室依賴班級,班級依賴主鍵;性別和教室都存在傳遞依賴。

 

  • 解決方案:將存在傳遞依賴的欄位,一級依賴的欄位本身單獨取出,形成一個單獨的表,然後在需要對應的信息的時候,使用對應的實體表的主鍵加起來。
id 講師id 班級id 代課時間 開始時間 結束時間
1 1 10 30天 2014-02-27 2014-05-05
2 1 12 30天 2014-03-21 2014-05-30
3 2 12 30天 2014-06-01 2014-06-20

 

 

 

 

id 講師 性別
1 朱元璋
2 李世民

 

 

 

id 班級 教室
10 java01班 A03
12 Linux02班 B23

 

 

 

5 逆規範化

  • 有的時候,在設計表的時候,如果一張表中有幾個欄位是需要從另外的表中去獲取信息。理論上講,的確可以獲取到想要的數據,但是就是效率低一點。所以我們會刻意在某些表中,不去保存另外表的主鍵(邏輯主鍵),而是直接保存想要的數據信息,這樣一來,在查詢數據的時候,一張表可以直接提供數據,而不需要多表查詢(效率低),但是會導致數據冗餘增加。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、需求緣起 大部分互聯網的業務都是“讀多寫少”的場景,資料庫層面,讀性能往往成為瓶頸。如下圖:業界通常採用“一主多從,讀寫分離,冗餘多個讀庫”的資料庫架構來提升資料庫的讀性能。 這種架構的一個潛在缺點是,業務方有可能讀取到並不是最新的舊數據: (1)系統先對DB-master進行了一個寫操作,寫主 ...
  • 創建db_link,遠程導出/導入。expdp/impdp Oracle資料庫本地磁碟空間有限,或應用系統的需要,會通過遠程的方式導出資料庫。在oracle當中,exp遠程導庫的速度太慢,而expdp又無法直接通過遠程導庫。因此需要創建db_link遠程連接後,才能使用expdp遠程導庫。詳細步驟如 ...
  • 在資料庫中,經常有業務人員提出需求導出資料庫中的業務數據,而且是每天、每周或每月定時導出。為了方便,可將sql查詢的腳本 通過下麵腳本來導出EXCEL數據。 1.將查詢sql腳本(AAA.sql)放到 相關目錄如:/home/oracle/tongji-scripts/sql/AAA.sql 2.# ...
  • 最近買了阿裡雲,把項目部署上去以後,每天第一次訪問總是出一次異常,然後刷新一下就正常了。經查詢資料發現,原來mysql預設會自動關閉空閑時間超過8小時的連接,而連接池並不知道這個連接已經關閉了,所以就會出異常。 查看mysql 修改wait_timeout,雖然通過修改mysql的wait_time ...
  • 環境相關 系統:CentOS 6.8 64位jdk:1.7.0_79hadoop:hadoop 2.7.2 配置SSH免密碼登錄 測試下ssh是否可用 安裝hadoop2 下載hadoop-2.7.2.tar.gz,放在opt目錄下,解壓 配置Hadoop,路徑/opt/hadoop-2.5.1/e ...
  • 一、定義變數 --簡單賦值 declare @a int set @a=5 print @a --使用select語句賦值 declare @user1 nvarchar(50) select @user1='張三' print @user1 declare @user2 nvarchar(50) ...
  • 因公司項目需要,開始接觸大數據分析這塊知識。網上關於大數據這塊的知識還是比較多的。學習了一個禮拜了,再次記錄一下,自己的學習過程,希望可以幫助後學者少走一些彎路。 服務端的配置,由於公司項目經理已經配置好,我也就沒有過多的接觸,我所記錄的更多的是如果使用大數據。(JDK 和Eclipse不講了) 1 ...
  • mysql "ON DUPLICATE KEY UPDATE" 語法如果在INSERT語句末尾指定了ON DUPLICATE KEY UPDATE,並且插入行後會導致在一個UNIQUE索引或PRIMARY KEY中出現重覆值,則在出現重覆值的行執行UPDATE;如果不會導致唯一值列重覆的問題,則插入 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...