Mysql資料庫 深度知識點

来源:https://www.cnblogs.com/Mr-Rocker/archive/2019/10/21/11712529.html
-Advertisement-
Play Games

停止命令:net stop mysql 啟動命令:net start mysql mysql登錄命令 mysql -h ip -P 埠 -u 用戶名 -p mysql --version 或者mysql -V用於在未登錄情況下,查看本機mysql版本 select version();:登錄情況下 ...


停止命令:net stop mysql 啟動命令:net start mysql  

mysql登錄命令

mysql -h ip -P 埠 -u 用戶名 -p   mysql --version 或者mysql -V用於在未登錄情況下,查看本機mysql版本 select version();:登錄情況下,查看鏈接的庫版本   顯示所有資料庫:show databases; 進入指定的庫:use 庫名; 顯示當前庫中所有的表:show tables; 查看其他庫中所有的表:show tables from 庫名; 查看表的創建語句:show create table 表名; 查看表結構:desc 表名; 查看當前所在庫:select database();  

mysql語法規範

  1. 不區分大小寫,但建議關鍵字大寫,表名、列名小寫
  2. 每條命令最好用英文分號結尾
  3. 每條命令根據需要,可以進行縮進或換行
  4. 註釋
    • 單行註釋:#註釋文字
    • 單行註釋:-- 註釋文字 ,註意, 這裡需要加空格
    • 多行註釋:/ **註釋文字 **/

SQL的語言分類

  • DQL(Data Query Language):數據查詢語言 select 相關語句
  • DML(Data Manipulate Language):數據操作語言 insert 、update、delete 語句
  • DDL(Data Define Languge):數據定義語言 create、drop、alter 語句
  • TCL(Transaction Control Language):事務控制語言 set autocommit=0、start transaction、savepoint、commit、rollback
  主要包括以下五大類 整數類型:bit、bool、tinyint、smallint、mediumint、int、bigint 浮點數類型:float、double、decimal 字元串類型:char、varchar、tinyblob、blob、mediumblob、longblob、tinytext、text、mediumtext、longtext 日期類型:Date、DateTime、TimeStamp、Time、Year 其他數據類型:暫不介紹,用的比較少。  

類型(n)說明

在開發中,我們會碰到有些定義整型的寫法是int(11),這種寫法個人感覺在開發過程中沒有什麼用途,不過還是來說一下,int(N)我們只需要記住兩點:
  • 無論N等於多少,int永遠占4個位元組
  • N表示的是顯示寬度,不足的用0補足,超過的無視長度而直接顯示整個數字,但這要整型設置了unsigned zerofill才有效
  decimal採用的是四捨五入  float和double採用的是四舍六入五成雙 什麼是四舍六入五成雙?
就是5以下捨棄5以上進位,如果需要處理數字為5的時候,需要看5後面是否還有不為0的任何數字,如果有,則直接進位,如果沒有,需要看5前面的數字,若是奇數則進位,若是偶數則將5舍掉
char類型占用固定長度,如果存放的數據為固定長度的建議使用char類型,如:手機號碼、身份證等固定長度的信息

數據類型選擇的一些建議

  • 選小不選大:一般情況下選擇可以正確存儲數據的最小數據類型,越小的數據類型通常更快,占用磁碟,記憶體和CPU緩存更小。
  • 簡單就好:簡單的數據類型的操作通常需要更少的CPU周期,例如:整型比字元操作代價要小得多,因為字元集和校對規則(排序規則)使字元比整型比較更加複雜。
 
  • 儘量避免NULL:儘量制定列為NOT NULL,除非真的需要NULL類型的值,有NULL的列值會使得索引、索引統計和值比較更加複雜。
  • 浮點類型的建議統一選擇decimal
  • 記錄時間的建議使用int或者bigint類型,將時間轉換為時間戳格式,如將時間轉換為秒、毫秒,進行存儲,方便走索引
 

許可權生效時間

用戶及許可權信息放在庫名為mysql的庫中,mysql啟動時,這些內容被讀進記憶體並且從此時生效,所以如果通過直接操作這些表來修改用戶及許可權信息的,需要重啟mysql或者執行flush privileges;才可以生效。 用戶登錄之後,mysql會和當前用戶之間創建一個連接,此時用戶相關的許可權信息都保存在這個連接中,存放在記憶體中,此時如果有其他地方修改了當前用戶的許可權,這些變更的許可權會在下一次登錄時才會生效。

創建用戶

語法: create user 用戶名[@主機名] [identified by '密碼'];
說明:
  1. 主機名預設值為%,表示這個用戶可以從任何主機連接mysql伺服器
  2. 密碼可以省略,表示無密碼登錄
通過修改mysql.user表修改密碼 use mysql; update user set authentication_string = password('321') where user = 'test1' and host = '%'; flush privileges;   給用戶授權: grant privileges ON database.table TO 'username'[@'host'] [with grant option]   grant命令說明:
  • priveleges (許可權列表),可以是all,表示所有許可權,也可以是select、update等許可權,多個許可權之間用逗號分開。
  • ON 用來指定許可權針對哪些庫和表,格式為資料庫.表名 ,點號前面用來指定資料庫名,點號後面用來指定表名,*.* 表示所有資料庫所有表。
  • TO 表示將許可權賦予某個用戶, 格式為username@host,@前面為用戶名,@後面接限制的主機,可以是IP、IP段、功能變數名稱以及%,%表示任何地方。
  • WITH GRANT OPTION 這個選項表示該用戶可以將自己擁有的許可權授權給別人。註意:經常有人在創建操作用戶的時候不指定WITH GRANT OPTION選項導致後來該用戶不能使用GRANT命令創建用戶或者給其它用戶授權。 備註:可以使用GRANT重覆給用戶添加許可權,許可權疊加,比如你先給用戶添加一個select許可權,然後又給用戶添加一個insert許可權,那麼該用戶就同時擁有了select和insert許可權。

查看用戶有哪些許可權

show grants for '用戶名'[@'主機'] show grants -- 查看當前用戶的許可權 撤銷用戶的許可權:revoke privileges ON database.table FROM '用戶名'[@'主機']; 刪除用戶: 1.drop user '用戶名'[@‘主機’] 2.delete from user where user='用戶名' and host='主機';    

授權原則說明

  • 只授予能滿足需要的最小許可權,防止用戶幹壞事,比如用戶只是需要查詢,那就只給select許可權就可以了,不要給用戶賦予update、insert或者delete許可權
  • 創建用戶的時候限制用戶的登錄主機,一般是限製成指定IP或者內網IP段
  • 初始化資料庫的時候刪除沒有密碼的用戶,安裝完資料庫的時候會自動創建一些用戶,這些用戶預設沒有密碼
  • 為每個用戶設置滿足密碼複雜度的密碼
  • 定期清理不需要的用戶,回收許可權或者刪除用戶
 

總結

  1. 通過命令的方式操作用戶和許可權不需要刷新,下次登錄自動生效
  2. 通過操作mysql庫中表的方式修改、用戶信息,需要調用flush privileges;刷新一下,下次登錄自動生效
  3. mysql識別用戶身份的方式是:用戶名+主機
  4. 本文中講到的一些指令中帶主機的,主機都可以省略,預設值為%,表示所有機器
  5. mysql中用戶和許可權的信息在庫名為mysql的庫中
   

修改列

alter table 表名 modify column 列名 新類型 [約束]; 或者 alter table 表名 change column 列名 新列名 新類型 [約束]; 2種方式區別:modify不能修改列名,change可以修改列名  
delete單表刪除
delete [別名] from 表名 [[as] 別名] [where條件];
註意: 如果無別名的時候,表名就是別名 如果有別名,delete後面必須寫別名 如果沒有別名,delete後面的別名可以省略不寫。
示例
-- 刪除test1表所有記錄delete from test1; -- 刪除test1表所有記錄delete test1 from test1; -- 有別名的方式,刪除test1表所有記錄delete t1 from test1 t1; -- 有別名的方式刪除滿足條件的記錄delete t1 from test1 t1 where t1.a>100;
多表刪除
可以同時刪除多個表中的記錄,語法如下:
delete [別名1,別名2] from 表1 [[as] 別名1],表2 [[as] 別名2] [where條件];
說明: 別名可以省略不寫,但是需要在delete後面跟上表名,多個表名之間用逗號隔開。
示例1
delete t1 from test1 t1,test2 t2 where t1.a=t2.c2;
刪除test1表中的記錄,條件是這些記錄的欄位a在test.c2中存在的記錄
 

drop,truncate,delete區別

  • drop (刪除表):刪除內容和定義,釋放空間,簡單來說就是把整個表去掉,以後要新增數據是不可能的,除非新增一個表。 drop語句將刪除表的結構被依賴的約束(constrain),觸發器(trigger)索引(index),依賴於該表的存儲過程/函數將被保留,但其狀態會變為:invalid。 如果要刪除表定義及其數據,請使用 drop table 語句。
  • truncate (清空表中的數據):刪除內容、釋放空間但不刪除定義(保留表的數據結構),與drop不同的是,只是清空表數據而已。 註意:truncate不能刪除具體行數據,要刪就要把整個表清空了。
  • delete (刪除表中的數據):delete 語句用於刪除表中的行。delete語句執行刪除的過程是每次從表中刪除一行,並且同時將該行的刪除操作作為事務記錄在日誌中保存,以便進行進行回滾操作。 truncate與不帶where的delete :只刪除數據,而不刪除表的結構(定義) truncate table 刪除表中的所有行,但表結構及其列、約束、索引等保持不變。 對於由foreign key約束引用的表,不能使用truncate table ,而應使用不帶where子句的delete語句。由於truncate table 記錄在日誌中,所以它不能激活觸發器。 delete語句是資料庫操作語言(dml),這個操作會放到 rollback segement 中,事務提交之後才生效;如果有相應的 trigger,執行的時候將被觸發。 truncate、drop 是資料庫定義語言(ddl),操作立即生效,原數據不放到 rollback segment 中,不能回滾,操作不觸發 trigger。 如果有自增列,truncate方式刪除之後,自增列的值會被初始化,delete方式要分情況(如果資料庫被重啟了,自增列值也會被初始化,資料庫未被重啟,則不變)
  • 如果要刪除表定義及其數據,請使用 drop table 語句
  • 安全性:小心使用 drop 和 truncate,尤其沒有備份的時候,否則哭都來不及
  • 刪除速度,一般來說: drop> truncate > delete
drop truncate delete  
條件刪除 不支持 不支持 支持
刪除表結構 支持 不支持 不支持
事務的方式刪除 不支持 不支持 支持
觸發觸發器
別名中有特殊符號的,比如空格,此時別名必須用引號引起來。   不等於符號的使用: <> 這個是最早的用法。 !=是後來才加上的。 兩者意義相同,在可移植性上前者優於後者 故而sql語句中儘量使用<>來做不等判斷    

 

like(模糊查詢)

select 列名 from 表名 where 列 like pattern;
pattern中可以包含通配符,有以下通配符: %:表示匹配任意一個或多個字元 _:表示匹配任意一個字元。

 

查詢運算符、like、between and、in、not in對NULL值查詢不起效  

<=>(安全等於)

<=>:既可以判斷NULL值,又可以判斷普通的數值,可讀性較低,用得較少  

總結

  • like中的%可以匹配一個到多個任意的字元,_可以匹配任意一個字元
  • 空值查詢需要使用IS NULL或者IS NOT NULL,其他查詢運算符對NULL值無效
  • 建議創建表的時候,儘量設置表的欄位不能為空,給欄位設置一個預設值
  • <=>(安全等於)玩玩可以,建議少使用
語法: select 列 from 表 limit [offset,] count;
說明: offset:表示偏移量,通俗點講就是跳過多少行,offset可以省略,預設為0,表示跳過0行;範圍:[0,+∞)。 count:跳過offset行之後開始取數據,取count行記錄;範圍:[0,+∞)。 limit中offset和count的值不能用表達式。
 

limit中不能使用表達式,limit後面的2個數字不能為負數

 

欄位存在相同的值,當排序過程中存在相同的值時,沒有其他排序規則時,mysql懵逼了,不知道怎麼排序了;  建議:分頁排序時,排序不要有二義性,二義性情況下可能會導致分頁結果亂序,可以在後面追加一個主鍵排序 where 多欄位同時限制: SELECT user_id 用戶id, price 最大金額, the_year 年份 FROM t_order t1 WHERE (t1.user_id , t1.price) IN (SELECT t.user_id, MAX(t.price) FROM t_order t GROUP BY t.user_id); 現在我們來討論java輸出的順序為何和sql不一致?
上面java代碼中兩個表的連接查詢使用了嵌套迴圈,外迴圈每執行一次,內迴圈的表都會全部遍歷一次,如果放到mysql中,就相當於內標全部掃描了一次(一次全表io讀取操作),主表(外迴圈)如果有n條數據,那麼從表就需要全表掃描n次,表的數據是存儲在磁碟中,每次全表掃描都需要做io操作,io操作是最耗時間的,如果mysql按照上面的java方式實現,那效率肯定很低。
那mysql是如何優化的呢?
msql內部使用了一個記憶體緩存空間,就叫他join_buffer吧,先把外迴圈的數據放到join_buffer中,然後對從表進行遍歷,從表中取一條數據和join_buffer的數據進行比較,然後從表中再取第2條和join_buffer數據進行比較,直到從表遍歷完成,使用這方方式來減少從表的io掃描次數,當join_buffer足夠大的時候,大到可以存放主表所有數據,那麼從表只需要全表掃描一次(即只需要一次全表io讀取操作)。 mysql中這種方式叫做Block Nested Loop。     欄位值為NULL的時候,not in查詢有大坑,這個要註意 建議創建表的時候,列不允許為空  

delimiter關鍵字  sql語句結束符

delimiter用來設置結束符,當mysql執行腳本的時候,遇到結束符的時候,會把結束符前面的所有語句作為一個整體運行,存儲過程中的腳本有多個sql,但是需要作為一個整體運行,所以此處用到了delimiter   /*在執行過程中出任何異常設置hasSqlError為TRUE*/ DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET hasSqlError=TRUE; 根據hasSqlError判斷是否有異常,做回滾和提交操作     mysql使用binlog和relaylog記錄資料庫的變化 binlog有三種格式:ROW STATEMENT MIXED ,ROW記錄national數據被修改了,修改成了什麼樣子;STATEMENT 記錄修改的sql到binlog;MIXED就是以上兩種模式的混合。 binlog是一個二進位文件,解析binlog有兩種方式: 1.在命令行使用,show binlog events in 'binlog-filename';方式查看 2.下載分析binlog,然後通過mysqlbinlog工具進行解析     扇區:磁碟存儲的最小單位,扇區一般大小為512Byte 磁碟塊:文件系統與磁碟交互的最小單位(電腦系統讀寫磁碟的最小單位),一個磁碟塊由連續幾個扇區組成,塊一般大小為4KB   二分法查找數據的優點:定位數據非常快,前提是:目標數組是有序的。  

總結一下使用索引的一些建議

  1. 在區分度高的欄位上面建立索引可以有效的使用索引,區分度太低,無法有效的利用索引,可能需要掃描所有數據頁,此時和不使用索引差不多
  2. 聯合索引註意最左匹配原則:必須按照從左到右的順序匹配,mysql會一直向右匹配直到遇到範圍查詢(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)順序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調整
  3. 查詢記錄的時候,少使用*,儘量去利用索引覆蓋,可以減少回表操作,提升效率
  4. 有些查詢可以採用聯合索引,進而使用到索引下推(IPC),也可以減少回表操作,提升效率
  5. 禁止對索引欄位使用函數、運算符操作,會使索引失效
  6. 字元串欄位和數字比較的時候會使索引無效
  7. 模糊查詢'%值%'會使索引無效,變為全表掃描,但是'值%'這種可以有效利用索引
  8. 排序中儘量使用到索引欄位,這樣可以減少排序,提升查詢效率

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

-Advertisement-
Play Games
更多相關文章
  • 分區測試的時候發現之前用gdisk分區之後,就無法用fdisk進行分區了,哪怕格式化了也不行,通過fdisk 查看硬碟,發現硬碟都變成了GPT分區,無法通過fdisk進行分區操作,所以要通過parted 刪除其GPT分區 [root@docker-server-1 ~]# fdisk -lDisk ...
  • 在腳本中使用start命令: 註: start命令:啟動單獨的“命令提示符”視窗來運行指定程式或命令。如果在沒有參數的情況下使用,start 將打開第二個命令提示符視窗。 ...
  • 1、Redis概念 Redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字元串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add ...
  • 轉自:http://www.maomao365.com/?p=10278 摘要: 下文講述sqlserver中將使用逗號組合的單列數據,分隔為多列數據的方法 實驗環境:sql server 2012 實現思路: 1.將逗號分隔的數據替換成為xml數據 2.使用xml讀取函數讀取相關數據例: 將包含逗 ...
  • 一、排序 redis 支持對 list,set 和 zset 元素的排序,排序的時間複雜度是 O(N+M log(M))。(N 是集合大小,M 為返回元素的數量) [BY pattern]:sort 命令預設使用集合元素進行排序,可以通過 “BY pattern” 使用外部 key 的數據作為權重排 ...
  • 前言 索引的主要作用是起到約束和加速查找,ORM框架(sqlalchemy)是用類和對象對資料庫進行操作 索引的種類 按種類去分 1.普通索引:能夠加速查找 2.主鍵索引:能夠加速查找、不能為空、不能重覆 3.唯一索引:加速查找、可以為空、不能重覆 4.聯合索引(多列): ①聯合主鍵索引 ②聯合唯一 ...
  • [20191013]oracle number類型存儲轉化腳本.txt--//測試看看是否可以利用bc obase=100的輸出解決問題。另外以前腳本忘記考慮尾數的四捨五入問題。--//也許編程就是這樣,總有一些細節沒有考慮到...--//代碼如下num2raw_5.sh:#! /bin/bash# ...
  • 錯誤內容 解決方法 本人連接的是mysql資料庫,檢查sql語法並無錯誤。而此處為 多條query語句,報錯信息指向分號後的第二條語句。 判斷可能是連接的datasource預設只允許執行單個query語句。 在連接datasource的url後面增加參數allowMultiQueries=true ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...