mysql
優化數據庫設計
第一范式(1st NF)
-
第一范式的目標是確保每列的原子性
定義:數據庫表中的所有字段都是單一屬性,不可再分的。這個單一屬性是由基本的數據類型所構成的,如整數,浮點數,字符串,等;
換句話說 第一范式要求數據庫中的表都是二維表。
如果每列都是不可再分的最小數據單元(也稱為最小的原子單元),則滿足第一范式(1 NF);
第二范式(2nd NF)
- 第二范式要求每個表只描述一件事情;
- 定義:數據庫的表中不存在非關鍵字段對任一候選關鍵字段的部分函數依賴。
- 部分函數依賴是指存在著組合關鍵字中的某一關鍵字決定非關鍵字的情況。
- 換句話說:所有單關鍵字段的表都符合第二范式。
第三范式(3nd NF)
- 如果一個關系滿足2NF,并且除了主鍵以外的其他列都不傳遞依賴于主鍵列,則滿足第三范式(3 NF);
- 定義:第三范式是在第二范式的基礎之上定義的,如果數據表中不存在非關鍵字段對任意候選關鍵字段的傳遞函數則符合第三范式。
1.什么是數據庫?
- 數據庫(database,簡稱DB):是按照數據結構來組織,存儲和管理數據的倉庫。
- 數據庫管理系統(Databse Management System,DBMS):是指數據庫系統中對數據進行管理的軟件系統。
2.什么是MySQL?
MySQL一個開源的關系型數據庫管理系統
-
MySQL由瑞典MySQL AB公司開發
目前屬于Oracle旗下產品
SQL語言是用于訪問數據庫的最常用的標準化語言
3.MySQL常用命令
-
mysqladmin命令用于修改用戶密碼
命令格式:
mysqladmin命令格式:
mysqladmin -u用戶名 -p舊密碼 password
輸入新密碼:
確認新密碼:
show databases; 命令用于顯示所有數據庫
use 數據庫名;使用某個數據庫(或切換到某個數據庫)
-
select命令:
此命令用于顯示當前連接(選擇)的信息
select database(); 顯示當前連接的數據庫
select version(); 顯示當前服務器版本
select now(); 顯示當前日期時間
select user(); 顯示當前用戶
4.操作數據庫
-
創建數據庫是在系統磁盤上劃分一塊區域用于數據的存儲和管理
創建數據庫的語法格式:
create database 數據庫名
create database if not exists test02 character set utf8; 判斷數據庫是否存在并創建默認編碼字符
create datebase dbname charset=utf8; 創建數據庫并創建默認編碼字符
-
修改數據庫
修改數據庫的編碼格式:
alter database test02 character set gb2312;
顯示數據庫的編碼格式:
show variables like 'character%';
刪除數據庫:
drop database test02;
5.mysql的數據類型
- 數據類型是指數據列,存儲過程參數,表達式和局部變量的數據特征,他決定了數據的存儲格式,代表了不同的信息類型。
-
整型
數據類型 存儲范圍 字節 tinyint 有符號值:-128到127(-27到27-1) 無符號值:0到255(0到2^8-1) 1 smallint 有符號值:-32768到32767(-215到215-1) 無符號值:0到65535(0到2^16-1) 2 mediumint 有符號值:-8388608到8388607(-223到223-1) 無符號值:0到16777215(0到2^24-1) 3 int 有符號值:-2147483648到2147483647(-231到231-1) 無符號值:0到4294967295(0到2^32-1) 4 bigint 有符號值:-9223372036854775808到9223372036854775807(-263到263-1) 無符號值:0到18446744073709551615(0到2^64-1) 8 -
浮點數類型和定點數類型(表示小數)
數據類型 存儲范圍 浮點數類型 float[(m,d)] double[(m,d)] 4個字節存儲 范圍:-3.402823466E+38到3.402823466E+38 8個字節存儲 范圍:-1.797931348623157E+308 到 1.797931348623157E+308 定點數類型 decimal[(m,d)] m是精度 (=整數位數+小數位數),是標度(小數點后的位數) -
日期時間型
列類型 字節數 取值范圍 表示形式 year 1 1901~2155 YYYY time 3 -838:59:59~838:59:59 HH:MM:SS date 4 1000-01-01~9999-12-31 YYYY-MM-DD datetime 8 1000-01-01 00:00:00~9999-12-3123:59:59 YYYY-MM-DD HH:MM:SS timestamp 4 1970010108001~20380119111407 YYYY-MM-DD HH:MM:SS -
字符型(字符串類型用來存儲字符串數據,除了可以存儲字符串數據之外,還可以存儲其它數據,比如圖片和聲音的二進制數據)
列類型 存儲需求 char(m) m個字節,0<=m<=255 varchar(m) l+1個字節,其中l<=m且0<=m<=65535 tinytext 0~255 (2^8-1) text 0~65535(2^16-1) mediumtext 0~2^24-1 longtext 0~2^32-1 enum('value1','value2',……) 取決于枚舉的個數(最多65535個值) set('value1','value2',……) 取決于set成員的數目(最多64個成員)
數據庫表
-
數據庫最重要的組成部分之一,是其它對象的基礎。
行(記錄) 列(字段)
創建數據庫表
-
create table<表名>
(
? 列名1 數據類型【列級別約束條件】【默認值】
? 列名2 數據類型【列級別約束條件】【默認值】
? ……
? 【表級別約束條件】
);
-
查看數據庫表
- 查看數據表列表
- show tables [from 數據庫名];查看當前庫下的表時[ ]這部分可以省略
-
查看數據表基本結構
- show columns from 表名;
- describe 表名/desc 表名;
-
查看表詳細結構語句
- show create table 表名;
修改數據庫表
-
在已經存在的表添加新的列
alter table 表名 add 新列名 數據類型 [約束條件] 【first | after 已存在列名】;// [ ]為可選項
-
修改表列名的命令
alter table表名 change 舊列名 新列名 新數據類型
-
修改列的數據類型
alter table 表名 modify 列名 數據類型 //modify修改的意思
-
修改列的排列位置
alter table 表名 modify 列 1 數據類型 first | after 列2;
-
刪除列
alter table 表名 drop 列名;
-
修改表名
alter table 舊表名 rename 【to】新表名
刪除數據庫表
- drop table [if exists] 表1,表2,表3,……表n; //添加括號內容不會報錯(將錯誤信息隱藏)
表分區
當我們創建的表,需要承載的數據量很大的時候,就要注意他的性能問題,比如圖書信息表,有1000萬個圖書信息,那么我們就得考慮如何優化他,其中一種方式就是表分區。
表分區就是把一張表的數據分成多個區塊,這些區塊可以在同一個磁盤上,也可以在不同的磁盤上,但所有的數據還在一個表中。
-
不過使用表分區有個前提就是你的數據庫必須支持。執行下面命令查看是否支持
show plugins;
顯示 partition |active|storage engine | null |gpl | //為支持
-
表分區方式
-
水平分區
將表的數據按行分割成不同的數據文件
-
垂直分區
將表的數據按列分割成不同的數據文件
-
MySQL約束
約束是一種限制,它通過對表的行或列的數據做出限制,來確保表的數據的完整性,唯一性。
-
常用的幾種約束類型
約束類型 非空約束 主鍵約束 唯一約束 默認約束 外鍵約束 關鍵字 not null primary key unique default foreign key not null:這一列不能為空;
值 說明 null 字段值可以為空 not null 字段值禁止為空 - 非空約束(not null constraint)指字段的值不能為空。對于使用了非空約束的字段如果用戶在添加數據時,沒有指定值,數據庫系統會報錯。
- 語法:列名 數據類型 not null
- 添加非空約束:alter table 表名 modify 字段名 數據類型 not null;
- 刪除非空約束:alter table 表名 modify 字段名 數據類型;
primary key:用于約束表當中的一行,通過主鍵約束定位到表中的一行;
- 要求主鍵列的數據唯一,并且不允許為空,主鍵能夠唯一地標識表中的一條記錄。
- 一張表中最多只能擁有一個主鍵列
類型 說明 單字段主鍵 由一個字段列組成 1.在定義列的同時指定主鍵(列名 數據類型 primary key); 2.在列定義的后邊指定主鍵([constrant <約束名>])primary key(列名); 多字段聯合主鍵 主鍵由多個字段(列)聯合組成 primary key(字段1,字段2,……字段n) create table borrowinfo( book_id int,card_id char(18),primary key(book_id,card_id)); - 通過修改表為列添加主鍵
- alter table bookinfo modfiy book_id int primary key;
- alter table bookinfo add primary key(book_id);
- alter table bookinfo add constarint pk_id primary key(book_id);
- 刪除主鍵
- alter table bookinfo drop primary key;
unique:一張表中指定一列的值不能有重復且唯一;
- 要求該列唯一,允許為空,可以確保一列或者幾列不出現重復值
- 語法規則:
- 列名 數據類型 unique;
- 定義完所有列后
- 【constraint <約束名>】unique(列名);
- 修改表時添加唯一約束
- 與主鍵類似
- 刪除表的唯一約束
- alter table bookinfo drop index book_name;
- alter table bookinfo drop key book_name;
default:插入數據時如果沒有明確為字段賦值,就會自動賦予默認值;
- 指定某列的默認值
- 語法規則:
- 列名 數據類型 default 默認值
- 修改表時添加默認約束
- alter table bookinfo modify book_name varchar(20) default '機械工業出版社';
- alter table bookinfo alter column book_name set default '機械工業出版社';
- 刪除默認約束
- altre table bookinfo modify book_name varchar(20);
- alter table bookinfo alter column book_name drop default;
foreign key:兩個表的數據之間建立連接,通過外鍵約束可以保證數據的完整性和一致性;
- 用來在兩個表的數據之間建立連接,它可以是一列或者多列。一個表可以有一個多個外鍵;
- 外鍵對應的是參照完整性,一個表的外鍵可以為空值,若不為空值,則每一外鍵必須等于另一個表中主鍵的某個值。
- 外鍵的作用是保持數據的一致性,完整性;
- 語法格式:
- [constraint<外鍵約束名>] foreign key(列名) references<主表名>(主鍵)
約束區別
- 唯一約束與主鍵約束的區別
- 一個表中可以有多個unique聲明,但只能有一個primary key聲明;
- 聲明primary key的列不允許有空值;
- unique的列允許空值
插入數據
- 在使用數據庫之前,數據庫表中必須有數據,我們需要使用insert語句向數據庫表中插入數據。
-
為表的所有列插入數據:
- 語法格式:
- insert into table_name(column_list) values(value_list);
- insert into table_name values(value_list); //插入順序需要跟字段順序對應
-
為表的指定列插入數據:
- 為表的指定列插入數據,就是在insert語句中只向部分列中插入值,而其他沒有指定值的列所插入的數據為表定義時的默認值。
- 語法格式:
- insert into table_name(column_list//部分字段) values(value_list);
-
同時插入多條記錄:
- 語法格式:
- nsert into table_name(column_list) values (value_list1), (value_list2), (value_list3)…… (value_listn);
-
將查詢結果插入到表中
- insert可以將select語句查詢的結果插入到表中。
- 語法格式:
- insert into table_name1(column_list1) select(column_list2) from table_name2 where (condition);
設置自動編號
-
設置表的屬性值自動增加
語法格式:
列名 數據類型 auto_increment;
注意:auto_increment約束的字段可以是任何整數類型(tinyint,smallint,int等)
自增列的初始值默認是1,每添加一條記錄,自動增長1。在建表時可用‘auto_increment=n’選項來指定一個自增的初始值。(默認為1)
-
create table table_name(
? id int primary key auto_increment,
? name varchar(10) not nul,
? ) auto_increment=5;
-
為已有的表添加自增列
- 修改表的方式
- alter table table_name modfiy 字段名 數據類型 auto_increment;
-
修改自增列的起始值
- alter table table_name auto_increment=x;
- 修改后auto_increment列起始值從x開始;
-
去掉字增列
- alter table table_name modfiy 字段名 數據類型 ;
單表數據記錄的更新
mysql中使用update語句更新表中的記錄
更新特定的行
-
更新所有的行
-
語法格式
update table_name set column_name1=value1,column_name2=value2,column_name3=value3,column_namen=valuen where (condition);
//不加where條件會更新所有的行
-
單表記錄的刪除
- 使用delete語句刪除滿足條件的記錄,語法格式如下:
- delete from table_name [where <condition>];
- 如果想刪除表中的所有記錄,還可以使用truncate table語句,truncate將直接刪除原來的表,并重新創建一個表,其語法結構為:
- TRUNCATE TABLE_NAME table_name;
單表記錄的查詢
mysql從數據表中查詢數據的基本語句為select語句。
-
語法結構:
SELECT select_expr【,select_expr……】
【
? FROM table_references
? 【WHERE where_condition】
? 【GROUP BY {col_name|position} 【ASC|DESC】,……】
? 【HAVING where_condition】
? 【ORDER BY {col_name|expr|position} 【ASC|DESC】,……】
? 【LIMIT {【offset,】row_count|row_count OFFSET offset}】
】
在select語句中使用星號‘*’通配符查詢所有列
如:select * from bookcategory;
指定所有列
如:select category_id, category, parent_id from bookcategory;
查詢單個列
如:select category from bookcategory;
查詢多個列
如:select category_id, category from bookcategory;
-
通過where子句,對數據進行過濾,語法格式為:
select 列名1,列名2,……列名n
from 表名
where 查詢條件
select book_id,book_name,price from bookinfo where press ='機械工業出版社';
-
使用distinct關鍵字指示mysql消除重復的記錄值
select distinct 列名 from 表名;
如:select disyinct press from bookinfo;
使用is null子句,可以查詢某列內容為空記錄。
如:select * from readerinfo where age is null;
分組查詢
- 分組查詢是對數據按照某個或多個列進行分組
- 【group by 列名】【having<條件表達式>】
創建分組
查詢結果分組
group by 列名
group 不要通常和聚合函數一起使用,例如:max(), min(), sum(), avg(), count()
-
例:
select count(*) from readerinfo where sex='男';
select sex ,count(*) from readerinfo group by sex;
[having <條件表達式>]
having限定顯示記錄所需滿足的條件,只有滿足條件的分組才會被顯示。
-
例:
select sex from readerinfo group by sex having count(sex)>2;
排序
- 對查詢結果進行排序
- mysql中可以通過order by子句對查詢的結果進行排序
- order by 列名 [ASC|DESC]
- 單列排序
- 按照指定的某個列進行排序,默認升序。
- select * from bookinfo order by price;
- 多列排序
- 按照多個列進行排序,默認升序
- select * from bookinfo order by price,store;
- 指定排序方向
- 排序分為升序和降序,默認升序。
- 升序ASC
- 降序DESC
- select * from bookinfo order by price ASC,store DESC;
- 單列排序
限制查詢
-
通過limit語句限制查詢記錄的數量
limit關鍵字可以返回指定位置的記錄
limit [位置偏移量,] 行數
說明:第一條記錄的位置偏移量為0,第二條為1,……以此類推。
-
顯示圖書信息表的前3行記錄
select * from bookinfo limit 3;
-
顯示從第3條記錄開始后的2條圖書信息記錄
select * from bookinfo limit 2,2;
說明:mysql5.7中也可以使用limit 2 offset 2,實現例2相同的效果。
Mysql中的額運算符
-
熟悉mysql中常用運算符的使用
運算符是告訴mysql執行特定算術或邏輯操作的符號,運算符連接表達式中各個操作數,其作用是用來指明對操作數所進行的運算。
-
常用的運算符
算術運算符
-
用于各類數值運算
運算符 作用 + 加法 - 減法 * 乘法 / 除法 % 求余(取模)
比較運算符
運算符 作用 >,< 大于,小于 >=,<= 大于等于,小于等于 = 等于 <>(!=) 不等于 is(not) null 判斷一個值是否為空(或不為空) between……and 判斷一個值是否在兩個值之間 (not)in 判斷一個值是(或不是)in列表中的值 like 通配符匹配 邏輯運算符
-
運算符 | 作用 |
---|---|
AND | 邏輯與 |
OR | 邏輯或 |
NOT | 邏輯非 |
mysql數值函數
函數
- 函數表示對輸入參數值返回一個具有特定關系的值,mysql提供了大量豐富的函數,在進行數據庫管理以及數據的查詢和操作時會經常用到各種函數。通過對數據的處理,數據庫功能可以變得更加強大,更加靈活的滿足不同用戶的需求。
- 常用函數
-
數值函數(數學函數)
-
主要是用來處理數值數據的。
獲取整數的函數
-
CEIL(x):向上取整
select ceil(28.55) 結果:29
-
floor(x):向下取整
select floor(28.55) 結果:28
-
round(x) :返回最接近于參數x的整數,對參數x進行四舍五入
select round(28.55) 結果:29
-
round(x,y):返回最接近于參數x的數,其值保留到小數點后面的y位,若y為負值,則將保留x值到小數點左邊y位
select round(28.55,1), round(28.55,0), round(28.55,-1);
結果:28.6 29 30
-
截斷函數 truncate(x,y)返回被舍去至小數點后y位的數字x.若y的值為0,則結果為整數,若y的值為負數,則截去x小數點左起第y位開始后面所有低位的值
select truncate(28.55,1), truncate(28.55,0), truncate(28.55,-1);
結果: 28.5 28 20
-
取模(求余)
-
mod(x,y)返回x被y除后的余數
select mod(11,2); 結果:1
-
-
-
字符函數
-
用來處理數據庫中字符串數據
-
字符串連接函數
concat(s1,s2,...)返回結果為連接參數產生的字符串,如果任何一個參數為null,則返回值為null
select concat('hello','world'); 結果:helloworld
-
concat_ws(x,s1,s2,...),第一個參數x是其它參數的分隔符,分隔符的位置放在要連接的兩個字符串之間,分隔符可以是一個字符串,也可以是其它參數,如果分隔符為null,則結果為null。
select concat_ws('-','hello','word'); 結果為:hello-word
-
字母轉換大小寫函數
-
lower(str)可以將字符串str中的字母字符全部轉換成小寫字母
select lower('Hello Word'); 結果:hello word
-
upper(str)可以將字符串str中的字母字符串全部換成大寫字母。
select upper('Hello Word'); 結果:HELLO WORLD
-
-
求字符長度的函數
-
length(str)返回值為字符串的字節長度
select length(' hello '); 結果:7
-
-
刪除空格的函數
- ltrim(s)返回字符串s,字符左側空格字符被刪除
- rtrim(s)返回字符串s,字符右側空格字符被刪除
- trim(s):刪除字符串兩側的空格
-
截取字符串
substring(s,n,len)帶有len參數的格式,從字符串s返回一個長度同len字符相同的子字符串,起始于位置n。n如果是負數,則子字符串的位置起始于字符串結尾的n個字符。
select substring('hello,world',1,5); 結果:hello
select substring('hello world',-3,2); 結果:rl
-
獲取指定長度的字符串函數
-
left(s,n)返回字符串s開始的最左邊n個字符
select left('hello world',5); 結果:hello
-
right(s,n)返回字符串中最右邊n個字符
select right('hello world',5); 結果:world
-
-
替換函數
-
replace(str,from_str,to_str)在字符串str中所有出現的字符串from_str均被yo_str替換,然后返回這個字符串。
select replace('hello world','world','mysql'); 結果:hello mysql
-
-
格式化函數
-
format(x,n)將數字x格式化,并以四舍五入的方式保留小數點后n為,結果以字符串的形式返回。若n為0,則返回結果不含小數部分。
select format(1234.5678,2), format(1234.5,2),format(1234.5678,0);
結果:1234.57 1234.50 1235
-
-
-
-
日期時間函數
- 日期和時間函數主要是用來處理日期和時間值
- 獲取當前日期的函數
- curdate()和current_date()函數作用相同,將當前日期按照‘YYY-MM-DD’或‘YYYMMDD’格式的值返回,具體格式根據函數在字符串或是數字語境中而定。
- select curdate(); 結果為:2018-05-16
- select curdate()+0; 結果為:20180516
- 獲取當前時間的函數
- curtime()和current_time()函數作用相同,將當前時間按照‘HH:MM:SS’或‘HHMMSS’格式的值返回,具體格式根據函數在字符串或是數字語境中而定。
- select curdate(); 結果為:15:03:28
- select curdate()+0; 結果為:150328
- 獲取當前的日期和時間
- now()和sysdate()函數作用相同,均返回當前的日期時間值。格式為‘YYY-MM-DD HH:MM:SS’或‘YYYMMDDHHMMSS’格式的值返回,具體格式根據函數在字符串或是數字語境中而定。
- select now(); 結果為:2018-05-16 15:12:57
- select now()+0; 結果為:20180516151257
- 執行日期的加運算
- date_add(date,interval expr type)其中,date是一個DATETIME或DATE值,用來指定起始時間。expr是一個表達式,用來指定從起始時間添加或減去的時間間隔值。type為關鍵詞,它指示了表達式被解釋的方式,如:YEAR,MONTH,DAY,WEEK,HOUR等。
- select date_add('2018-05-19',interval 3 month); 結果為:2018-08-19
- 計算兩個日期之間的間隔天數
- datediff(date1,date2)返回起始時間date1和結束時間date2之間的天數。
- select datediff('2018-06-1','2018-05-1'); 結果為:31
- 日期的格式化
- date_format(date,format)根據format指定的格式顯示date值。
- date_format時間日期格式:
- %b:月份的縮寫名稱(Jan...Dec)
- %c:月份,數字形式(0...12)
- %m:月份,數字形式(00...12)
- %M:月份名稱(January..December)
- %d:該月日期,數字形式(00...31)
- %e:該月日期,數字形式(0...31)
- %Y:4位數形式表示年份
- %y:2位數形式表示年份
-
聚合函數(分組函數)
- 有時候并不需要返回實際表中的數據,而只是對獲取的數據進行分析和總結。這時候就需要使用聚合函數。
名稱 描述 AVG() 返回某列的平均值 COUNT() 返回某列的行數 MAX() 返回某列的最大值 MIN() 返回某列的最小值 SUM() 返回某列值的和 -
信息函數
- VERSION():返回當前MySQL服務器版本的版本號。
- CONNECTION_ID():返回MySQL服務器當前連接的次數,每個連接都有各自唯一的ID。
- DATABASE()和SCHEMA():返回當前的數據庫名
- USER():獲取用戶名的函數,返回當前登錄 的用戶名稱
-
加密函數
- 加密函數主要用來對數據進行加密和界面處理,以保證某些重要數據不被別人獲取
- MD5():信息摘要算法(不可逆)
- MD5(str)函數可以加密字符串,加密后的值以32位十六進制數字的二進制字符串形式返回,若參數為NULL,則返回NULL。
- PASSWORD():密碼算法
- PASSWORD(str)從原明文密碼str計算并返回加密后的密碼字符串,當參數為NULL時,返回NULL。
-