.數據庫
數據庫的發展: 文件系統(使用磁盤文件來存儲數據)=>第一代數據庫(出現了網狀模型,層次模型的數據庫)=>第二代數據庫(關系型數據庫和結構化查詢語言)=>新一代數據庫("關系-對象"型數據庫);
層次模型是一種導航結構,
優點:分類管理,如果查詢同一類的數據是很方便的。
缺點:如果查詢很多不是同一類的數據,效率就很低了
層次結構可以造成數據無效,比如張經理管理了一個員工叫張三,李經理也管理了一個叫張三,我們無法區分張三是一個人還是兩個人。
網狀模型解決了層次模型數據無效的問題,但是沒有解決導航問題,深層率查詢,效率很低.
關系模型中,每個表都是獨立的,通過公共字段來建立關系。優點:表是獨立的,需要什么數據就到那個表中查詢。
缺點:多表查詢的時候效率低下。
關系:兩個表的公共字段叫關系
- SQL語句
Structured Query Language 結構化查詢語言,是用來操作關系型數據庫的.常用的關系型數據有:
Access,MySQL,Sql Server,Oracls.
標準的SQL是所有關系型數據庫都支持的操作語句,標準的SQL也叫作SQL-92.但是每個數據庫在標準的基礎上又擴展了自己的東西.所有,一個數據庫的拓展語句在在其他數據庫不能運行.
- 連接數據庫
需要的參數: Host (-h),username (-u), password (-p),port(默認3306) (-P)
mysql -u root -h localhost -p
退出數據庫:exit,quit,\q
數據庫操作:數據庫的本質是一個文件.操作數據庫的軟件叫做數據庫管理系統.
/**
* 創建數據庫
* 如果創建的數據庫已經存在,會報錯.所以一般要進行判 斷.
* 同時,如果數據庫名是關鍵字或者純數字,需要加上反引 號,最好的辦法是任何時候都加反引號
*/
Create database db_name [charset=字符編碼]
Create database if not exists db_name [charset=字符編碼]
/**
*/
2. 查詢數據庫
show database;
3.顯示數據庫的創建語句
show create database create db_name;
4. 更改數據庫
alter database db_name [option];
//eg:alter database haha charset=gbk;
5. 刪除數據庫:如果數據庫不存在會報錯
drop database if exists db_name;
6. 選擇數據庫
use db_name;
- 數據庫表的操作
幾個概念:
行row:也叫記錄,一行就是一條記錄
列(column) : 一列就是一個字段,字段也叫屬性,一個表中包含多個字段
1.創建表:(primary key)主鍵不能重復,不能為空,一個表只能有一個主鍵,主鍵可以由多個字段組成.
create table table_name(
field1 data_type [null | not null][default][auto_increment][primary key],
field2 data_type,
...,
);
2. 查看所有表
show tables;
3.顯示創建表的SQL語句
show create table table_name [\G];
4.顯示表結構
describe [desc] table_name;
5.刪除表
drop tabel table_name1,table_name2,...;
數據類型:
int,decimal(總位數,小數位數) 存小數 decimal(10,3), char(1):定長, varchar(10):可變長度, text:大段文字
- 數據操作
1.插入數據:插入字段可以和數據庫中字段順序不一致,但是值和插入的字段順序必須一致. 如果插入字段省略掉,插入的值和數據庫表的字段的順序和個數都要一致.
insert into table_name (field1,field2) values (value1,value2);
//自動增長的插入
insert into student values (null,"name","female","shenzhen",22);
//默認值的插入
insert into student values (null,"name","female",default,33);
2.數據的修改
update table_name set field1=value1,field2=value2 [where 條件];
//eg:
update student set gender="male" where name="xiaoming";
update student set gender = "female";
3.刪除數據
delete from table_name [whre 條件];
delete from student where name = "haha";
delete from student; //所有的數據都刪除了
4 .查詢數據
select 列名 from 表 [where 條件] [order by 排序字段 asc|desc] [limit [起始位置默認0],或者的記錄數量];
升序:asc
降序:desc
默認升序
select name,gender from student;
select * from; //獲取所有
select * from student order by score desc;
select * from student limit 3;
select * from student limit 2,10;
select * from student order by score desc limit 3;
//取出第一位
select * from stu order by score desc limit 0,1
- 運算符
比較運算符: > , >=, <, <=, = , <>(不等于)
邏輯運算符: and, or, not
聚合運算:
Sum(), Avg(), Min(), Count(), Max().
select max(score) from student;
select min(score) from student;
select sum(score) from student;
select avg(score) from student;
select count(*) from student;
select count(*) from student where gender="male";
4.PHP與MySQL
- php開啟MySQL拓展,PHP本身是一個框架,它的功能是由PHP拓展而來的,要通過PHP連接數據庫,必須開啟PHP連接MySQL的功能,就是PHP的MySQL拓展. 在php.ini中,把extension=php_mysql.dll 開啟,重啟服務器.
1.php連接數據庫
$connect = mysql_connect("localhost",'root','password') or die("數據庫連接失敗");
/**
通過@符號屏蔽信息
$connect = @mysql_connect("localhost",'root','password') or die("數據庫連接失敗");
*/
2. 終止執行:exit(),和die();
die()停止執行,把生成的代碼發送到客戶端.
3. 選擇數據庫
方法1: 執行 use db_name
mysql_query("use database_name") or die("數據選擇失敗");
方法二:
mysql_select_db("database_name") or die ("數據庫選擇失敗");
4. 設置字符編碼
mysql_query("set names utf8");
5.查詢數據庫 : 返回一個資源類型的數據
$results = mysql_query("select * from products"); //resource type
mysql_fetch_row: 取出結果集中數據
開始匹配,指針指向第一個記錄.取出資源中的當前記錄,匹配成索引數組,指針指向下一條記錄.
5.1.
while($rows = mysql_fetch_row($results)){
echo $rows[0];
echo "<br>";
echo $rows[1];
echo "<br>";
echo $rows[2];
echo "<br>";
echo $rows[3];
echo "<br>";
}
這種方法讀取數據缺點:數據庫字段發生變化,會影響數組的索引編碼.
5.2: mysql_fetch_assoc : 形成關聯數組
數組的鍵和數據表的字段名相關聯
while($rows = mysql_fetch_assoc($results)){
echo $rows["name"];
echo "<br>";
echo $rows["gender"];
echo "<br>";
echo $rows["age"];
echo "<br>";
echo $rows["id"];
echo "<br>";
}
5.3: mysql_fetch_object: 匹配成對象,通過->訪問
while($obj=mysql_fetch_object($results)){
echo $rows->name;
echo "<br>";
echo $rows->gender;
echo "<br>";
echo $rows->age;
echo "<br>";
echo $rows->id;
echo "<br>";
}
6. 釋放資源 mysql_free_result($results);
7. 關閉連接 mysql_close($connect);
頁面執行完畢后,所有變量全部銷毀,可以不用手動釋放資源.
數據的導入與導出,用phpMyAdmin工具
1月 5日
MySQL 學習
- 簡介
- 數據庫系統: DataBase System = 數據庫管理系統(DBMS,DataBase Management System) + 數據庫 (DataBase) + 管理員(Manager)
DBS = DBMS + DB;
對大量信息進行管理的高效解決方案,按照數據結構來組織,存儲和管理數據的庫.
關系型數據庫系統:建立在關系模型上的數據庫系統
關系模型: 日常生活的實體和實體的屬性保存到數據庫時,處理實體結構的方式:
數據結構可以規定,同類數據,結構一致.數據之間的關系可以設置實體之間的聯系.
Nosql: Not only sql,非關系型數據庫
mongoD,MemBase
對象型數據庫.
關系型數據庫的幾個重要概念:
數據庫database:數據的倉庫
表table:數據是保存在表內,保存在一個表內的數據,應該具有相同的數據格式.
行和列:行用于記錄數據,列用于規定數據的格式
MySQL是基于C/S架構的.
- MySQL常用的操作
(1)數據庫操作
//創建數據庫
create database `db_name` [數據庫選項];
//查詢當前存在的數據庫
show databases;
//查詢數據庫的創建語句
show create database db_name;
//刪除數據庫
drop database db_name;
//修改數據庫信息
alter database db_name [修改指令];
alter database db_class character set utf8;
//修改數據庫的名字
1.直接修改文件夾的目錄名
2.將數據全部導出,新建一個數據庫,再導入數據,刪除舊數據庫
3.新建數據庫,把就數據庫的表移到新數據庫,刪除就數據庫
(2)表操作
可以通過.(點)語法,指明數據表所屬的數據庫
create table `db_name`.`table_name`(
field1 type,
field2 type
);
use db_name 只是設定了默認數據庫,不影響操作其它數據庫.選擇了默認數據庫,只會影響默認行為.可以操作任意的數據庫
//創建表
create table info_student(
`name` varchar(20),
`stu_no` varchar(20)
);
//查看表
show tables [like 'pattern'];like pattern部分表示獲得規定規則的表名. % 為通配符,表示任意字符的任意組合.同樣適用于數據庫查詢:
show databses like 'pattern';
//查看表的結構
describe(desc) table_name;
//刪除表
drop table [if exists] table_name;
drop database [if exists] database_name;
//修改表名
rename table old_table_name to new_table_name;
//同時修改多個
rename table tb1 to new_tb1,tb2 to new_tb2;
//支持跨數據庫重命名
//可以利用這個操作為數據庫重命名: 創建一個新的數據庫,舊數據內的表,都rename到新的數據庫.刪除舊的數據庫.
rename table exam_user to `db_name`.table_name;
//修改列的定義
alter table tb_name [add | drop | change | modify]
//增加一個新列
alter table table_name add filed_name type;
//刪除一個列
alter table tb_name drop field;
//修改一個列的定義
alter table tb_name modify field varchar(90);
//重命名一個列
alter table table_name change old_field new_field type;
//修改表選項
alter table table_name character set utf8;
(3)數據操作
//創建數據(插入數據)
insert into table_name (fields) values (value1,...);
insert into student (name,id) values (`name`,`09332`);
//獲取數據(查詢數據)
select fields(*) from table_name condition;
select * from students;
select name,id from students where 1;
select * from students where score>=80;
//刪除數據
delete from table_name condition;
delete from students where score<=20;
//修改數據
update table_name set field1 = value1,... condition;
update students set score = 90 where id = 0922;
- SQL
Structured Query Language:結構化查詢語言;
針對操作對象不同,分成不同語言:
1.數據操作(管理)語言.DML;
查詢,獲得數據.DQL;
管理,增加,刪除,修改數據.DML
2.數據定義語言(對保存的數據的格式進行定義) DDL;
3.數據庫控制語言 (針對數據庫軟件服務進行操作) DCL;
- 字符集
字符的集合;構成分兩部分:1.字符的集合,展示用,2.字符的編碼,保存和處理.
MySQL支持常見的字符集,查看: show character set;
字符集決定的是字段的數據以何種形式保存.
如果通過客戶端操作服務器,那么客戶端和服務器端之間進行數據通信,要保證編碼一致.可以將互相發送的數據,轉換成目標可以接收的編碼數據.
通過MySQL配置:
character_ser_client 客戶端發送數據編碼
character_ser_results 客戶端接收數據的編碼
通過指令 show variables like 'character_set_%';查看當前的字符編碼集
設置變量: set 變量名=值;
set character_set_client = utf8;告知服務器,客戶端發送的數據是utf8編碼;
如果需要從服務器返回數據,還需要設置服務器發送給客戶端的編碼:set character_set_results = utf8;服務器在發送數據時,才能轉成客戶端認識的編碼;
對于普通的簡單項目統一的操作可以使用 set names utf8;完成設置
連接層編碼: set character_set_connection = utf8;
set names 操作可以同時設置客戶端接收的數據格式,客戶端發送的數據格式,連接層編碼三個.
數據編碼轉換過程: client->connection->[服務器內部編碼]->results
- MySQL數據類型
1.整型
類型 | 字節 | 最小值(有符號/無符號) | 最大值(有符號/無符號) |
---|---|---|---|
tinyint | 1 | -128 / 0 | 127/255 |
smallint | 2 | -32768 / 0 | 32767/65535 |
mediumint | 3 | -838808 / 0 | 83888607/1777215 |
int/integer | 4 | -2147483648 / 0 | 2147483647/4294967295 |
bigint | 8 | -922337203685477580/ 0 | 922337203685477580/8446744073709551615 |
在定義字段時,可以使用unsigned標示無符號,默認為有符號.
create table tbl_int(
a tinyint unsigned,
b tinyint
);
定義顯示寬度:通過規定數據的顯示寬度,達到統一顯示的目的. 類型(M) ,M表示顯示的最小寬度是多少. 如果需要用前導零值填充,使用 zerofill;不會影響數的范圍,寬度大的不影響,不會截取;
alter table tbl_int add c tinyint(2) zerofill;
insert into tbl_int values (0,123,2);
2.浮點數
float 單精度,默認精度位數為6位;
double 雙精度,默認16位
控制數值的范圍 Type(M,D),D表示所有的數值的位數(不包括小數點和符號);
D表示小數位數;
支持科學計數法: 1.322*10^3;
3.定點數
decimal(M,D);M總位數,D小數位數,M默認10,D默認0
小數也支持zerofill和unsigned
create table number1(
send_money decimal(10,2) zerofill;
);
insert into number1 values (123.43);
insert into number1 values (122332.564);
- 日期和時間
DateTime 年月日時分秒
Timestamp 時間戳,存儲時整型,表示時,日期時間
Date 年月日
支持0值:表示當前沒有規定 2015-04-0 表示4月整個月.
insert into dt_1 values (0,0);
Time 類型: 1,表示一天中的時間 2,時間間隔,在表示時間間隔時,可以用天表示 格式: DHH:MM:SS
create table tb_1(
ago time
);
insert into tb_1 values ('4 21:22:11');
insert into tb_1 values ('23:22:11');
insert into tb_1 values ('232211');
Year:此時表示日期的范圍,不是1000-9999
而是 1901-2155 一個字節(256間隔)
在實際項目中,通常保存的都是Unix時間戳,直接用整型保存在數據庫,不是MySQL提供的timestamp類型;
- 字符串類型
char(M): 固定長度
varchar(M): 可變長度
M在varchar中表示允許的最大長度,char內表示嚴格限定的長度
char(5) | varchar(5) | ||
---|---|---|---|
'' | 5個字符 | 一個字節 | varchar需要一個字節保存字符串總長度 |
'abc' | 5 | 4 | |
'abcdf' | 5 | 6 | |
'abcdefg' |
M表示的是字節,而不是字節數,但是總的長度的使用時按照字節計算的
create table tb_2(
a varchar(65535) //會報錯,最大長度是21845, 三個字節21845 * 3 = 65535
);
create table tb_3(
a varchar(65535)
) character set gbk; //報錯,最大長度是32767,2個字節 2 * 32767 = 65535
字段的最大長度除了類型本身之外,記錄的總長度也是有限制的.
真實的varchar長度:
記錄存在總長度65535限制
特點:當類型數據超過255個字符時,采用2個字節表示長度 65535-2 = 65533
整條記錄,需要一個額外的字節,用于保存當前字段的null值.除非所有的字段都不是null,這個字節才可以忽略.一個記錄,不論有多少個字段存在null,都是使用統一的一個字節表示.而不是每個字段一個字節
Text類型: 2 ^ 16,文本類型,tinytext,longtext;
枚舉 enum
值是否能為空: null || notnull,如果為not null,在插入時,缺少值,會插入失敗;
默認值屬性: default value來聲明. 在沒有為該字段設置值時啟用,而且默認值的設置,需要使用固定值;
常見的是一個字段不能為空,而且存在默認值;
create table tb_3(
a int not null default 10,
b int not null default 2
);
insert into tb_3 (a) values (1);
insert into tb_3 (b) values (22);
主鍵pk,primary key:
可以唯一標示,某條記錄的字段或者是字段的集合,就是主鍵.主鍵可以是真實實體的屬性.常用的是使用一個與實體信息不相關的屬性作為唯一標識.主鍵與業務邏輯不發生關系,只是用來標識記錄.
1.字段上設置:主鍵字段在插入時不能為空,或者沖突
create table reacher(
t_id int primary key,
t_name varchar(5);
class_name varchar (6);
days tinyint unsigned
);
2.在定義完字段后,可以定義多列主鍵(組合主鍵):一個主鍵內包含多個字段,而不是多個字段的主鍵.只需要一個唯一標識即可,MySQL規定只能存在一個主鍵;
常見的主鍵設計,每個表都應該存在一個可以唯一標識的主鍵字段,最好與實體沒有關系,不是實體屬性字段.
create table teacher(
t_name varchar(5),
class_name varchar(6),
days tinyint unsigned,
primary key(t_name,class_name);
);
字段增長:auto_increment,自動增長的默認值是1,可以設置
如果插入的值小于已經存在的主鍵的值,是可以的,如果是主鍵,不能重復;
實體之間的關系:
1vs1:
兩個實體表內,存在相同的主鍵字段.如果記錄的主鍵值等于另一個關系表內的主鍵值,則兩條記錄一一對應;
1 vs n
:一個實體對應多個其它實體;例如,一個班級對應多個學生
在多的那端,增加一個字段,用于指向改實體所屬的另外實體的標識
M:N 多對多
典型的,利用一個中間表,標識實體之間的對應關系.中間表的每個記錄,標識一個關系
一個M:N,
1:M,1:N來實現
講師主鍵 | 名字 | 班級 |
---|---|---|
1 | joe | |
2 | jack |
班級主鍵 | 班級名 | 講師主鍵 |
---|---|---|
29 | 0234 | |
30 | 0907 |
講師主鍵 | 班級主鍵 |
---|---|
1 | 29 |
3 | 29 |
- 外鍵 foreign key
:如果一個實體(student)的某個字段(class_id)指向(引用)另外一個實體(class)的主鍵(class_id),就稱student實體的class_id是外鍵.被指向的實體,稱之為主實體(主表,父實體),對應的另外一個實體稱之為從實體(從表,子實體,子表)
外鍵的作用: 保證數據的完整性,用于約束處于關系的內的實體.增加子表記錄的時候,是否有與之對應的父表記錄.在刪除或者更新的主表記錄時,從表應該如何處理相關的記錄.
//定義一個外鍵
在從表上在,增加一個外鍵字段,指向主表的主鍵.使用關鍵字foreign key;
foreign key (外鍵字段) references 主表名 (關聯字段)[主表記錄刪除時的動作][主表記錄更新時的動作];
drop table if eixsts class;
create table class (
class_id int primary key auto_increment,
class_name varchar(10) not null default `php` comment `班級名稱`
)character set utf8;
drop table if exists student;
create table student(
stu_id int primary key auto_increment,
stu_name varchar(10) not null default ``,
class_id int,
foreign key (class_id) references class (class_id)
) character set utf8;
設置級聯操作:
在主表數據發生改變時,與之關聯的從表數據應該如何處理:
主表更新:on update,主表刪除 on delete
允許的聯級操作,cascade:關聯操作,如果主表被更新或者刪除,那么從表也會執行相應的操作.set null:設置為null,表示從表不指向任何主表記錄,restrict:拒絕主表的相關操作
修改外鍵:先刪除,再新建.通過修改表完成
alter table_name drop foreign key field;
刪除外鍵需要通過指定外鍵名稱達到目的,可以在創建外鍵時,指定名稱或者使用MySQL默認生成的名稱;
alter table student drop foreign key class_id;
//增加外鍵
alter table student add foreign key (class_id) references class (class_id) on delete set null; //刪除時,將從表外鍵,設置為null;
alter table student add foreign key (class_id) references class (class_id) on delete cascade; //刪除時,將從表外鍵刪除;
alter table student add foreign key (class_id) references class (class_id) on delete cascade on update restrict; //刪除時,將從表外鍵上刪除,更新時拒絕更新;
- 數據庫存儲引擎
默認的服務器表類型,通過mu.ini可以配置:default-storeage-engine=INNODB
在創建表時,或者編輯表時,可以指定表的存儲引擎
alter table class engine myisam;
create table room(
room_id int primary key auto_increment,
room_no char(3)
)engine myisam character set utf8;
innodb和myisam區別
保存的文件的方式不同:
myisam,一個表,三個文件
Tbl_name.frm 結構 (frame)
Tbl_name.myd 數據 (data)
Tbl_name.myi 索引 (index)
innodb:
一個表一個文件:
Tbl_name.frm 結構
所有的innodb表,都使用相同的innodb存儲空間在保存數據和索引;
選擇存儲引擎的依據: 1 功能, 2 性能
特點 | Myisam | InnoDB | BDB | Memory | Archive |
---|---|---|---|---|---|
事務安全 | 支持 | 支持 | |||
全文索引 | 支持 | 5.5版本支持 | |||
鎖機制 | 表鎖 | 行鎖 | 頁鎖 | 表鎖 | 行鎖 |
存儲限制 | 沒有 | 64TB | 沒有 | 有 | 沒有 |
B樹索引 | 支持 | 支持 | 支持 | 支持 | |
哈希索引 | 支持 | 支持 | |||
集群索引 | 支持 | ||||
數據緩存 | 支持 | 支持 | |||
索引緩存 | 支持 | 支持 | 支持 | ||
數據可壓縮 | 支持 | 支持 | |||
空間使用 | 低 | 高 | 低 | N/A | 非常低 |
內存使用 | 低 | 高 | 低 | 中等 | 低 |
支持外鍵 | 支持 |
innoDB&Myisam:
數據和索引的保存的文件不同: Myisam是分開保存的,innoDB是保存到表空間
Myisam支持索引壓縮,而innoDB索引和數據是綁定保存不壓縮,體積大;
innoDB很多時候是行級鎖,而myisam是表級鎖,innodb的并發高;
innodb不支持fulltext類型的索引(新的版本的innodb支持);
innodb支持事務,外鍵,數據的完整性約束要強,二myisam不支持.
innodb中不保存表的具體行數,所以在執行 select count(*) from table_name 時,innodb要掃描一遍整個表來計算有多少行,但myisam只需要簡單的讀取保存好的行數即可.注意的是,當count(*)語句包含where時,兩種表的操作是一樣的;
對于auto_increment類型的字段,innodb中必須包含只有該字段的索引,但是在myisam中,可以和其它字段一起建立聯合.
- 范式 (Normal Form)
用于規范表的設計的一套原則體系.
規范表的結構:
體系:1NF,2NF,3NF,4NF...
1NF:
要求: 表,所有的列(屬性),不能再分,具有原子性.通常認為,不符合第一范式的表,不具有關系模型的定義;
2NF:
滿足第一個范式的基礎上.
要求:每一行(記錄)必須能夠唯一標識.同時要求:不存在非主鍵字段,不能對主鍵有部分函數依賴.(在組合鍵前提下,表中非主鍵字段,有依賴于組合主鍵內的個別字段依賴的情況). 比如:非主鍵關鍵字(教室號碼),依賴主鍵內的部分字段(班級id),非主鍵關鍵字(教師性別),依賴于主關鍵字內部分字段(教師)
解決方案:常用方案是增加一個單子段主鍵即可,可以保證唯一標識,而且也不能形成部分函數依賴(一個獨立的字段)
3NF:
不錯出現傳遞依賴:不能出現 A->B->C
這樣的結構,如果出現,就說C傳遞依賴A
實體上表示,一個關系(二維表),只能保持一個實體的信息,不能保存多個信息
通用原則:
1,每個實體一個表(可以采取常用信息和詳細信息分開保存的思路)
2,為一個關系(二維表)增加,一個邏輯主鍵(不屬于真實實體屬性的字段),用于做標識。
3,出現二維表對應的關系,采用1:1, 1:N, M:n的形式
將關聯關系設計。
注意:
實際的開發中,常常會為了操作方便,編碼容易,做一些逆規范化的事情。
例如,每次得到授課信息時,都需要得到教室號。如果不做逆規范話,每次都
需要2個表內獲得數據。可以考慮,將教室號,放入到 代課信息內。查詢容易,編碼簡單。
- 校對規則
每一套編碼字符集都有與之相關的校對規則.即,在當前編碼規則下,字符間的比較規則,順序;
每個字符集都支持不定數量的校對規則,可以通過指令:show collation 查看字符集地區名比較規則(ci,cs,bin)(不區分大小寫,區分大小寫,字節比較)
show collation like `gbk%`;
在設置字符集的時候,可以設置當前字符集所采用的校對規則,如果不設置校對規則,那么每個字符集都有一個默認的校對規則;
以gbk為例子,比較chinese_ci bin 之間的區別,一個chinese_ci,一個chinese_bin,插入相同的數據:
當使用order by 進行排序時,數據會按照某個字段進行排序.由于排序規則不同,排序會不一致
character set gbk collate gbk_chinese_ci;
character set gbk collate gbk_bin;
select * from tb_3 order by name;
select * from tb_4 order by name;
- 查詢語句 select
select語法: select [查詢選項][查詢表達式(字段)] [from 子句][where 子句][having 子句][order by 子句][limit 子句];
要求子句可以不出現.如果出現,要求必須按照順序書寫;
表達式:字段,值,返回值的語句,函數的返回值
列子句
select id+10,concat(t_name,'-',gender),c_name from teacher_class;
//concat字符串拼接函數,字段可以作為參數,也可以進行加法運算
別名: 通常一個表達式,形式不夠好,不容易讀取,起一個可以容易讀取的別名即可:
使用關鍵字 as: 標識符 [as] 別名;as可以省略,建議保留
from子句:表示查詢的目標數據源,通常情況下是表名,表名也支持別名
select * from teacher_class,num_2;
表名也是一個列表:如果沒有任何條件的兩個表名,會得到表1乘表2的所有數據.交叉連接,笛卡爾積;
from可以省略,但是有些數據庫不支持,MySQL支持;使用dual作為虛擬表存在
select now() from dual;
where 子句:
用于通過條件過濾數據,得到真實的結果;
MySQL支持的操作符:邏輯運算符和關系運算符
=,>,<,>=,<=.!= (<>)
字符串匹配運算符:like 可以利用通配符,完成模糊匹配
通配符: _ 匹配一個字符,%匹配多個任意字符,%匹配%,_匹配_
判斷某個值是否為null: is null, is not null;
isnull()結構可以判斷null值;
<=>功能與 = 一致,特別的功能在于可以比較null值
select null is not null,null is null;
select null<=>null, 10 <=> null;
between and:
between valueA and valueB:范圍取值
范圍比較,閉區間: valuesA<=expr<=valueB;
select * from teacher_class where id between 3 and 5; //3,4,5三個id的值
select * from teacher_class where id in (3,5) //兩個值,3,5
in| not in:集合之內(外);
in| not in(集合元素);
.interval:
獲得一個集合元素的集合:interval(值A,元素1,元素2....);
一次判斷值與元素之間的大小,如果值A小于元素1,則返回0;如果值A小于元素2,則返回1,依次類推;
select t_name ,days,interval(days,10,20,30) from teacher_class where interval(days,10,20,30) = 1;
邏輯運算符: And && ,Or ||, Not ! ;
null值的特殊性: not null,! null 為null
異或:xor ,有null就是null
. group by:分組聚合查詢語句:通過列內,不同的值,完成數據統計;
分組的目錄,通常是組內統計:統計是通過MySQL的統計函數完成的;
sum()計算所有表達式的和
select t_name,sum(days) from teacher_class where 1 group by t_name; //所有老師的上課天數
select c_name, sum(days) as sum_days from teacher_class where 1 group by c_name; //所有班級的上課天數
如果合計函數的使用,沒有與group by配合,統計所有的數據,將所有的數據當作一組.
select sum(days) from teacher_class where 1;
排序group by:會通過排序字段,為數據進行重新排序,默認升序(asc)
select t_name,sum(days) from teacher_class where 1 group by t_name [asc | desc];
group by 多字段分組:
select t_name,c_name,sum(days) from teacher_class where 1 group by t_name,c_name; 類似多字段主鍵,使用組合的字段進行標識;
. rollup:在使用多字段分組時,通常需要做上級統計:
select t_name,c_name,sum(days) from teacher_class where 1 group by t_name,c_name with rollup;
使用 with rollup ,可以相當于利用組合條進行統計后,
再使用上一條件再次統計一次。
注意,會統計到 沒有分組的情況,整個都是一組的情況
是否可以得到 大于某些代課天數的講師信息?
select t_name, sum(days) from teacher_class where sum(days)>50 group by t_name;
分析發現:
where先執行,group by 后執行。
Sum()在計算的時候,沒有分組的呢
無法在在where內使用合計函數:
需要一個,可以在結果內,再次過濾的功能:
having
slect t_name,sum(days) from teacher_class where days > 10 group by t_name; //where會影響group的統計,說明where執行在前;
. having :負責在結果(where查詢到的)中進行再次過濾,可以像使用where一樣,having進行處理;
select t_name,sum(days) from teacher_class where 1 group by t_name having sum(days) > 50;
- 聚合函數
Sum(),Avg(),Max(),Min(),Count()
Count():統計總的記錄數,統計的是非null的記錄數,通常用count(*)來統計.
group_concat(): 組內字符串連接,做了分組,只能顯示組內信息.如果需要對其它列進行顯示,可以把結果連起來;
- order by
校對規則,決定排序關系;按照字段值進行排序,order by 字段 asc | desc;
默認升序asc;
允許多字段排序:先按照第一個字段排序,如果說,不能區分,才使用第二個字段,依次類推
select * from teacher_class order by days;
select * from teacher_class order by days ddesc;
select * from teacher_class order by days desc,begin_date desc,edn_date asc;
如果是分組,應該用對應字段group by,進行排序的group by語法.
. limit
限制獲得的記錄數量;
limit offset,row_count;
;offset偏移量,默認從零開始,0可省略,row_count要取的記錄數,不足,全部取了;
select * from teacher_class limit 3,5;
select * from teacher_class limit 5;
. distinct: 去除重復記錄
重復的記錄指的是字段值,都相同的記錄,而不是部分字段相同的記錄
相對的是all,表示所有.默認就是all行為.
select days from teacher_class;
select distinct days from teacher_class;
selct days,begin_date from teacher_class;
select distinct days,begin_date from teacher_class;
聯合查詢:
將多條select語句的結果,合并到以前,稱為聯合操作.
使用的場景: 獲得數據的條件,出現邏輯沖突,或者很難在一個邏輯內表示,可以拆分多個邏輯,分別實現,最后吧結果合并到一起.
//獲取兩個不同班級上課天數最多的老師
(select t_name,days,from teacher_class where c_name='1234' order by days desc limit 1) union (select t_name,days,from teacher_class where c_name='2221' order by days desc limit 1)
union all:環境
如果union的結果存在重復的記錄,會自動消除重復.如果不想消除重復,使用union all達到目的.
(select t_name,days,from teacher_class where c_name='1234' order by days limit 10) union all
(select t_name,days,from teacher_class where c_name='2221' order by days desc limit 10)
排序:子語句結果的排序,1 . 將子句包裹在括號內, 2. 子語句的order by 只有在order by配合limit時才生效.union在做子語句時,會對沒有limit的子語句優化(忽略)
(select t_name,days,from teacher_class where c_name='1234' order by days) union all //沒有limit,結果無序的
(select t_name,days,from teacher_class where c_name='2221' order by days desc limit 10)
如果要對所有結果進行排序,只需要在最后一個select語句后進行排序.
(select t_name,days,from teacher_class where c_name='1234') union all
(select t_name,days,from teacher_class where c_name='2221') order by days desc; //括號不是必須的,但提高了可讀性
多個select語句的檢索到的字段數,必須一致.更加嚴格的是,數據類型上也要一致.MySQL內部會做類型轉換,前提是能夠轉換成功. 檢索結果中列的名稱是根據第一條select語句決定的.
- 子查詢:語句內部的查詢語句,就是子語句查詢
如果一個表內,有多個相同的結果時取數據的思路: 比如并列第一的情況
select t_name,gender from teacher_class order by days limit 1;
//方案:先獲取條件數,作為判斷依據變量,這是SQL支持的
var1 = select max(days) from teacher_class;
select t_name,gender from teacher_class where days=var1;
//select t_name,gender from teacher_class where days=(select max(days) from teacher_class);
子查詢分類: 分類的依據: 出現的位置和返回值的形式
返回值分類:
單一值,一列,多列,表(多行,多列)
出現的位置:
where 型,where 后
from型:from 后
exists 型
集合運算符:in,not in, any, all , !=all(not in)
返回一行:
在參與比較時,使用括號可以構建一行:
(filed1, field2)
select t_name, gender, c_name from teacher_class where (gender, c_name) = (select distinct gender, c_name from teacher_class where t_name='李白' and c_name='0115' limit 1);
返回一個表:
如果用于在from子句內,from子句內,要求使用一個表,是一個結果.
應該給這個結果起個名稱,別名.
select * from (select t_name,c_name,days from teacher_class where days > 15) as temp_name where t_name like '李%';
exists(subquery):如果子查詢的可以返回數據,則認為exists表達式返回真. 否則返回假;
//這兩個語句完成的是同樣的語句
select * from teacher_class where exists(select * from teacher where teacher_class.id=t_id);
select * from teacher_class where id in (select t_id from teacher);
//兩個語句的思路
exists:先獲得每一條teacher_class的數據,然后獲得ID字段,去teacher 表內查詢對應值,找到.
in:先找到所有的ID 的可能性.再在檢索teacher_class數據時,判斷當前的id是否在id集合內.
- join
每一個實體,每一個表,一個業務邏輯,使用多個實體的數據,多張表應該在一起使用,將多個表的記錄連接起來.
總體的思路:將所有的數據,按照某種條件,連接起來,在進行篩選處理.
連接的分類: 內連接,外連接,自然連接
//內連接:數據內部的連接,要求連接的多個數據必須存在才能進行連接
select join_teacher.t_name,join_teacher_class.begin_date,join_teacher_class.days from join_teacher inner join join_teacher_class on join_teacher.id=join_teacher_class.t_id;
//外連接:如果負責連接的一個或者多個數據不真實存在,則稱之為外鏈接.
select join_teacher.t_name,join_teacher_class.begin_date,join_teacher_class.days from join_teacher left outer join join_teacher_class on join_teacher.id=join_teacher_class.t_id;
內連接的處理:
內連接,在連接時,是可以省略連接條件的.意味著所有的左表的數據都要與右表的記錄做一個連接,共存M*N個連接.這種連接稱為交叉連接或者笛卡爾積;
select join_teacher.t_name,join_teacher_class.begin_date,join_teacher_class.days from join_teacher inner join join_teacher_class;
join_teacher.t_name,join_teacher_class.begin_date,join_teacher_class.days from join_teacher cross join join_teacher_class;
join_teacher.t_name,join_teacher_class.begin_date,join_teacher_class.days from join_teacher join join_teacher_class;
此時,可以用cross join 代替inner join.可以通過多表查詢,不使用where做到笛卡爾積.
在MySQL中cross join和inner join相同,但在數據庫的定義上,交叉連接就是笛卡爾積.是沒有條件的inner join.MySQL inner join是默認的連接方案,可以省略join
. 有條件的內連接: 會在連接時過濾掉非法的連接.
where的寫法:在數據過濾上,數據交叉連接完成后,再做數據過濾.
on的寫法:在連接時,就對數據進行判斷;
using的寫法:using要求,負責連接的兩個實體之間的字段名稱一致.
建議在有同名字段時用using,而在通用的條件時,用on.在數據過濾時(不是指連接過濾)使用where.
查詢條件,與外鏈接通用(外鏈接,不能使用where作為連接條件)
//后面再補充
- select
將檢索到的數據,保存到服務器的文件內.可以自動創建文件,但是不能重寫已經存在的文件,否則報錯;
生成的文件格式:
默認的,采用行來區分記錄,而采用制表符,來區分字
為了滿足某種特別的需求,會采用不同的分割方式。
支持,在導出數據時,設置記錄,與字段的分割符。
通過如下的選項:
fields:設置字段選項
Lines: 設置行選項(記錄選項)
先看默認值:
字段:fields terminated by '\t' enclosed by '' escaped by '\‘
記錄:lines terminated by '\n' starting by ''
可以自己設定
:
select * into outfile 'e:/amp/three'
fields terminated by ','
lines terminated by '\n' starting by 'start:'
from teacher_class where t_name = '韓信';
select * into outfile 'e:/amp/four'
fields terminated by '\t' enclosed by 'x'
lines terminated by '\n' starting by 'start:'
from teacher_class where t_name = 'jjj';
注意:
常規的,所有的記錄,應該通過行來顯示
例外是保存二進制數據:
//
select * into outfile '/usr/application/www' from table_name where name = "jjj";
Blob binary
使用 into dumpfile
select * into dumpfile 'e:/amp/six' from teacher_class where t_name = 'jjj' limit 1;
- 新增數據Insert&replace&loaddata
Insert into tbl_name (字段列表)values (值列表)
可以不將所有的字段都插入數據。
如果說需要完成部分字段的插入,需要必須存在 字段列表
沒有插入的字段,使用默認值:
insert into teacher_class (t_name) values ('張三豐');
如果是插入部分字段, 可以使用下面的set語句:
insert into teacher_class set t_name='張無忌';
insert into teacher_class set t_name='趙敏', c_name='武術';
值列表的語法,可以一次性插入多條數據:
每條數據采用記錄構造符 括號完成即可:
insert into teacher_class (t_name, c_name) values
('張君寶', '太極'),
('楊過', '黯然銷魂掌');
插入數據時,如果主鍵沖突會如何?
默認有 主鍵約束,不會插入成功
但是可以在insert語法內,控制
在主鍵沖突時,改成執行更新操作。
Update 后 不跟 set。
insert into teacher_class (id, t_name, c_name) values
(13, '楊露嬋', '太極')
on duplicate key update
t_name='楊露嬋', c_name='太極'
;
插入的數據源:
除了使用自定義數據外,
還可以是使用 select 語句
查詢到數據,作為插入的數據源。
insert into teacher_class (t_name, c_name) select t_name, c_name from teacher_class;
數據可以來源于其他數據表,要求,字段數量和類型一致即可:
insert into teacher_class (t_name, c_name) select t_name, class_name from teacher;
通過強制使用 default關鍵字,或者default()函數,使用默認值;
insert into teacher values
(13, 'xxx', 'yyy', default),
(14, 'xxx', 'yyy', default(days))
;
Replace
主鍵或唯一索引沖突,則替換
否則插入。
replace into teacher values
(1, '韓非', '法家', 30);
replace into teacher values
(15, '韓非', '法家', 30);
Load data infile "file" into table tbl_name;
導入 select * into outfile 'file' 命令
導出的內容;
上面兩個命令 互補。
注意:
導入時,涉及到數據增加,需要考慮,
是否沖突的情況。
通常,可以在導出時,將主鍵導出成null。
利用自動增長的特性。可以形成新的主鍵:
同樣:
在導入數據時,需要同樣指定數據的分割,
起止符號等。
保證 導出數據的格式與導入數據需要的格式
是一致的即可
刪除數據:Delete
允許使用條件(刪除符合條件的數據)
允許使用 limit :
限制刪除的記錄數。
Limit N;
常見的是
Limit 配合 order by來使用:
先將結果排序,再刪除固定數量的記錄:
delete from teacher order by days limit 10;
只有 order by 是沒有意義的
;
允許連接刪除:允許使用類似join的語法,同時刪除多個表內的記錄;需要先提供表名,再提供連接條件;可以拆分成 delete one,deletetwo...
delete from one,two using one join two on one.public_field=two.public_field where one_id=2;
清空表:truncate
類似delete from table;
truncate teacher;
truncate:不會返回刪除的記錄數. 會重建自動增長的主鍵
delete逐行刪除
,truncate刪除表,新建表
- 更新數據
replace,insert onduplicate key update
update where order by limit;
多表更新:
update one join two on one.public_field=two.public_field set one_data='x',two_data='y' where one_id = 3;
- 備份還原
方案1:
適用于 mysiam表:
直接將 tbl_name.frm
Tbl_name.myd
Tbl_name.myi
三個文件,保存,備份即可。
需要的時候,直接解壓到移動
到相應的數據庫目錄內即可
注意,如果是同樣的方法,處理的
innodb表結構的文件。
則使用showtables時,也可以看到
但是不能使用的;
方案2:
通用的方案:
思路是:將建表結構,與插入數據的sql語句生成并保存,下次如果需要該結構和數據
直接將數據語句 執行即可。
利用 mysql提供的工具完成的:
不是sql語言的一部分。
不需要在 mysql命令行客戶端執行,
直接運行即可。
將備份的數據庫還原:
就是將剛剛生成的sql語句,執行即可;
將備份的數據庫還原:
就是將剛剛生成的sql語句,執行即可。
在mysql客戶端,直接執行即可:
如何執行 保存在文件內的sql語句:
使用 source 指令,可以指定需要執行sql語句的源代碼文件:
常用的備份操作:
1,備份整個數據內的表:
Mysqldump -uroot -p db_name > bak.sql
2,備份數據庫內的某張表:
mysqldump -uroot -p php_one teacher_class > e:/php_one_teacher_class.sql
mysqldump -uroot -p php_one teacher_class tbl_name1 tbl_name2 tbl_name3 > e:/php_one_teacher_class.sql
- 視圖
創建視圖:
Create view view_name
AS select_statement;
create view v_teacher as select id,t_name from info_teacher;
視圖就是一個存在與數據庫中的虛擬表了;視圖,本身沒有數據,只是通過執行相應的select語句完成獲得相應的數據。
視圖管理
刪除視圖:
Drop view [if exists] view_name;
修改視圖:
Alter view view_name
修改視圖內,所使用的字段的名稱:
視圖名稱后,使用 (字段列表即可)
縮減業務邏輯:
通過視圖還可以,使復雜的業務邏輯,簡單的完成,先使用視圖完成一定的邏輯,在在視圖的基礎上,完成另外的邏輯。
通常,視圖完成的邏輯,都是相對來說比較基礎的邏輯。
create view join_info as select tc.id as tc_id, t_name, c_name, days from join_teacher_class as tc left join join_teacher as t on tc.t_id=t.id left join join_class as c on tc.c_id=c.id;
select * from join_info;
視圖的執行過程:
視圖的執行算法:
存在兩種執行算法:
1,merge
2,temptable
指的是一個視圖是在什么
時候執行,依據哪些方式執行:
merge:合并的執行方式,每當執行的時候,現將我們視圖的sql語句
與外部查詢視圖的sql語句,混合在一起。最終執行:
Temptable:臨時表,模式,每當查詢的時候,將視圖所使用select語句
生成一個結果的臨時表。再在當前的臨時表內進行查詢。
當用戶創建視圖時,mysql默認使用一種 undefine的處理算法:就是會自動在
合并和臨時表內進行選擇。
- 事務
一組sql語句操作單元。
組內所有sql語句完成一個業務。
如果整組成功:意味著全部sql都實現
如果其中任何一個失敗。意味著整個操作都失敗。
失敗,意味著整個過程都是沒有意義的。應該
是數據庫回到 操作前的初始狀態。
上面的特性,就是事務。
如何處理?
1,失敗后,可以回到開始位置
2,沒都成功之前,別的用戶(進程,會話)是不能看到
操作內的數據修改的。
思路:就是在 一組操作之間,設計一個記號,備份點。
實現:
利用 innodb存儲引擎的,事務日志功能:
SQL執行分成2個階段:1,執行階段 2,將執行結果,提交的數據庫的階段;
其中,我們的事務日志,就是保存執行階段的結果.如果用于選擇提交,則才將執行的結果提交到數據庫;默認的執行方式叫自動提交,執行完畢,自動完成提交,因此.
需要關閉自動提交功能.
自動提交
存在一個系統的變量,
Autocommit 可以對自動提交進行配置
show variables like autocommit
;
關閉后,再次執行相應的更新語句:
發現,在其他連接中,查看數據,
沒有發生變化,因為結果沒有提交.
提交或回滾。
在此基礎上,執行完所有的sql語句。
判斷是否都成功(出現錯誤,包括語法錯誤,和邏輯錯誤
服務器錯誤)。
成:將結果提交
利用 commit
敗:回到開始位置。
Rollback
常見的事務的指令:
開啟事務
Start transaction; 可以使用begin。
關閉自動提交。如果事務結束了,
成或敗,都會將自動提交機制,回到start時的狀態。
成功:commit;
失敗:rollback;
限定:
在innodb下生效(DBD)
事務的特點:
1,原子性。
2,一致性。
3,隔離性。
4,持久性。
ACID。
- 觸發器
監聽數據進行操作:在當前的表上,設置一個對每行數據的一個監聽器,監聽相關事件,每當事件發生時.會執行一段有SQL完成的一段功能代碼;
觸發器的元素:事件,執行代碼
創建觸發器: create trigger 名字 事件 執行代碼;
事件:insert,delete,update
事件的時機:執行之前和執行之后,after/before
由時機和事件在一起形成了6種事件:before insert,before delete...
事件規定在哪個表上的什么時機的什么動作上;
觸發程序:特定事件發生,即觸發:
update addMoney set stu_money = stu_money + 20 where id = 1;
觸發器不能同名,目前MySQL只支持一類事件設置一個觸發器
create trigger my_trigger after update on addMoney for each row update class set cz_money=cz_money+20;
管理觸發器:
刪除:
Drop trigger trigger_name;
查看:
Show create trigger trigger_name;
在觸發器內,獲得觸發該觸發程序時的數據:
Old new
利用 觸發程序內的 new 和 old來完成;
create trigger my_trigger after update on addMoney for each row update class set cz_money=cz_money+(old.stu_money-new.stu_money);
Old:
監聽事件所在表上的數據,在事件發生之前時的數據。舊的數據。
New:
監聽表上,事件發生之后,新處理完畢的數據。
數據,就是觸發該事件的記錄。
事件是insert呢? 不能使用old
事件是 delete呢?不能使用new
如果一個觸發程序,由多條SQL語句組成;
應該:1.語句組成語句塊(begin end)來標示語句塊.
2.語句塊的語句需要獨立的語句結束符,分號;
命令行:由于觸發器程序內使用分號作為語句結束符,那么當命令行客戶端碰到分號時,就應該理解成觸發程序內子語句結束,而不是整個觸發器的語句結束.
應該通過修改命令行的語句結束符達到目的.delimiter語句可以完成設置語句結束符;
drop trigger ruxue;
delimiter $$
create trigger ruxue after insert on czbk_student for eache row
begin
update class set student_count = stu_count +1;
update class set cz_money=cz_money+20;
end
$$
delimiter;
SQL編程
SQL:結構化查詢語言。
是一門編程語言。是由于管理數據的編程語言。
元素:
數據,
數據類型,
變量,
函數,
控制流程,
運算符 ,
注釋;
注釋:
行:
--[空格]
塊:
/* */
結束符:
命令行:\g \G
可以使用 delimiter 來修改語句結束符
Delimiter $$
變量:
字段名就是變量。
php有許多系統默認變量例如:
show variables like 'char%';
用戶自定義變量:
定義一個變量:set
Set 變量名 = 變量值。
注意,為了區分 系統變量和字段與用戶自定義變量,需要在用戶變量前,增加@標識符。
set @who = "haha";
通過 select 語句可以獲得當前的變量的值:
select @who;
Set是專門的為變量賦值的形式,甚至可以子查詢
set @total = (select count(*) from join_teacher);
定義一個變量 select info:
Select 字段列表 表達式 。。。 Into 變量列表。
select 10,14,20 into @a,@b,@c;
select c_name from join_class where id = 2 into @c_name;
注意,select into @var 要求,只能返回一行。如果返回多行,會語法錯誤,或者只將最后一行的數據,注入到變量內。
//會報錯
select c_name from join_class where 1 into @c_name;
利用 select語句的部分表達式達到為變量賦值的目的:
select @who = 'xiaoming'; //=是關系判斷
使用 := 的形式;
select @who := 'xiaoming';
注意,=應該賦值,但是在 select語句內,就成了 關系等于。使用專門的賦值運算符 :=。
同樣適用于 set。
set @i := '111';
select * from teacher where @who:='xiaoming';
使用變量是在表達式,或者使用select查詢到即可。
1,作用域。用戶定義的函數,是全局的(函數內可用)。存在局部作用域變量,函數內定義的變量。
2,有效期。會話結束(連接結束)。
運算符:
- 函數
內置函數
數值:
Rand()得到1-0之間的隨機數
select rand();
如何得到5到10?
5+(0-5)
5+rand()*5;
取整:
select floor(rand()*5+5);
格式化:
format
select format(2132432.12323,2); //2位小數顯示
時間日期:
Now();
Unix_timestamp();
select unix_timestamp();
select from_unixtime(123456);
select from_unixtime(unix_timestamp());
字符串:
Concat()字符串連接
Substring(原字符串,開始位置,截取長度);
開始位置 從1開始
Char_length();
Length();
Lpad(需要補足的字符串,補足后的長度,補字符串);
左邊補足:
其他:
Md5()
select substring("hahahaha",2,2);
select length('你好'); //4
select char_length("你好"); //2
select lpad("1",3,"0"); //001
select md5("2");
select password("2");
select sha1("332");
數值函數
Abs(X),絕對值 abs(-10.9) = 10
Format(X,D),格式化千分位數值 format(1234567.456, 2) = 1,234,567.46
Ceil(X),向上取整 ceil(10.1) = 11
Floor(X),向下取整 floor (10.1) = 10
Round(X),四舍五入去整
Mod(M,N) M%N M MOD N 求余 10%3=1
Pi(),獲得圓周率
Pow(M,N) M^N
Sqrt(X),算術平方根
Rand(),隨機數
TRUNCATE(X,D) 截取D位小數
時間日期函數
Now(),current_timestamp(); 當前日期時間
Current_date();當前日期
current_time();當前時間
Date(‘yyyy-mm-dd HH;ii:ss’);獲取日期部分
Time(‘yyyy-mm-dd HH;ii:ss’);獲取時間部分
Date_format(‘yyyy-mm-dd HH;ii:ss’,’ %D %y %a %d %m %b %j');
Unix_timestamp();獲得unix時間戳
From_unixtime();//從時間戳獲得時間
字符串函數
LENGTH (string ) //string長度,字節
CHAR_LENGTH(string) //string的字符個數
SUBSTRING (str , position [,length ]) //從str的position開始,取length個字符
REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替換search_str
INSTR (string ,substring ) //返回substring首次在string中出現的位置
CONCAT (string [,... ]) //連接字串
CHARSET(str) //返回字串字符集
LCASE (string ) //轉換成小寫
LEFT (string ,length ) //從string2中的左邊起取length個字符
LOAD_FILE (file_name ) //從文件讀取內容
LOCATE (substring , string [,start_position ] ) //同INSTR,但可指定開始位置
LPAD (string ,length ,pad ) //重復用pad加在string開頭,直到字串長度為length
LTRIM (string ) //去除前端空格
REPEAT (string ,count ) //重復count次
RPAD (string ,length ,pad) //在str后用pad補充,直到長度為length
RTRIM (string ) //去除后端空格
STRCMP (string1 ,string2 ) //逐字符比較兩字串大小
流程函數:
CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END 多分支
IF(expr1,expr2,expr3) 雙分支。
聚合函數
Count()
Sum();
Max();
Min();
Avg();
Group_concat()
其他常用函數
Md5();
Default();
- 自定義函數
要素:
函數名,
參數列表,
函數體,
返回值;
語法:
定義:
Create function 函數名 (參數列表) 返回值類型
函數體
delimiter $$
create function sayHi() returns varchar(20);
begin
return 'Hi';
end
$$
delimiter;
//調用
select sayHi();
注意:函數是與當前的數據庫綁定的,可以使用庫名.函數名的形式調用;
select one.sayHi();
sql中的流程控制:
分支
If 條件1 then
條件1滿足執行的語句
Elseif 條件2 then
條件2滿足執行的語句
….
Else
上面的條件全都不滿足,執行的語句
End if;
Elseif 和 else 都是可以省略的。
循環
While 條件 do
循環體
End while
循環的提前終止
Leave break 終止循環
Iterate continue 終止當前循環
注意,不是根據leave和iterate所在的位置來決定終止哪個循環,而是由循環的標簽來決定的。
循環的標簽,給循環起名字。
標簽 : while
End while 標簽;
函數內使用的變量
@var的形式,相當于 全局變量,函數內和函數外通用。
函數的參數:
參數,同樣需要確定類型。
參數名 類型
一個函數,可以有多個參數,使用 逗號分割。
函數聲明的局部變量:
使用 declare聲明局部變量。 需要指定類型,可以指定默認值 default。
delimiter $$
create function func1() returns varchar(20)
begin
if hour(now(()) > 18 then
return 'night';
else
return 'day';
end if;
end
$$
delimiter;
delimiter $$
create function func2() returns int
begin
-- 1-10的和
set @i = 1;
set @sum = 0;
while @i<=10 do
set @sum = @sum + @i;
set @i = @i + 1;
end while;
return @sum;
end
$$
delimiter
delimiter $$
create function func2() returns int
begin
-- iterate
set @i = 1;
set @sum = 0;
w:while @i<10 do
set @i = @i + 1;
if @i = 5 then
-- iterate w;
iterate w;
end if;
set @sum = @sum + @i;
end while w;
return @sum;
end
$$
delimiter
delimiter $$
drop function if exists sayHi;
create function sayHi(user_name varchar(10)) returns varchar(20)
begin
return concat("Hi ",user_name);
end
$$
delimiter;
delimiter $$
drop function if exists func2;
create function func2() returns int
begin
-- 1-10的和
declare i int default 0;
declare total int default 0 ;
while i<=10 do
set total = total + i;
set i = i+ 1;
end while;
return total;
end
$$
delimiter;