?? 作者主頁:不吃西紅柿
?? 簡介:CSDN博客專家??、信息技術智庫公號作者? 簡歷模板、PPT模板、學習資料、面試題庫、技術互助【關注我,都給你】
?? 歡迎點贊 ?? 收藏 ?留言 ??
?? 耗時1年整理,硬核文章目錄:https://t.1yb.co/zHJ
目錄
1.MySQL數據庫的介紹
什么是數據庫
作用
常見的數據庫
認識mysql數據庫
2.安裝MySQL
Mac系統(tǒng)中安裝MySQL
使?用Mac中的Homebrew進?行行mysql的安裝
Windows安裝MySQL5.7.17
3.認識和操作一下mysql的基本命令
登錄mysql,在終端輸入以下命令,進行登錄
查看當前mysql中所有的庫
選擇需要操作的庫,打開庫
查看表中的數據
庫和表的概念與關系
如何創(chuàng)建自己的庫?
查看所有庫
創(chuàng)建表的語法
添加數據
4.MySQL基礎操作
使用方法:
SQL ( Structure query language ) 結構化查詢語言
SQL語句中的快捷鍵
1.通過命令行連接MySQL
2. 數據庫操作
3. 數據表操作
4. 數據操作 增刪改查
退出MySQL
5.MySQL的數據類型
一.MySQL的數據類型
1、字符串數據類型
2、數值類型
3、日期和時間類型
4、二進制數據類型
二、表的字段約束
三、MySQL的運算符
四、主鍵
6.MySQL數據庫與數據表操作
數據庫的操作
1.數據庫的創(chuàng)建
2.查看所有庫
3.打開庫/進入庫/選擇庫
4.刪除庫
數據表的操作
1.創(chuàng)建表
2.修改表結構
3.修改表名
4.更改表中的自增的值
5.修改表引擎
6.刪除表
7.Mysql數據庫表引擎與字符集
1.服務器處理客戶端請求
2.存儲引擎
3.MyISAM和InnoDB表引擎的區(qū)別
1) 事務支持
2) 存儲結構
3) 表鎖差異
4) 表主鍵
5) 表的具體行數
6) CURD操作
7) 外鍵
8) 查詢效率
9)MyISAM和InnoDB兩者的應用場景
4.了解一下字符集和亂碼
字符集簡介
5.MySQL中的utf8和utf8mb4
字符集的查看
8.MySQL 數據操作 DML
添加數據
修改數據
刪除數據
9.MySQL數據查詢SQL
基礎查詢
Where 條件查詢
Like 子句
Group BY 分組
Having 子句
Order by 排序
Limit 數據分頁
10.Mysql數據庫導入導出和授權
數據導出
1.數據庫數據導出
2.將數據庫中的表導出
數據導入
把導出的sql文件數據導入到mysql數據庫中
把導出的表sql 導入數據庫
權限管理
創(chuàng)建用戶的語法格式:
刪除用戶
數據庫(Database)就是按照數據結構來組織,存儲和管理數據的倉庫 專業(yè)的數據庫是專門對數據進行創(chuàng)建,訪問,管理,搜索等操作的軟件,比起我們自己用文件讀寫的方式對象數據進行管理更加的方便,快速,安全
方便數據的存儲和查詢,速度快,安全,方便
可以處理并發(fā)訪問
更加安全的權限管理訪問機制
數據庫分兩大類,一類是 關系型數據庫。另一類叫做 非關系型數據庫。
1.下載安裝mysql
brew install mysql@5.7
如果看到以下界?面則表示已經下載安裝成功
2.啟動mysql mysql.server start
3.關閉mysql mysql.server stop
4.登錄mysql mysql -u root -p
1. 在MySQL官網 http://dev.mysql.com/downloads/mysql/ 上面下載ZIP安裝包(第二個:Windows (x86, 64-
bit), ZIP Archive)。
2. 下載完成后解壓,將其放到想要安裝的目錄下。
例如:D:\MySQL5.7\mysql-5.7.17-winx64
3. 新建一個my.ini配置文件,原始的my-default.ini配置文件只是個模版,不要在里面改動。 my.ini的內容如下:
[mysql] default-character-set=utf8
[mysqld] port = 3306 basedir=D:\MySQL5.7\mysql-5.7.17-winx64 datadir=D:\MySQL5.7\mysql-5.7.17- winx64\data max_connections=200 character-set-server=utf8 default-storage-engine=INNODB explicit_defaults_for_timestamp=true
4. 在安裝路徑下新建一個空的data文件夾。
5. 以管理員身份運行cmd,進入bin目錄,執(zhí)行 mysqld --initialize-insecure --user=mysql 命令。不進行這一
步,安裝完成之后無法啟動服務。
6. 依然在管理員cmd窗口的bin目錄下,執(zhí)行 mysqld install 命令安裝。完成后會提示安裝成功。
7. 依然在管理員cmd窗口的bin目錄下,執(zhí)行 net start mysql 命令啟動MySQL服務。
8. 修改環(huán)境變量,添加"D:\MySQL5.7\mysql-5.7.17-winx64\bin"。
9. 在普通cmd窗口中,進入bin目錄,執(zhí)行 mysql -u root -p 命令,默認沒有密碼,回車進入。
認識庫,表的概念和關系 mysql的基本命令: 登錄,查看庫,選擇庫,查看表, 創(chuàng)建庫,創(chuàng)建表,添加數據,查詢數據。
- mysql -u root -p
- MacBook-Pro:~ yc$ mysql -u root -p
- Enter password:
- Welcome to the MySQL monitor. Commands end with ; or \g.
- Your MySQL connection id is 4
- Server version: 5.7.28 Homebrew
- Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
- Oracle is a registered trademark of Oracle Corporation and/or its
- affiliates. Other names may be trademarks of their respective
- owners.
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- mysql>
庫==>數據庫==>就像文件夾一樣,庫里面可以存儲很多個表)
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
use mysql; 查看當前庫中的所有數據表
show tables;
+---------------------------+
| Tables_in_mysql |
# 查看user表中的所有數據的所有字段 select * from user;
# 查看 user表中的所有數據的 host和user字段列 select host,user from user;
+-----------+---------------+
| host | user |
+-----------+---------------+
| localhost | mysql.session |
| localhost | mysql.sys |
| localhost | root |
+-----------+---------------+
庫就像是文件夾,庫中可以有很多個表 表就像是我們的excel表格文件一樣 每一個表中都可以存儲很多數據
mysql中可以有很多不同的庫,庫中可以有很多不同的表 表中可以定義不同的列(字段), 表中可以根據結構去存儲很多的數據
create database 庫名 default charset=utf8; 創(chuàng)建庫
+---------------------------+
| columns_priv |
| db |
| engine_cost |
....
| time_zone_name |
| time_zone_transition |
| time_zone_transition_type |
| user |
+---------------------------+
31 rows in set (0.00 sec)
create database tlxy default charset=utf8;
-- Query OK, 1 row affected (0.01 sec)
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| tlxy |
+--------------------+
5 rows in set (0.00 sec)
-- 進入庫 use tlxy;
create table 表名( 字段名 類型 字段約束, 字段名 類型 字段約束, 字段名 類型 字段約束, )engine=innodb default
charset=utf8;
-- 創(chuàng)建用戶表 create table user(
name varchar(20),
age int,
sex char(1)
)engine=innodb default charset=utf8;
-- Query OK, 0 rows affected (0.16 sec)
-- 向 user 表中 添加 name,age,sex 數據
insert into user(name,age,sex) values('admin',26,'男'); -- Query OK, 1 row affected (0.00 sec)
insert into user(name,age,sex) values('張三',22,'女');
查看表中的數據
select * from user; +--------+------+------+ |name |age |sex | +--------+------+------+ |admin| 26|男 | |張三 | 22|女 | +--------+------+------+ 2 rows in set (0.00 sec)
SQL語言分為4個部分:DDL(定義)、DML(操作)、DQL(查詢)、DCL(控制)
\G 格式化輸出(文本式,豎立顯示) \s 查看服務器端信息
\c 結束命令輸入操作
\q 退出當前sql命令行模式
\h 查看幫助
連接, 打開庫, 操作, 關閉退出
1) SQL 語句可以換行, 要以分號結尾
2) 命令不區(qū)分大小寫. 關鍵字和函數建議用大寫
3) 如果提示符為 '> 那么需要輸入一個'回車
4) 命令打錯了換行后不能修改, 可以用 \c 取消
數據庫管理系統(tǒng)中, 可以有很多庫, 每個數據庫中可以包括多張數據表
查看表: show tables;
創(chuàng)建表: create table 表名(字段名1 類型,字段名2 類型)engine=innodb default charset=utf8; 創(chuàng)建表: 如果表不存在,則創(chuàng)建, 如果存在就不執(zhí)行這條命令
create table if not exists 表名(字段1 類型,字段2 類型);
create table if not exists users(
id int not null primary key auto_increment, name varchar(4) not null,
age tinyint,
sex enum('男','女')
) engine=innodb default charset=utf8;
刪除表: drop table 表名;
表結構: desc 表名;
查看建標語句:show create table users;
插入
insert into 表名(字段1,字段2,字段3) values(值1,值2,值3);
insert into 表名(字段1,字段2,字段3) values(a值1,a值2,a值3),(b值1,b值2,b值3); 查詢
select * from 表名;
select 字段1,字段2,字段3 from 表名;
select * from 表名 where 字段=某個值;
修改
update 表名 set 字段=某個值 where 條件;
update 表名 set 字段1=值1,字段2=值2 where 條件;
update 表名 set 字段=字段+值 where 條件;
刪除
delete from 表名 where 字段=某個值;
exit; 或者 quit;
數據類型是定義列中可以存儲什么類型的數據以及該數據實際怎樣存儲的基本規(guī)則數據類型限制存儲在數據列列中的數據。例如,數值數據類型列只能接受數值類型的的數據在設計表時,應該特別重視所用的數據類型。使用錯誤的數據類型可能會嚴重地影響應用程序的功能和性能。
更改包含數據的列不是一件小事(而且這樣做可能會導致數據丟失)。
數據類型: 整型、浮點型、字符串、日期等
最常用的數據類型是串數據類型。它們存儲串,如名字、地址、電 話號碼、郵政編碼等。 不管使用何種形式的串數據類型,串值都必須括在引號內 有兩種基本的串類型,分別為定長串和變長串
定長串:char
1. 接受長度固定的字符串,其長度是在創(chuàng)建表時指定的。 定長列不允許存儲多于指定長度字符的數據。
2. 指定長度后,就會分配固定的存儲空間用于存放數據 char(7) 不管實際插入多少字符,它都會占用7個字符位置
變長串 varchar
存儲可變長度的字符串 varchar(7) 如果實際插入4個字符, 那么它只占4個字符位置,當然插入的數據長度不能超過7個字符。
注意
既然變長數據類型這樣靈活,為什么還要使用定長數據類型? 回答:因為性能,MySQL處理定長列遠比處理變長列快得多。
Text 變長文本類型存儲
數值數據類型存儲數值。MySQL支持多種數值數據類型,每種存儲的數值具有不同的取值范圍。支持的取值范圍越大,所需存儲空間越多
與字符串不一樣,數值不應該括在引號內
decimal(5, 2) 表示數值總共5位, 小數占2位 tinyint 1字節(jié)(8位) 0-255。-128,127 int 4字節(jié)。 -21億,21億。0-42億 float.
MySQL中沒有專門存儲貨幣的數據類型,一般情況下使用DECIMAL(8, 2)
有符號或無符號
所有數值數據類型(除BIT和BOOLEAN外)都可以有符號或無符號
注意
如果將郵政編碼類似于01234存儲為數值類型,則保存的將是數值1234,此時需要使用字符串類型 手機號應該用什么進行存儲呢?
MySQL使用專門的數據類型來存儲日期和時間值
datetime 8字節(jié)1000-01-01 00:00:00 ~ 9999-12-31 23:59:59
二進制數據類型可存儲任何數據(甚至包括二進制信息),如圖像、多媒體、字處理文檔等
其中%表示任意數量的任意字符,_表示任意一位字符
1、表中每一行都應該有可以唯一標識自己的一列,用于記錄兩條記錄不能重復,任意兩行都不具有相同的主鍵值
2、應該總是定義主鍵 雖然并不總是都需要主鍵,但大多數數據庫設計人員都應保證他們創(chuàng)建的每個表具有一個主 鍵,以便于以后的數據操縱和管理。
要求
(例如,如果使用一個名字作為主鍵以標識某個供應商,當該供應商合并和更改其名字時,必須更改這個主鍵。)
數據庫的操作:數據庫創(chuàng)建 ;數據庫刪除
數據表的操作:數據表的創(chuàng)建;數據表的修改 (表結構) ;數據表的刪除
# 鏈接mysql數據庫后,進入mysql后可以操作數據
# 1. 創(chuàng)建庫
create database if not exists tlxy default charset=utf8;
-- 1. 數據庫 tlxy 如果不存在則創(chuàng)建數據庫,存在則不創(chuàng)建
-- 2. 創(chuàng)建 tlxy 數據庫,并設置字符集為utf8
-- 3. 無特殊情況都要求字符集為utf8或者utf8mb4的字符編碼
# 1. 查看所有庫 show databases;
# use 庫名 use tlxy
刪庫有風險,動手需大膽(哈哈哈,大不了西紅柿帶你跑路)
# 刪除庫,那么庫中的所有數據都將在磁盤中刪除。 drop database 庫名
語法格式:
create table 表名(字段名,類型,【字段約束】,。。。); 實例:
# 以下創(chuàng)建一個 users 的表 create table users(
-- 創(chuàng)建ID字段,為正整數,不允許為空 主鍵,自動遞增
id int unsigned not null primary key auto_increment,
-- 創(chuàng)建 存儲 名字的字段,為字符串類型,最大長度 5個字符,不允許為空 username varchar(5) not null,
-- 創(chuàng)建存儲 密碼 的字段,固定長度 32位字符, 不允許為空
password char(32) not null,
-- 創(chuàng)建 年齡 字段,不允許為空,默認值為 20
age tinyint not null default 20
)engine=innodb default charset=utf8;
# 查看表結構 desc users;
#查看建表語句
show create table users;
創(chuàng)建表的基本原則:
語法格式:alter table 表名 action (更改的選項)
添加字段
# 語法:alter table 表名 add 添加的字段信息 --在users表中 追加 一個num字段
alter table users add num int not null;
-- 在指定字段后面追加字段 在 users 表中 age字段后面 添加一個 email 字段 alter table users add email varchar(50) after age;
-- 在指定字段后面追加字段,在 users 表中 age字段后面 添加一個 phone alter table users add phone char(11) not null after age;
-- 在表的最前面添加一個字段
alter table users add aa int first;
刪除字段
# 刪除字段 alter table 表名 drop 被刪除的字段名 alter table users drop aa;
修改字段
語法格式: alter table 表名 change|modify 被修改的字段信息 change: 可以修改字段名,
modify: 不能修改字段名。
# 修改表中的 num 字段 類型,使用 modify 不修改表名
alter table users modify num tinyint not null default 12;
# 修改表中的 num 字段 為 int并且字段名為 nn alter table users change num mm int;
# 注意:一般情況下,無特殊要求,不要輕易修改表結構
# 語法:alter table 原表名 rename as 新表名
# 在常規(guī)情況下,auto_increment 默認從1開始繼續(xù)遞增 alter table users auto_increment = 1000;
# 推薦在定義表時,表引擎為 innodb。
# 通過查看建表語句獲取當前的表引擎
mysql> show create table users\G;
*************************** 1. row ***************************
Table: users
Create Table: CREATE TABLE `users` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
# 直接查看當前表狀態(tài)信息
mysql> show table status from tlxy where name = 'users'\G; *************************** 1. row ***************************
Name: users
Engine: InnoDB
# 修改表引擎語句
alter table users engine = 'myisam';
drop table 表名
其實不論客戶端進程和服務器進程是采用哪種方式進行通信,最后實現(xiàn)的效果都是:客戶端進程向服務器進程發(fā)送
一段文本(MySQL語句),服務器進程處理后再向客戶端進程發(fā)送一段文本(處理結果)。那服務器進程對客戶
端進程發(fā)送的請求做了什么處理,才能產生最后的處理結果呢?客戶端可以向服務器發(fā)送增刪改查各類請求,我們
這里以比較復雜的查詢請求為例來畫個圖展示一下大致的過程:
雖然查詢緩存有時可以提升系統(tǒng)性能,但也不得不因維護這塊緩存而造成一些開銷,比如每次都要去查詢緩
存中檢索,查詢請求處理完需要更新查詢緩存,維護該查詢緩存對應的內存區(qū)域。從MySQL 5.7.20開始,不
推薦使用查詢緩存,并在MySQL 8.0中刪除。
MySQL 服務器把數據的存儲和提取操作都封裝到了一個叫 存儲引擎 的模塊里。我們知道 表 是由一行一行的記錄組成的,但這只是一個邏輯上的概念,物理上如何表示記錄,怎么從表中讀取數據,怎么把數據寫入具體的物理存儲器上,這都是 存儲引擎 負責的事情。為了實現(xiàn)不同的功能, MySQL 提供了各式各樣的 存儲引擎 ,不同 存儲引擎 管理的表具體的存儲結構可能不同,采用的存取算法也可能不同。
存儲引擎以前叫做 表處理器 ,它的功能就是接收上層傳下來的指令,然后對表中的數據進行提取或寫入操作。
為了管理方便,人們把 連接管理 、 查詢緩存 、 語法解析 、 查詢優(yōu)化 這些并不涉及真實數據存儲的功能劃分為MySQL server 的功能,把真實存取數據的功能劃分為 存儲引擎 的功能。各種不同的存儲引擎向上邊的 MySQLserver 層提供統(tǒng)一的調用接口(也就是存儲引擎API),包含了幾十個底層函數,像"讀取索引第一條內容"、"讀取索引下一條內容"、"插入記錄"等等。
所以在 MySQL server 完成了查詢優(yōu)化后,只需按照生成的執(zhí)行計劃調用底層存儲引擎提供的API,獲取到數據后返回給客戶端就好了。
MySQL 支持非常多種存儲引擎:
ARCHIVE 用于數據存檔(行被插入后不能再修改)
BLACKHOLE 丟棄寫操作,讀操作會返回空內容
CSV 在存儲數據時,以逗號分隔各個數據項
FEDERATED 用來訪問遠程表
InnoDB 具備外鍵支持功能的事務存儲引擎
MEMORY 置于內存的表
MERGE 用來管理多個MyISAM表構成的表集合
MyISAM 主要的非事務處理存儲引擎
NDB MySQL集群專用存儲引擎
MyISAM不支持事務,而InnoDB支持。
事務:訪問并更新數據庫中數據的執(zhí)行單元。事物操作中,要么都執(zhí)行要么都不執(zhí)行
MyISAM:每個MyISAM在磁盤上存儲成三個文件。
InnoDB:主要分為兩種文件進行存儲
MyISAM:只支持表級鎖,用戶在操作myisam表時,select,update,delete,insert語句都會給表自動加鎖,如果加鎖以后的表滿足insert并發(fā)的情況下,可以在表的尾部插入新的數據。
InnoDB:支持事務和行級鎖,是innodb的最大特色。
行鎖大幅度提高了多用戶并發(fā)操作的新能。但是InnoDB的行鎖,只是在WHERE的主鍵是有效的,非主鍵的WHERE都會鎖全表的。
MyISAM:允許沒有任何索引和主鍵的表存在,索引都是保存行的地址。 InnoDB:如果沒有設定主鍵或者非空唯一索引,就會自動生成一個6字節(jié)的主鍵(用戶不可見),數據是主索引的一部分,附加索引保存的是主索引的值。
InnoDB的主鍵范圍更大,最大是MyISAM的2倍。
MyISAM:保存有表的總行數,如果select count() from table;會直接取出出該值。 InnoDB:沒有保存表的總行數
(只能遍歷),如果使用select count() from table;就會遍歷整個表,消耗相當大,但是在加了wehre條件后,
myisam和innodb處理的方式都一樣。
MyISAM:如果執(zhí)行大量的SELECT,MyISAM是更好的選擇。 InnoDB:如果你的數據執(zhí)行大量的INSERT或UPDATE,出于性能方面的考慮,應該使用InnoDB表。DELETE 從性能上InnoDB更優(yōu),但DELETE FROM table時,InnoDB不會重新建立表,而是一行一行的刪除,在innodb上如果要清空保存有大量數據的表,最好使用truncate table這個命令。
MyISAM:不支持 InnoDB:支持
MyISAM相對簡單,所以在效率上要優(yōu)于InnoDB,小型應用可以考慮使用MyISAM。
推薦考慮使用InnoDB來替代MyISAM引擎,原因是InnoDB自身很多良好的特點,比如事務支持、存儲 過程、視圖、行級鎖定等等,在并發(fā)很多的情況下,相信InnoDB的表現(xiàn)肯定要比MyISAM強很多。
另外,任何一種表都不是萬能的,只用恰當的針對業(yè)務類型來選擇合適的表類型,才能最大的發(fā)揮MySQL的性能優(yōu)勢。如果不是很復雜的Web應用,非關鍵應用,還是可以繼續(xù)考慮MyISAM的,這個具體情況可以自己斟酌。
MyISAM管理非事務表。它提供高速存儲和檢索,以及全文搜索能力。如果應用中需要執(zhí)行大量的SELECT查詢,那么MyISAM是更好的選擇。 InnoDB用于事務處理應用程序,具有眾多特性,包括ACID事務支持。如果應用中需要執(zhí)行大量的INSERT或UPDATE操作,則應該使用InnoDB,這樣可以提高多用戶并發(fā)操作的性能?,F(xiàn)在默認使用InnoDB。
我們知道在計算機中只能存儲二進制數據,那該怎么存儲字符串呢?當然是建立字符與二進制數據的映射關系了,
建立這個關系最起碼要搞清楚兩件事兒:
1. 你要把哪些字符映射成二進制數據?
也就是界定清楚字符范圍。
2. 怎么映射?
將一個字符映射成一個二進制數據的過程也叫做 編碼 ,將一個二進制數據映射到一個字符的過程叫做 解碼 。人們抽象出一個 字符集 的概念來描述某個字符范圍的編碼規(guī)則
我們看一下一些常用字符集的情況:
ASCII 字符集
共收錄128個字符,包括空格、標點符號、數字、大小寫字母和一些不可見字符。由于總共才128個字符,所以可以使用1個字節(jié)來進行編碼,我們看一些字符的編碼方式:
ISO 8859-1 字符集
共收錄256個字符,是在 ASCII 字符集的基礎上又擴充了128個西歐常用字符(包括德法兩國的字母),也可以使用1個字節(jié)來進行編碼。這個字符集也有一個別名 latin1 。
GB2312 字符集
收錄了漢字以及拉丁字母、希臘字母、日文平假名及片假名字母、俄語西里爾字母。其中收錄漢字6763個,其他文字符號682個。同時這種字符集又兼容 ASCII 字符集,所以在編碼方式上顯得有些奇怪:
這種表示一個字符需要的字節(jié)數可能不同的編碼方式稱為 變長編碼方式 。比方說字符串 '愛u' ,其
中 '愛' 需要用2個字節(jié)進行編碼,編碼后的十六進制表示為 0xCED2 , 'u' 需要用1個字節(jié)進行編碼,編碼后的十六進制表示為 0x75 ,所以拼合起來就是 0xCED275 。
小貼士: 我們怎么區(qū)分某個字節(jié)代表一個單獨的字符還是代表某個字符的一部分呢?別忘了 ASCII 字符集只收錄128個字符,使用0~127就可以表示全部字符,所以如果某個字節(jié)是在0~127之內的,就意味著一個字節(jié)代表一個單獨的字符,否則就是兩個字節(jié)代表一個單獨的字符。
GBK 字符集
GBK 字符集只是在收錄字符范圍上對 GB2312 字符集作了擴充,編碼方式上兼容 GB2312 。
utf8 字符集
收錄地球上能想到的所有字符,而且還在不斷擴充。這種字符集兼容 ASCII 字符集,采用變長編碼方式,編碼一個字符需要使用1~4個字節(jié),比方說這樣:
小貼士: 其實準確的說,utf8只是Unicode字符集的一種編碼方案,Unicode字符集可以采用utf8、
utf16、utf32這幾種編碼方案,utf8使用1~4個字節(jié)編碼一個字符,utf16使用2個或4個字節(jié)編碼一個字符,utf32使用4個字節(jié)編碼一個字符。更詳細的Unicode和其編碼方案的知識不是本書的重點,大家上網查查哈~ MySQL中并不區(qū)分字符集和編碼方案的概念,所以后邊嘮叨的時候把utf8、utf16、utf32 都當作一種字符集對待。
對于同一個字符,不同字符集也可能有不同的編碼方式。比如對于漢字 '我' 來說, ASCII 字符集中根本沒有收錄這個字符, utf8 和 gb2312 字符集對漢字 我 的編碼方式如下:
我們上邊說 utf8 字符集表示一個字符需要使用1~4個字節(jié),但是我們常用的一些字符使用1~3個字節(jié)就可以表示了。而在 MySQL 中字符集表示一個字符所用最大字節(jié)長度在某些方面會影響系統(tǒng)的存儲和性能,所以設計 MySQL的大叔偷偷的定義了兩個概念:
有一點需要大家十分的注意,在 MySQL 中 utf8 是 utf8mb3 的別名,所以之后在 MySQL 中提到 utf8 就意味著使用1~3個字節(jié)來表示一個字符,如果大家有使用4字節(jié)編碼一個字符的情況,比如存儲一些emoji表情啥的,那請使用 utf8mb4 。
MySQL 支持好多好多種字符集,查看當前 MySQL 中支持的字符集可以用下邊這個語句:
show charset;
數據的DML操作:添加數據,修改數據,刪除數據
格式: insert into 表名[(字段列表)] values(值列表...);
--標準添加(指定所有字段,給定所有的值)
mysql> insert into stu(id,name,age,sex,classid) values(1,'zhangsan',20,'m','lamp138');
Query OK, 1 row affected (0.13 sec)
--指定部分字段添加值
mysql> insert into stu(name,classid) value('lisi','lamp138');
Query OK, 1 row affected (0.11 sec)
-- 不指定字段添加值
mysql> insert into stu value(null,'wangwu',21,'w','lamp138');
Query OK, 1 row affected (0.22 sec)
-- 批量添加值
mysql> insert into stu values
-> (null,'zhaoliu',25,'w','lamp94'),
-> (null,'uu01',26,'m','lamp94'),
-> (null,'uu02',28,'w','lamp92'),
-> (null,'qq02',24,'m','lamp92'),
-> (null,'uu03',32,'m','lamp138'),
-> (null,'qq03',23,'w','lamp94'),
-> (null,'aa',19,'m','lamp138');
Query OK, 7 rows affected (0.27 sec)
Records: 7 Duplicates: 0 Warnings: 0
格式:update 表名 set 字段1=值1,字段2=值2,字段n=值n... where 條件
-- 將id為11的age改為35,sex改為m值
mysql> update stu set age=35,sex='m' where id=11;
Query OK, 1 row affected (0.16 sec)
Rows matched: 1 Changed: 1 Warnings: 0
-- 將id值為12和14的數據值sex改為m,classid改為lamp92
mysql> update stu set sex='m',classid='lamp92' where id=12 or id=14 --等價于下面
mysql> update stu set sex='m',classid='lamp92' where id in(12,14);
Query OK, 2 rows affected (0.09 sec)
Rows matched: 2 Changed: 2 Warnings: 0
格式:delete from 表名 [where 條件]
-- 刪除stu表中id值為100的數據
mysql> delete from stu where id=100;
Query OK, 0 rows affected (0.00 sec)
-- 刪除stu表中id值為20到30的數據
mysql> delete from stu where id>=20 and id<=30;
Query OK, 0 rows affected (0.00 sec)
-- 刪除stu表中id值為20到30的數據(等級于上面寫法)
mysql> delete from stu where id between 20 and 30;
Query OK, 0 rows affected (0.00 sec)
-- 刪除stu表中id值大于200的數據
mysql> delete from stu where id>200;
Query OK, 0 rows affected (0.00 sec)
語法格式:
select 字段列表|* from 表名
[where 搜索條件]
[group by 分組字段 [having 分組條件]]
[order by 排序字段 排序規(guī)則]
[limit 分頁參數]
# 查詢表中所有列 所有數據
select * from users;
# 指定字段列表進行查詢
select id,name,phone from users;
可以在where子句中指定任何條件
可以使用 and 或者 or 指定一個或多個條件
where條件也可以運用在update和delete語句的后面
where子句類似程序語言中if條件,根據mysql表中的字段值來進行數據的過濾
示例:
-- 查詢users表中 age > 22的數據
select * from users where age > 22;
-- 查詢 users 表中 name=某個條件值 的數據
select * from users where name = '王五';
-- 查詢 users 表中 年齡在22到25之間的數據
select * from users where age >= 22 and age <= 25;
select * from users where age between 22 and 25;
-- 查詢 users 表中 年齡不在22到25之間的數據
select * from users where age < 22 or age > 25;
select * from users where age not between 22 and 25;
-- 查詢 users 表中 年齡在22到25之間的女生信息
select * from users where age >= 22 and age <= 25 and sex = '女';
and和or 使用時注意
假設要求 查詢 users 表中 年齡為22或者25 的女生信息
select * from users where age=22 or age = 25 and sex = '女';
思考上面的語句能否返回符合條件的數據?
實際查詢結果并不符合要求?
select * from users where age=22 or age = 25 and sex = '女';
+------+--------+------+-------+-------+------+------+
| id | name | age | phone | email | sex | mm |
+------+--------+------+-------+-------+------+------+
| 1 | 章三 | 22 | | NULL | 男 | 0 |
| 1002 | cc | 25 | 123 | NULL | 女 | NULL |
+------+--------+------+-------+-------+------+------+
2 rows in set (0.00 sec)
-- 上面的查詢結果并不符合 查詢條件的要求。
-- 問題出在 sql 計算的順序上,sql會優(yōu)先處理and條件,所以上面的sql語句就變成了
-- 查詢變成了為年齡22的不管性別,或者年齡為 25的女生
-- 如何改造sql符合我們的查詢條件呢?
-- 使用小括號來關聯(lián)相同的條件
select * from users where (age=22 or age = 25) and sex = '女';
+------+------+------+-------+-------+------+------+
| id | name | age | phone | email | sex | mm |
+------+------+------+-------+-------+------+------+
| 1002 | cc | 25 | 123 | NULL | 女 | NULL |
+------+------+------+-------+-------+------+------+
1 row in set (0.00 sec)
我們可以在where條件中使用=,<,> 等符合進行條件的過濾,但是當想查詢某個字段是否包含時如何過濾?
可以使用like語句進行某個字段的模糊搜索,
例如: 查詢 name字段中包含五的數據
-- like 語句 like某個確定的值 和。where name = '王五' 是一樣
select * from users where name like '王五';
+----+--------+------+-------+-----------+------+------+
| id | name | age | phone | email | sex | mm |
+----+--------+------+-------+-----------+------+------+
| 5 | 王五 | 24 | 10011 | ww@qq.com | 男 | 0 |
+----+--------+------+-------+-----------+------+------+
1 row in set (0.00 sec)
-- 使用 % 模糊搜索。%代表任意個任意字符
-- 查詢name字段中包含五的
select * from users where name like '%五%';
-- 查詢name字段中最后一個字符 為 五的
select * from users where name like '%五';
-- 查詢name字段中第一個字符 為 王 的
select * from users where name like '王%';
-- 使用 _ 單個的下劃線。表示一個任意字符,使用和%類似
-- 查詢表中 name 字段為兩個字符的數據
select * from users where name like '__';
-- 查詢 name 字段最后為五,的兩個字符的數據
select * from users where name like '_五';
注意:where子句中的like在使用%或者_進行模糊搜索時,效率不高,使用時注意:
盡可能的不去使用%或者_
如果需要使用,也盡可能不要把通配符放在開頭處
Mysql中的統(tǒng)計函數(聚合函數)
max(),min(),count(),sum(),avg()
# 計算 users 表中 最大年齡,最小年齡,年齡和及平均年齡
select max(age),min(age),sum(age),avg(age) from users;
+----------+----------+----------+----------+
| max(age) | min(age) | sum(age) | avg(age) |
+----------+----------+----------+----------+
| 28 | 20 | 202 | 22.4444 |
+----------+----------+----------+----------+
-- 上面數據中的列都是在查詢時使用的函數名,不方便閱讀和后期的調用,可以通過別名方式 美化
select max(age) as max_age,
min(age) min_age,sum(age) as sum_age,
avg(age) as avg_age
from users;
+---------+---------+---------+---------+
| max_age | min_age | sum_age | avg_age |
+---------+---------+---------+---------+
| 28 | 20 | 202 | 22.4444 |
+---------+---------+---------+---------+
-- 統(tǒng)計 users 表中的數據量
select count(*) from users;
+----------+
| count(*) |
+----------+
| 9 |
+----------+
select count(id) from users;
+-----------+
| count(id) |
+-----------+
| 9 |
+-----------+
-- 上面的兩個統(tǒng)計,分別使用了 count(*) 和 count(id),結果目前都一樣,有什么區(qū)別?
-- count(*) 是按照 users表中所有的列進行數據的統(tǒng)計,只要其中一列上有數據,就可以計算
-- count(id) 是按照指定的 id 字段進行統(tǒng)計,也可以使用別的字段進行統(tǒng)計,
-- 但是注意,如果指定的列上出現(xiàn)了NULL值,那么為NULL的這個數據不會被統(tǒng)計
-- 假設有下面這樣的一張表需要統(tǒng)計
+------+-----------+------+--------+-----------+------+------+
| id | name | age | phone | email | sex | mm |
+------+-----------+------+--------+-----------+------+------+
| 1 | 章三 | 22 | | NULL | 男 | 0 |
| 2 | 李四 | 20 | | NULL | 女 | 0 |
| 5 | 王五 | 24 | 10011 | ww@qq.com | 男 | 0 |
| 1000 | aa | 20 | 123 | NULL | 女 | NULL |
| 1001 | bb | 20 | 123456 | NULL | 女 | NULL |
| 1002 | cc | 25 | 123 | NULL | 女 | NULL |
| 1003 | dd | 20 | 456 | NULL | 女 | NULL |
| 1004 | ff | 28 | 789 | NULL | 男 | NULL |
| 1005 | 王五六 | 23 | 890 | NULL | NULL | NULL |
+------+-----------+------+--------+-----------+------+------+
9 rows in set (0.00 sec)
-- 如果按照sex這一列進行統(tǒng)計,結果就是8個而不是9個,因為sex這一列中有NULL值存在
mysql> select count(sex) from users;
+------------+
| count(sex) |
+------------+
| 8 |
+------------+
聚合函數除了以上簡單的使用意外,通常情況下都是配合著分組進行數據的統(tǒng)計和計算
group by 語句根據一個或多個列對結果集進行分組
一般情況下,是用與數據的統(tǒng)計或計算,配合聚合函數使用
-- 統(tǒng)計 users 表中 男女生人數
-- 很明顯按照上面的需要,可以寫出兩個語句進行分別統(tǒng)計
select count(*) from users where sex = '女';
select count(*) from users where sex = '男';
-- 可以使用分組進行統(tǒng)計,更方便
select sex,count(*) from users group by sex;
+------+----------+
| sex | count(*) |
+------+----------+
| 男 | 4 |
| 女 | 5 |
+------+----------+
-- 統(tǒng)計1班和2班的人數
select classid,count(*) from users group by classid;
+---------+----------+
| classid | count(*) |
+---------+----------+
| 1 | 5 |
| 2 | 4 |
+---------+----------+
-- 分別統(tǒng)計每個班級的男女生人數
select classid,sex,count(*) as num from users group by classid,sex;
+---------+------+-----+
| classid | sex | num |
+---------+------+-----+
| 1 | 男 | 2 |
| 1 | 女 | 3 |
| 2 | 男 | 2 |
| 2 | 女 | 2 |
+---------+------+-----+
# 注意,在使用。group by分組時,一般除了聚合函數,其它在select后面出現(xiàn)的字段列都需要出現(xiàn)在grouop by 后面
having時在分組聚合計算后,對結果再一次進行過濾,類似于where,
where過濾的是行數據,having過濾的是分組數據
-- 要統(tǒng)計班級人數
select classid,count(*) from users group by classid;
-- 統(tǒng)計班級人數,并且要人數達到5人及以上
select classid,count(*) as num from users group by classid having num >=5;
我們在mysql中使用select的語句查詢的數據結果是根據數據在底層文件的結構來排序的,
首先不要依賴默認的排序,另外在需要排序時要使用orderby對返回的結果進行排序
Asc 升序,默認
desc降序
-- 按照年齡對結果進行排序,從大到小
select * from users order by age desc;
-- 從小到大排序 asc 默認就是。可以不寫
select * from users order by age;
-- 也可以按照多個字段進行排序
select * from users order by age,id; # 先按照age進行排序,age相同情況下,按照id進行排序
select * from users order by age,id desc;
limit n 提取n條數據,
limit m,n 跳過m跳數據,提取n條數據
-- 查詢users表中的數據,只要3條
select * from users limit 3;
-- 跳過前4條數據,再取3條數據
select * from users limit 4,3;
-- limit一般應用在數據分頁上面
-- 例如每頁顯示10條數據,第三頁的 limit應該怎么寫? 思考
第一頁 limit 0,10
第二頁 limit 10,10
第三頁 limit 20,10
第四頁 limit 30,10
-- 提取 user表中 年齡最大的三個用戶數據 怎么查詢?
select * from users order by age desc limit 3;
# 不要進入mysql,然后輸入以下命令 導出某個庫中的數據
mysqldump -u root -p tlxy > ~/Desktop/code/tlxy.sql
導出一個庫中所有數據,會形成一個建表和添加語句組成的sql文件之后可以用這個sql文件到別的庫,或著本機中創(chuàng)建或回復這些數據
# 不要進入mysql,然后輸入以下命令 導出某個庫中指定的表的數據
mysqldump -u root -p tlxy tts > ~/Desktop/code/tlxy-tts.sql
# 在新的數據庫中 導入備份的數據,導入導出的sql文件
mysql -u root -p ops < ./tlxy.sql
mysql -u root -p ops < ./tlxy-tts.sql
mysql中的root用戶是數據庫中權限最高的用戶,千萬不要用在項目中。
可以給不同的用戶,或者項目,創(chuàng)建不同的mysql用戶,并適當的授權,完成數據庫的相關操作。這樣就一定程度上保證了數據庫的安全。
grant 授權的操作 on 授權的庫.授權的表 to 賬戶@登錄地址 identified by '密碼’;
示例:
# 在mysql中 創(chuàng)建一個 zhangsan 用戶,授權可以對tlxy這個庫中的所有表 進行 添加和查詢 的權限
grant select,insert on tlxy.* to zhangsan@'%' identified by '123456';
# 用戶 lisi。密碼 123456 可以對tlxy庫中的所有表有 所有操作權限
grant all on tlxy.* to lisi@'%' identified by '123456';
drop user 'lisi'@'%';