mysql学习笔记整理
作者:Poetry 轉自:http://blog.poetries.top/2016/05/26/mysql%E7%AC%94%E8%AE%B0%E6%95%B4%E7%90%86/
第一部分:DML--數據庫操作語言
常用表管理語句:
set names gbk;--設置字符編碼
查看所有數據庫:show databases;
查看所有表:show tables
查看表結構:desc 表名/視圖名
use 表名;--選擇表
查看建表過程:show create table 表名
查看建視圖過程:show create view 視圖
查看所有詳細表信息:show table status\G(讓結果顯示好看一些)
查看某張表詳細信息:show table status where name='goods(表名)'\G
刪除表:drop table 表名
刪除視圖:drop view 視圖名;
刪除列:alter table drop column 指定列
改表名:rename table oldName to newName
更新表:update 表名 set 字段
插入數據:insert into 表名 value()
清空數據:truncate 表名;(相當于刪除表在重建)
寫錯語句退出:\c
讓結果顯示好看一些:\G
insert:
insert into 表名 插入列與值要嚴格對應
數字不必加單引號 字符串必須加單引號
例子:insert into test(age,name)values(10,'小明');
update操作:
例子:update user set age=8 where name=lianying;(注意where條件不加會影響所有行,需要小心)
delete操作:
不可能針對某一列刪除 要刪必須一行
delete from 表名 where 添加
delete from user where uid=1;(必須加上添加,否則全部數據刪除)
select查找:
select * from 表名(全部查出)
select uid,name from user where uid>10;
select * from user where uid=11;
select查詢模型(重要):
select * from 表名 where 1(where是一個表達式 為真則取出來 為假不取)
把列看成變量,既然是變量就能參與運,。這個過程稱為廣義投影(比如:取出兩列參與運算) 也可以帶到函數里面計算
查詢練習:
子查詢可以查出一個欄目下所有字欄目的商品
模糊查詢:where 字段 like '%A%' --%代表任意字符 _代表單一字符
注意:NULL:查詢方法: select * from test where name is (not)null
group分組與統計函數:
統計函數:
max()
count()
avg()
min()
sum()
在sql中重復要用的語句:用as名字新變量,以便調用
select goods_id,goods_name,(market_price-shop_price) as save from goods
having -- 對查詢出來的結果集進行篩選
where 不能寫在having后面
order by :(默認升序asc) 降序asc(排序很浪費資源)
select goods_id,goods_name,shop_price from goods order by shop_price desc;
limit用法:(做分頁類能用到)
限制取出條目(limit有兩個參數 :偏移量 取出的條目)
select goods_id,goods_name,shop_price
-> from goods
-> order by shop_price desc
-> limit 0,3;
子句的查詢陷阱:
5種語句有嚴格的順序,where ,group by,having,order by,limit
不能顛倒順序
例子: #語句有嚴格的順序
mysql> select id,sum(num)
-> from
-> (select * from a union select * from b) as temp
-> group by id
-> having sum(num)>10
-> order by sum(num) desc
-> limit 0,1;
子查詢:
where字查詢:(內層的查詢結果作為外層的比較條件)
靜態的:select goods_id,goods_name from goods where goods_id=32;
動態的:select goods_id,goods_name from goods where goods_id=(select max(goods_id) from goods);
#取出每個欄目下最新的商品:
select goods_id,cat_id,goods_name from goods where goods_id in (select max(goods_id) from goods group by cat_id);
from子查詢:
#每個欄目下最新的商品:
mysql> select goods_id,goods_name from (select * from goods where 1 order by cat_id desc) as tmp
-> group by cat_id;
exists子查詢:
#查詢欄目下是否有商品
mysql> select * from category
-> where exists(select * from goods where goods.cat_id=category.cat_id)
內連接查詢(重要):
內連接是左右連接結果的交集
select xxx from
table1 inner jion table2 on table1.xx=table2.xx
mysql> select boy.hid,boy.bname,girl.hid,girl.gname
-> from
-> boy inner join girl on boy.hid=girl.hid;
左連接特點:
以左表的數據為標準,去找右表的數據,查不到的為NULL
#左連接
mysql> select boy.hid,boy.bname,girl.hid,girl.gname
-> from
-> boy left join girl on boy.hid=girl.hid;
#右連接
mysql> select boy.hid,boy.bname,girl.hid,girl.gname
-> from
-> boy right join girl on boy.hid=girl.hid;
mysql> select goods_id,cat_name,goods_name,shop_price
-> from
-> goods left join category on goods.cat_id= category.cat_id
-> where goods.cat_id=4;
union查詢:
把2條或多條的額查詢結果,合并成1個結果集
sql1 N行
sql2 M行
sql1 union sql2,N+M行
union語句必須滿足一個條件:各語句取出的列數要相同
union語句中不用寫order by 因為sql合并后得到總的結果集可以order by 字句order by失去意義
場景:2條語句,各自的where非常復雜,可以簡化成簡單的條件在union
注意:使用union時,完全相等的行將會被合并
合并是比較耗時的操作,一般不讓union合并,使用union all 可以避免合并 對速度有提升
mysql> select * from a
-> union all #union all 可以避免重復語句合并
-> select * from b;
mysql> select goods_id,cat_id,goods_name,shop_price from goods where cat_id=2
-> union
-> select goods_id,cat_id,goods_name,shop_price from goods where cat_id=4;
第二部分:DDL數據庫定義語言(建表)
create table 表名 (
列1 列類型 [列屬性 默認值]
列2 列類型 [列屬性 默認值]
...
);
engine = 存儲引擎
chartset = 字符集
建表過程:聲明表頭的過程,也就是聲明列的過程
選擇合理的列類型 合理的列寬度(即放下內容 又不浪費磁盤空間)
列選什么類型的列 列給什么樣的屬性
數值型--整形,浮點型,定點型
字符串型--char varchar text
日期時間類型--2012-12-13 14.25.36
整形列:
類型: 字節: 最小值: 最大值:
bigint -- 8字節 -9223372036854775808 18446744073709551615
int -- 4字節 --2147483648 4294967295
mediunint -- 3字節 -8388608 8388607
smallint -- 2字節 -32768 32767
tinyint -- 1字節 -128 127
整行列的可選參數:
unsigned 無符號,列的值從0開始不為負
zerofill M(寬度)適合用于 學號 編碼等固定寬度的數字,可以用0填充至固定寬度
學號:1--0001
注意:zerofill屬性默認決定是unsigned
浮點列與定點列:
float(M,D)M是精度總位數 D代表小數點后面的位數
double
float/double 范圍區別和decimal相比:浮點數存儲有精度的損失
decimal 定點型更精確
字符型列:
char(M)--char(10)只能存10個字符
char型:如果不夠M個字符,內部會用空格補齊,取出時在把右側空格刪掉
注意:這意味著 右側本身有空格將會丟失
varchar(M)--用多少占多少--自動擴展
varchar不會丟失空格
速度上:定長char快一些 在一定范圍內用char定長尋址快 速度快
M比較短20個以內用char
text:存大段文本
blob:是二進制類型 用來存圖像信息 音頻等二進制信息
blob意義在于防止因為字符集的問題導致信息丟失
enum枚舉類型:是定義好 值就在某幾個枚舉范圍內
gender emum('男','女') insert 只能選其中之一
日期時間類型:
year:存年份
date:存年份日期2016-18
time:存時分秒
datetime:年月日時分秒
mysql> create table t8(
-> ya year,
-> dt date,
-> tm time,
-> dttm datetime);
-> insert into t8 (ya,dt,tm) values(2015,'2015-12-18','18:28:36');
列的默認值:
1、NULL查詢不方便
2、NULL索引效率不高
3、實際中避免列的值為NULL
如何避免:聲明列NOT NULL default默認值
mysql> create table t10(
-> id int not null default 0,
-> name char(10) not null default ''
-> );
主鍵與自增:
主鍵primary key 此列不重復,能區分每一行
primary key,auto_increment(一般那兩個一起出現)
注意:一張表列只能有一列為auto_increment 且此列必須加索引(index key)
優化:
定長(char)與變長(varchar)分離
常用與不常用列分離
能提高表的查詢效率
列的刪除與增加:(列的增刪改)
alter table 表名 add 列名 列類型 列屬性 默認在表的最后
alter table 表名 drop column 指定列--刪除列
alter table 表名 add列名 列類型 列屬性 [after 指定列的后面]
alter table 表名 change height(要修改的) shengao(被修改后的) smallint
alter table 表名 modify 列名 要改成的新的屬性
#alter table t12 modify shengao bigint;
視圖:(存儲的都是語句)
view被稱為虛擬表,view是sql語句的查詢結果(物理表的一個映射結果,物理表一改變,視圖表也改變)
view好處:
1、權限控制可用:
比如某幾個列允許用戶查詢,其他不允許
可通過視圖開放其中一列或幾列,起到權限控制作用
2、簡化復雜的查詢
3、視圖能更新?
如果視圖的每一行是與物理表一一對應的可以
view的行是由物理表多行經過計算得到的結果,view不可以更新
視圖的algorithm:
對于檢查查詢形成的view,在對view查詢時,如order by where
可以把建視圖語句+查視圖的語句===合并成==>查物理的語句
這種視圖的算法叫merger(合并)
引擎的概念:
mysql 5.0以上默認的引擎是innoDB 一般建表時指定引擎
myisam引擎存儲的數據可以直接考出來拿去用
innDB要把數據導出來
myisam和innDB引擎區別:
mysiam innDB
批量插入的速度: 高 低
存儲限制: 沒有 64TB
字符集與亂碼問題:
字符集、校對集(排序規則)、亂碼
文字本來的字符集與展示的字符集不一致導致
客戶端編碼設置:set names gbk/utf8;
表設置編碼:create table ()charset utf8;
服務器端utf8/gbk 都可
網頁的話:mate:charset=utf8;
索引:
索引是數據的目錄,能快速定位行數據的位置
索引提高了查詢的速度,降低了增刪改的速度,并非越多越好
一般在查詢頻率的列上加,而且在重復低列上加效果好
key 普通索引
unique key 唯一鍵
primary key 主鍵索引
fulltext 全文索引(在中文環境下幾乎無效,一般用第三方解決方案:如sphinx)
索引長度:建索引時,可以只索引列的前一部分的內容比如:前十個字符 key email(email(10));
多列索引:就是把2列或者多列的值,看成一個整體,然后鍵索引
冗余索引:在某個列上可能存在多個索引
索引操作:
查看索引:show index from goods\G
刪除索引:alter table 表名 drop index 索引名
或者:drop index 索引名 on 表名
添加:alter table 表名 add [index \unqiue]索引名(列名)
添加主鍵索引:alter table 表名 add primary key 列名
刪除主鍵索引:alter table 表名 drop primary key
常用函數:
一、數學函數
abs(x) 返回x的絕對值
bin(x) 返回x的二進制(oct返回八進制,hex返回十六進制)
ceiling(x) 返回大于x的最小整數值
exp(x) 返回值e(自然對數的底)的x次方
floor(x) 返回小于x的最大整數值
greatest(x1,x2,...,xn)返回集合中最大的值
least(x1,x2,...,xn) 返回集合中最小的值
ln(x) 返回x的自然對數
log(x,y)返回x的以y為底的對數
mod(x,y) 返回x/y的模(余數)
pi()返回pi的值(圓周率)
rand()返回0到1內的隨機值,可以通過提供一個參數(種子)使rand()隨機數生成器生成一個指定的值。
round(x,y)返回參數x的四舍五入的有y位小數的值
sign(x) 返回代表數字x的符號的值
sqrt(x) 返回一個數的平方根
truncate(x,y) 返回數字x截短為y位小數的結果
二、聚合函數(常用于group by從句的select查詢中)
avg(col)返回指定列的平均值
count(col)返回指定列中非null值的個數
min(col)返回指定列的最小值
max(col)返回指定列的最大值
sum(col)返回指定列的所有值之和
group_concat(col) 返回由屬于一組的列值連接組合而成的結果
三、字符串函數
ascii(char)返回字符的ascii碼值
bit_length(str)返回字符串的比特長度
concat(s1,s2...,sn)將s1,s2...,sn連接成字符串
concat_ws(sep,s1,s2...,sn)將s1,s2...,sn連接成字符串,并用sep字符間隔
insert(str,x,y,instr) 將字符串str從第x位置開始,y個字符長的子串替換為字符串instr,返回結果
find_in_set(str,list)分析逗號分隔的list列表,如果發現str,返回str在list中的位置
lcase(str)或lower(str) 返回將字符串str中所有字符改變為小寫后的結果
left(str,x)返回字符串str中最左邊的x個字符
length(s)返回字符串str中的字符數
ltrim(str) 從字符串str中切掉開頭的空格
position(substr,str) 返回子串substr在字符串str中第一次出現的位置
quote(str) 用反斜杠轉義str中的單引號
repeat(str,srchstr,rplcstr)返回字符串str重復x次的結果
reverse(str) 返回顛倒字符串str的結果
right(str,x) 返回字符串str中最右邊的x個字符
rtrim(str) 返回字符串str尾部的空格
strcmp(s1,s2)比較字符串s1和s2
trim(str)去除字符串首部和尾部的所有空格
ucase(str)或upper(str) 返回將字符串str中所有字符轉變為大寫后的結果
四、日期和時間函數
curdate()或current_date() 返回當前的日期
curtime()或current_time() 返回當前的時間
date_add(date,interval int keyword)返回日期date加上間隔時間int的結果(int必須按照關鍵字進行格式化),如:selectdate_add(current_date,interval 6 month);
date_format(date,fmt) 依照指定的fmt格式格式化日期date值
date_sub(date,interval int keyword)返回日期date加上間隔時間int的結果(int必須按照關鍵字進行格式化),如:selectdate_sub(current_date,interval 6 month);
dayofweek(date) 返回date所代表的一星期中的第幾天(1~7)
dayofmonth(date) 返回date是一個月的第幾天(1~31)
dayofyear(date) 返回date是一年的第幾天(1~366)
dayname(date) 返回date的星期名,如:select dayname(current_date);
from_unixtime(ts,fmt) 根據指定的fmt格式,格式化unix時間戳ts
hour(time) 返回time的小時值(0~23)
minute(time) 返回time的分鐘值(0~59)
month(date) 返回date的月份值(1~12)
monthname(date) 返回date的月份名,如:select monthname(current_date);
now() 返回當前的日期和時間
quarter(date) 返回date在一年中的季度(1~4),如select quarter(current_date);
week(date) 返回日期date為一年中第幾周(0~53)
year(date) 返回日期date的年份(1000~9999)
一些示例:
獲取當前系統時間:select from_unixtime(unix_timestamp());
select extract(year_month from current_date);
select extract(day_second from current_date);
select extract(hour_minute from current_date);
返回兩個日期值之間的差值(月數):select period_diff(200302,199802);
在mysql中計算年齡:
select date_format(from_days(to_days(now())-to_days(birthday)),'%y')+0 as age from employee;
這樣,如果brithday是未來的年月日的話,計算結果為0。
下面的sql語句計算員工的絕對年齡,即當birthday是未來的日期時,將得到負值。
select date_format(now(), '%y') - date_format(birthday, '%y') -(date_format(now(), '00-%m-%d') 100,'true','false');
if()函數在只有兩種可能結果時才適合使用。然而,在現實世界中,我們可能發現在條件測試中會需要多個分支。在這種情況下,mysql提供了case函數,它和php及perl語言的switch-case條件例程一樣。
case函數的格式有些復雜,通常如下所示:
case [expression to be evaluated]
when [val 1] then [result 1]
when [val 2] then [result 2]
when [val 3] then [result 3]
......
when [val n] then [result n]
else [default result]
end
這里,第一個參數是要被判斷的值或表達式,接下來的是一系列的when-then塊,每一塊的第一個參數指定要比較的值,如果為真,就返回結果。所有的when-then塊將以else塊結束,當end結束了所有外部的case塊時,如果前面的每一個塊都不匹配就會返回else塊指定的默認結果。如果沒有指定else塊,而且所有的when-then比較都不是真,mysql將會返回null。
case函數還有另外一種句法,有時使用起來非常方便,如下:
case
when [conditional test 1] then [result 1]
when [conditional test 2] then [result 2]
else [default result]
end
這種條件下,返回的結果取決于相應的條件測試是否為真。
示例:
mysql>select case 'green'
when 'red' then 'stop'
when 'green' then 'go' end;
select case 9 when 1 then 'a' when 2 then 'b' else 'n/a' end;
select case when (2+2)=4 then 'ok' when(2+2)<>4 then 'not ok' end asstatus;
select name,if((isactive = 1),'已激活','未激活') as result fromuserlogininfo;
select fname,lname,(math+sci+lit) as total,
case when (math+sci+lit) < 50 then 'd'
when (math+sci+lit) between 50 and 150 then 'c'
when (math+sci+lit) between 151 and 250 then 'b'
else 'a' end
as grade from marks;
select if(encrypt('sue','ts')=upass,'allow','deny') as loginresultfrom users where uname = 'sue';#一個登陸驗證
七、格式化函數
date_format(date,fmt) 依照字符串fmt格式化日期date值
format(x,y) 把x格式化為以逗號隔開的數字序列,y是結果的小數位數
inet_aton(ip) 返回ip地址的數字表示
inet_ntoa(num) 返回數字所代表的ip地址
time_format(time,fmt) 依照字符串fmt格式化時間time值
其中最簡單的是format()函數,它可以把大的數值格式化為以逗號間隔的易讀的序列。
示例:
select format(34234.34323432,3);
select date_format(now(),'%w,%d %m %y %r');
select date_format(now(),'%y-%m-%d');
select date_format(19990330,'%y-%m-%d');
select date_format(now(),'%h:%i %p');
select inet_aton('10.122.89.47');
select inet_ntoa(175790383);
八、類型轉化函數
為了進行數據類型轉化,mysql提供了cast()函數,它可以把一個值轉化為指定的數據類型。類型有:binary,char,date,time,datetime,signed,unsigned
示例:
select cast(now() as signed integer),curdate()+0;
select 'f'=binary 'f','f'=cast('f' as binary);
九、系統信息函數
database() 返回當前數據庫名
benchmark(count,expr) 將表達式expr重復運行count次
connection_id() 返回當前客戶的連接id
found_rows() 返回最后一個select查詢進行檢索的總行數
user()或system_user() 返回當前登陸用戶名
version() 返回mysql服務器的版本
示例:
select database(),version(),user();
selectbenchmark(9999999,log(rand()*pi()));#該例中,mysql計算log(rand()*pi())表達式9999999次。
總結
以上是生活随笔為你收集整理的mysql学习笔记整理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何卸载阿里云&腾讯云官方的监
- 下一篇: 电影混剪 献给即将三十岁的你自己