.數(shù)據(jù)庫(kù)
數(shù)據(jù)庫(kù)的發(fā)展: 文件系統(tǒng)(使用磁盤文件來(lái)存儲(chǔ)數(shù)據(jù))=>第一代數(shù)據(jù)庫(kù)(出現(xiàn)了網(wǎng)狀模型,層次模型的數(shù)據(jù)庫(kù))=>第二代數(shù)據(jù)庫(kù)(關(guān)系型數(shù)據(jù)庫(kù)和結(jié)構(gòu)化查詢語(yǔ)言)=>新一代數(shù)據(jù)庫(kù)("關(guān)系-對(duì)象"型數(shù)據(jù)庫(kù));
層次模型是一種導(dǎo)航結(jié)構(gòu),
優(yōu)點(diǎn):分類管理虽缕,如果查詢同一類的數(shù)據(jù)是很方便的驾讲。
缺點(diǎn):如果查詢很多不是同一類的數(shù)據(jù),效率就很低了
層次結(jié)構(gòu)可以造成數(shù)據(jù)無(wú)效大渤,比如張經(jīng)理管理了一個(gè)員工叫張三缘眶,李經(jīng)理也管理了一個(gè)叫張三两蟀,我們無(wú)法區(qū)分張三是一個(gè)人還是兩個(gè)人祝旷。
網(wǎng)狀模型解決了層次模型數(shù)據(jù)無(wú)效的問(wèn)題面殖,但是沒(méi)有解決導(dǎo)航問(wèn)題,深層率查詢,效率很低.
關(guān)系模型中竖哩,每個(gè)表都是獨(dú)立的,通過(guò)公共字段來(lái)建立關(guān)系脊僚。優(yōu)點(diǎn):表是獨(dú)立的相叁,需要什么數(shù)據(jù)就到那個(gè)表中查詢。
缺點(diǎn):多表查詢的時(shí)候效率低下吃挑。
關(guān)系:兩個(gè)表的公共字段叫關(guān)系
- SQL語(yǔ)句
Structured Query Language 結(jié)構(gòu)化查詢語(yǔ)言,是用來(lái)操作關(guān)系型數(shù)據(jù)庫(kù)的.常用的關(guān)系型數(shù)據(jù)有:
Access,MySQL,Sql Server,Oracls.
標(biāo)準(zhǔn)的SQL是所有關(guān)系型數(shù)據(jù)庫(kù)都支持的操作語(yǔ)句,標(biāo)準(zhǔn)的SQL也叫作SQL-92.但是每個(gè)數(shù)據(jù)庫(kù)在標(biāo)準(zhǔn)的基礎(chǔ)上又?jǐn)U展了自己的東西.所有,一個(gè)數(shù)據(jù)庫(kù)的拓展語(yǔ)句在在其他數(shù)據(jù)庫(kù)不能運(yùn)行.
- 連接數(shù)據(jù)庫(kù)
需要的參數(shù): Host (-h),username (-u), password (-p),port(默認(rèn)3306) (-P)
mysql -u root -h localhost -p
退出數(shù)據(jù)庫(kù):exit,quit,\q
數(shù)據(jù)庫(kù)操作:數(shù)據(jù)庫(kù)的本質(zhì)是一個(gè)文件.操作數(shù)據(jù)庫(kù)的軟件叫做數(shù)據(jù)庫(kù)管理系統(tǒng).
/**
* 創(chuàng)建數(shù)據(jù)庫(kù)
* 如果創(chuàng)建的數(shù)據(jù)庫(kù)已經(jīng)存在,會(huì)報(bào)錯(cuò).所以一般要進(jìn)行判 斷.
* 同時(shí),如果數(shù)據(jù)庫(kù)名是關(guān)鍵字或者純數(shù)字,需要加上反引 號(hào),最好的辦法是任何時(shí)候都加反引號(hào)
*/
Create database db_name [charset=字符編碼]
Create database if not exists db_name [charset=字符編碼]
/**
*/
2. 查詢數(shù)據(jù)庫(kù)
show database;
3.顯示數(shù)據(jù)庫(kù)的創(chuàng)建語(yǔ)句
show create database create db_name;
4. 更改數(shù)據(jù)庫(kù)
alter database db_name [option];
//eg:alter database haha charset=gbk;
5. 刪除數(shù)據(jù)庫(kù):如果數(shù)據(jù)庫(kù)不存在會(huì)報(bào)錯(cuò)
drop database if exists db_name;
6. 選擇數(shù)據(jù)庫(kù)
use db_name;
- 數(shù)據(jù)庫(kù)表的操作
幾個(gè)概念:
行row:也叫記錄,一行就是一條記錄
列(column) : 一列就是一個(gè)字段,字段也叫屬性,一個(gè)表中包含多個(gè)字段
1.創(chuàng)建表:(primary key)主鍵不能重復(fù),不能為空,一個(gè)表只能有一個(gè)主鍵,主鍵可以由多個(gè)字段組成.
create table table_name(
field1 data_type [null | not null][default][auto_increment][primary key],
field2 data_type,
...,
);
2. 查看所有表
show tables;
3.顯示創(chuàng)建表的SQL語(yǔ)句
show create table table_name [\G];
4.顯示表結(jié)構(gòu)
describe [desc] table_name;
5.刪除表
drop tabel table_name1,table_name2,...;
數(shù)據(jù)類型:
int,decimal(總位數(shù),小數(shù)位數(shù)) 存小數(shù) decimal(10,3), char(1):定長(zhǎng), varchar(10):可變長(zhǎng)度, text:大段文字
- 數(shù)據(jù)操作
1.插入數(shù)據(jù):插入字段可以和數(shù)據(jù)庫(kù)中字段順序不一致,但是值和插入的字段順序必須一致. 如果插入字段省略掉,插入的值和數(shù)據(jù)庫(kù)表的字段的順序和個(gè)數(shù)都要一致.
insert into table_name (field1,field2) values (value1,value2);
//自動(dòng)增長(zhǎng)的插入
insert into student values (null,"name","female","shenzhen",22);
//默認(rèn)值的插入
insert into student values (null,"name","female",default,33);
2.數(shù)據(jù)的修改
update table_name set field1=value1,field2=value2 [where 條件];
//eg:
update student set gender="male" where name="xiaoming";
update student set gender = "female";
3.刪除數(shù)據(jù)
delete from table_name [whre 條件];
delete from student where name = "haha";
delete from student; //所有的數(shù)據(jù)都刪除了
4 .查詢數(shù)據(jù)
select 列名 from 表 [where 條件] [order by 排序字段 asc|desc] [limit [起始位置默認(rèn)0],或者的記錄數(shù)量];
升序:asc
降序:desc
默認(rèn)升序
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
- 運(yùn)算符
比較運(yùn)算符: > , >=, <, <=, = , <>(不等于)
邏輯運(yùn)算符: and, or, not
聚合運(yùn)算:
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本身是一個(gè)框架,它的功能是由PHP拓展而來(lái)的,要通過(guò)PHP連接數(shù)據(jù)庫(kù),必須開啟PHP連接MySQL的功能,就是PHP的MySQL拓展. 在php.ini中,把extension=php_mysql.dll 開啟,重啟服務(wù)器.
1.php連接數(shù)據(jù)庫(kù)
$connect = mysql_connect("localhost",'root','password') or die("數(shù)據(jù)庫(kù)連接失敗");
/**
通過(guò)@符號(hào)屏蔽信息
$connect = @mysql_connect("localhost",'root','password') or die("數(shù)據(jù)庫(kù)連接失敗");
*/
2. 終止執(zhí)行:exit(),和die();
die()停止執(zhí)行,把生成的代碼發(fā)送到客戶端.
3. 選擇數(shù)據(jù)庫(kù)
方法1: 執(zhí)行 use db_name
mysql_query("use database_name") or die("數(shù)據(jù)選擇失敗");
方法二:
mysql_select_db("database_name") or die ("數(shù)據(jù)庫(kù)選擇失敗");
4. 設(shè)置字符編碼
mysql_query("set names utf8");
5.查詢數(shù)據(jù)庫(kù) : 返回一個(gè)資源類型的數(shù)據(jù)
$results = mysql_query("select * from products"); //resource type
mysql_fetch_row: 取出結(jié)果集中數(shù)據(jù)
開始匹配,指針指向第一個(gè)記錄.取出資源中的當(dāng)前記錄,匹配成索引數(shù)組,指針指向下一條記錄.
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>";
}
這種方法讀取數(shù)據(jù)缺點(diǎn):數(shù)據(jù)庫(kù)字段發(fā)生變化,會(huì)影響數(shù)組的索引編碼.
5.2: mysql_fetch_assoc : 形成關(guān)聯(lián)數(shù)組
數(shù)組的鍵和數(shù)據(jù)表的字段名相關(guān)聯(lián)
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: 匹配成對(duì)象,通過(guò)->訪問(wèn)
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. 關(guān)閉連接 mysql_close($connect);
頁(yè)面執(zhí)行完畢后,所有變量全部銷毀,可以不用手動(dòng)釋放資源.
數(shù)據(jù)的導(dǎo)入與導(dǎo)出钝荡,用phpMyAdmin工具
1月 5日
MySQL 學(xué)習(xí)
- 簡(jiǎn)介
- 數(shù)據(jù)庫(kù)系統(tǒng): DataBase System = 數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS,DataBase Management System) + 數(shù)據(jù)庫(kù) (DataBase) + 管理員(Manager)
DBS = DBMS + DB;
對(duì)大量信息進(jìn)行管理的高效解決方案,按照數(shù)據(jù)結(jié)構(gòu)來(lái)組織,存儲(chǔ)和管理數(shù)據(jù)的庫(kù).
關(guān)系型數(shù)據(jù)庫(kù)系統(tǒng):建立在關(guān)系模型上的數(shù)據(jù)庫(kù)系統(tǒng)
關(guān)系模型: 日常生活的實(shí)體和實(shí)體的屬性保存到數(shù)據(jù)庫(kù)時(shí),處理實(shí)體結(jié)構(gòu)的方式:
數(shù)據(jù)結(jié)構(gòu)可以規(guī)定,同類數(shù)據(jù),結(jié)構(gòu)一致.數(shù)據(jù)之間的關(guān)系可以設(shè)置實(shí)體之間的聯(lián)系.
Nosql: Not only sql,非關(guān)系型數(shù)據(jù)庫(kù)
mongoD,MemBase
對(duì)象型數(shù)據(jù)庫(kù).
關(guān)系型數(shù)據(jù)庫(kù)的幾個(gè)重要概念:
數(shù)據(jù)庫(kù)database:數(shù)據(jù)的倉(cāng)庫(kù)
表table:數(shù)據(jù)是保存在表內(nèi),保存在一個(gè)表內(nèi)的數(shù)據(jù),應(yīng)該具有相同的數(shù)據(jù)格式.
行和列:行用于記錄數(shù)據(jù),列用于規(guī)定數(shù)據(jù)的格式
MySQL是基于C/S架構(gòu)的.
- MySQL常用的操作
(1)數(shù)據(jù)庫(kù)操作
//創(chuàng)建數(shù)據(jù)庫(kù)
create database `db_name` [數(shù)據(jù)庫(kù)選項(xiàng)];
//查詢當(dāng)前存在的數(shù)據(jù)庫(kù)
show databases;
//查詢數(shù)據(jù)庫(kù)的創(chuàng)建語(yǔ)句
show create database db_name;
//刪除數(shù)據(jù)庫(kù)
drop database db_name;
//修改數(shù)據(jù)庫(kù)信息
alter database db_name [修改指令];
alter database db_class character set utf8;
//修改數(shù)據(jù)庫(kù)的名字
1.直接修改文件夾的目錄名
2.將數(shù)據(jù)全部導(dǎo)出,新建一個(gè)數(shù)據(jù)庫(kù),再導(dǎo)入數(shù)據(jù),刪除舊數(shù)據(jù)庫(kù)
3.新建數(shù)據(jù)庫(kù),把就數(shù)據(jù)庫(kù)的表移到新數(shù)據(jù)庫(kù),刪除就數(shù)據(jù)庫(kù)
(2)表操作
可以通過(guò).(點(diǎn))語(yǔ)法,指明數(shù)據(jù)表所屬的數(shù)據(jù)庫(kù)
create table `db_name`.`table_name`(
field1 type,
field2 type
);
use db_name 只是設(shè)定了默認(rèn)數(shù)據(jù)庫(kù),不影響操作其它數(shù)據(jù)庫(kù).選擇了默認(rèn)數(shù)據(jù)庫(kù),只會(huì)影響默認(rèn)行為.可以操作任意的數(shù)據(jù)庫(kù)
//創(chuàng)建表
create table info_student(
`name` varchar(20),
`stu_no` varchar(20)
);
//查看表
show tables [like 'pattern'];like pattern部分表示獲得規(guī)定規(guī)則的表名. % 為通配符,表示任意字符的任意組合.同樣適用于數(shù)據(jù)庫(kù)查詢:
show databses like 'pattern';
//查看表的結(jié)構(gòu)
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;
//同時(shí)修改多個(gè)
rename table tb1 to new_tb1,tb2 to new_tb2;
//支持跨數(shù)據(jù)庫(kù)重命名
//可以利用這個(gè)操作為數(shù)據(jù)庫(kù)重命名: 創(chuàng)建一個(gè)新的數(shù)據(jù)庫(kù),舊數(shù)據(jù)內(nèi)的表,都rename到新的數(shù)據(jù)庫(kù).刪除舊的數(shù)據(jù)庫(kù).
rename table exam_user to `db_name`.table_name;
//修改列的定義
alter table tb_name [add | drop | change | modify]
//增加一個(gè)新列
alter table table_name add filed_name type;
//刪除一個(gè)列
alter table tb_name drop field;
//修改一個(gè)列的定義
alter table tb_name modify field varchar(90);
//重命名一個(gè)列
alter table table_name change old_field new_field type;
//修改表選項(xiàng)
alter table table_name character set utf8;
(3)數(shù)據(jù)操作
//創(chuàng)建數(shù)據(jù)(插入數(shù)據(jù))
insert into table_name (fields) values (value1,...);
insert into student (name,id) values (`name`,`09332`);
//獲取數(shù)據(jù)(查詢數(shù)據(jù))
select fields(*) from table_name condition;
select * from students;
select name,id from students where 1;
select * from students where score>=80;
//刪除數(shù)據(jù)
delete from table_name condition;
delete from students where score<=20;
//修改數(shù)據(jù)
update table_name set field1 = value1,... condition;
update students set score = 90 where id = 0922;
- SQL
Structured Query Language:結(jié)構(gòu)化查詢語(yǔ)言;
針對(duì)操作對(duì)象不同,分成不同語(yǔ)言:
1.數(shù)據(jù)操作(管理)語(yǔ)言.DML;
查詢,獲得數(shù)據(jù).DQL;
管理,增加,刪除,修改數(shù)據(jù).DML
2.數(shù)據(jù)定義語(yǔ)言(對(duì)保存的數(shù)據(jù)的格式進(jìn)行定義) DDL;
3.數(shù)據(jù)庫(kù)控制語(yǔ)言 (針對(duì)數(shù)據(jù)庫(kù)軟件服務(wù)進(jìn)行操作) DCL;
- 字符集
字符的集合;構(gòu)成分兩部分:1.字符的集合,展示用,2.字符的編碼,保存和處理.
MySQL支持常見的字符集,查看: show character set;
字符集決定的是字段的數(shù)據(jù)以何種形式保存.
如果通過(guò)客戶端操作服務(wù)器,那么客戶端和服務(wù)器端之間進(jìn)行數(shù)據(jù)通信,要保證編碼一致.可以將互相發(fā)送的數(shù)據(jù),轉(zhuǎn)換成目標(biāo)可以接收的編碼數(shù)據(jù).
通過(guò)MySQL配置:
character_ser_client 客戶端發(fā)送數(shù)據(jù)編碼
character_ser_results 客戶端接收數(shù)據(jù)的編碼
通過(guò)指令 show variables like 'character_set_%';查看當(dāng)前的字符編碼集
設(shè)置變量: set 變量名=值;
set character_set_client = utf8;告知服務(wù)器,客戶端發(fā)送的數(shù)據(jù)是utf8編碼;
如果需要從服務(wù)器返回?cái)?shù)據(jù),還需要設(shè)置服務(wù)器發(fā)送給客戶端的編碼:set character_set_results = utf8;服務(wù)器在發(fā)送數(shù)據(jù)時(shí),才能轉(zhuǎn)成客戶端認(rèn)識(shí)的編碼;
對(duì)于普通的簡(jiǎn)單項(xiàng)目統(tǒng)一的操作可以使用 set names utf8;完成設(shè)置
連接層編碼: set character_set_connection = utf8;
set names 操作可以同時(shí)設(shè)置客戶端接收的數(shù)據(jù)格式,客戶端發(fā)送的數(shù)據(jù)格式,連接層編碼三個(gè).
數(shù)據(jù)編碼轉(zhuǎn)換過(guò)程: client->connection->[服務(wù)器內(nèi)部編碼]->results
- MySQL數(shù)據(jù)類型
1.整型
類型 | 字節(jié) | 最小值(有符號(hào)/無(wú)符號(hào)) | 最大值(有符號(hào)/無(wú)符號(hào)) |
---|---|---|---|
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 |
在定義字段時(shí),可以使用unsigned標(biāo)示無(wú)符號(hào),默認(rèn)為有符號(hào).
create table tbl_int(
a tinyint unsigned,
b tinyint
);
定義顯示寬度:通過(guò)規(guī)定數(shù)據(jù)的顯示寬度,達(dá)到統(tǒng)一顯示的目的. 類型(M) ,M表示顯示的最小寬度是多少. 如果需要用前導(dǎo)零值填充,使用 zerofill;不會(huì)影響數(shù)的范圍,寬度大的不影響,不會(huì)截取;
alter table tbl_int add c tinyint(2) zerofill;
insert into tbl_int values (0,123,2);
2.浮點(diǎn)數(shù)
float 單精度,默認(rèn)精度位數(shù)為6位;
double 雙精度,默認(rèn)16位
控制數(shù)值的范圍 Type(M,D),D表示所有的數(shù)值的位數(shù)(不包括小數(shù)點(diǎn)和符號(hào));
D表示小數(shù)位數(shù);
支持科學(xué)計(jì)數(shù)法: 1.322*10^3;
3.定點(diǎn)數(shù)
decimal(M,D);M總位數(shù),D小數(shù)位數(shù),M默認(rèn)10,D默認(rèn)0
小數(shù)也支持zerofill和unsigned
create table number1(
send_money decimal(10,2) zerofill;
);
insert into number1 values (123.43);
insert into number1 values (122332.564);
- 日期和時(shí)間
DateTime 年月日時(shí)分秒
Timestamp 時(shí)間戳,存儲(chǔ)時(shí)整型,表示時(shí),日期時(shí)間
Date 年月日
支持0值:表示當(dāng)前沒(méi)有規(guī)定 2015-04-0 表示4月整個(gè)月.
insert into dt_1 values (0,0);
Time 類型: 1,表示一天中的時(shí)間 2,時(shí)間間隔,在表示時(shí)間間隔時(shí),可以用天表示 格式: 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:此時(shí)表示日期的范圍,不是1000-9999
而是 1901-2155 一個(gè)字節(jié)(256間隔)
在實(shí)際項(xiàng)目中,通常保存的都是Unix時(shí)間戳,直接用整型保存在數(shù)據(jù)庫(kù),不是MySQL提供的timestamp類型;
- 字符串類型
char(M): 固定長(zhǎng)度
varchar(M): 可變長(zhǎng)度
M在varchar中表示允許的最大長(zhǎng)度,char內(nèi)表示嚴(yán)格限定的長(zhǎng)度
char(5) | varchar(5) | ||
---|---|---|---|
'' | 5個(gè)字符 | 一個(gè)字節(jié) | varchar需要一個(gè)字節(jié)保存字符串總長(zhǎng)度 |
'abc' | 5 | 4 | |
'abcdf' | 5 | 6 | |
'abcdefg' |
M表示的是字節(jié),而不是字節(jié)數(shù),但是總的長(zhǎng)度的使用時(shí)按照字節(jié)計(jì)算的
create table tb_2(
a varchar(65535) //會(huì)報(bào)錯(cuò),最大長(zhǎng)度是21845, 三個(gè)字節(jié)21845 * 3 = 65535
);
create table tb_3(
a varchar(65535)
) character set gbk; //報(bào)錯(cuò),最大長(zhǎng)度是32767,2個(gè)字節(jié) 2 * 32767 = 65535
字段的最大長(zhǎng)度除了類型本身之外,記錄的總長(zhǎng)度也是有限制的.
真實(shí)的varchar長(zhǎng)度:
記錄存在總長(zhǎng)度65535限制
特點(diǎn):當(dāng)類型數(shù)據(jù)超過(guò)255個(gè)字符時(shí),采用2個(gè)字節(jié)表示長(zhǎng)度 65535-2 = 65533
整條記錄,需要一個(gè)額外的字節(jié),用于保存當(dāng)前字段的null值.除非所有的字段都不是null,這個(gè)字節(jié)才可以忽略.一個(gè)記錄,不論有多少個(gè)字段存在null,都是使用統(tǒng)一的一個(gè)字節(jié)表示.而不是每個(gè)字段一個(gè)字節(jié)
Text類型: 2 ^ 16,文本類型,tinytext,longtext;
枚舉 enum
值是否能為空: null || notnull,如果為not null,在插入時(shí),缺少值,會(huì)插入失敗;
默認(rèn)值屬性: default value來(lái)聲明. 在沒(méi)有為該字段設(shè)置值時(shí)啟用,而且默認(rèn)值的設(shè)置,需要使用固定值;
常見的是一個(gè)字段不能為空,而且存在默認(rèn)值;
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:
可以唯一標(biāo)示,某條記錄的字段或者是字段的集合,就是主鍵.主鍵可以是真實(shí)實(shí)體的屬性.常用的是使用一個(gè)與實(shí)體信息不相關(guān)的屬性作為唯一標(biāo)識(shí).主鍵與業(yè)務(wù)邏輯不發(fā)生關(guān)系,只是用來(lái)標(biāo)識(shí)記錄.
1.字段上設(shè)置:主鍵字段在插入時(shí)不能為空,或者沖突
create table reacher(
t_id int primary key,
t_name varchar(5);
class_name varchar (6);
days tinyint unsigned
);
2.在定義完字段后,可以定義多列主鍵(組合主鍵):一個(gè)主鍵內(nèi)包含多個(gè)字段,而不是多個(gè)字段的主鍵.只需要一個(gè)唯一標(biāo)識(shí)即可,MySQL規(guī)定只能存在一個(gè)主鍵;
常見的主鍵設(shè)計(jì),每個(gè)表都應(yīng)該存在一個(gè)可以唯一標(biāo)識(shí)的主鍵字段,最好與實(shí)體沒(méi)有關(guān)系,不是實(shí)體屬性字段.
create table teacher(
t_name varchar(5),
class_name varchar(6),
days tinyint unsigned,
primary key(t_name,class_name);
);
字段增長(zhǎng):auto_increment,自動(dòng)增長(zhǎng)的默認(rèn)值是1,可以設(shè)置
如果插入的值小于已經(jīng)存在的主鍵的值,是可以的,如果是主鍵,不能重復(fù);
實(shí)體之間的關(guān)系:
1vs1:
兩個(gè)實(shí)體表內(nèi),存在相同的主鍵字段.如果記錄的主鍵值等于另一個(gè)關(guān)系表內(nèi)的主鍵值,則兩條記錄一一對(duì)應(yīng);
1 vs n
:一個(gè)實(shí)體對(duì)應(yīng)多個(gè)其它實(shí)體;例如,一個(gè)班級(jí)對(duì)應(yīng)多個(gè)學(xué)生
在多的那端,增加一個(gè)字段,用于指向改實(shí)體所屬的另外實(shí)體的標(biāo)識(shí)
M:N 多對(duì)多
典型的,利用一個(gè)中間表,標(biāo)識(shí)實(shí)體之間的對(duì)應(yīng)關(guān)系.中間表的每個(gè)記錄,標(biāo)識(shí)一個(gè)關(guān)系
一個(gè)M:N,
1:M,1:N來(lái)實(shí)現(xiàn)
講師主鍵 | 名字 | 班級(jí) |
---|---|---|
1 | joe | |
2 | jack |
班級(jí)主鍵 | 班級(jí)名 | 講師主鍵 |
---|---|---|
29 | 0234 | |
30 | 0907 |
講師主鍵 | 班級(jí)主鍵 |
---|---|
1 | 29 |
3 | 29 |
- 外鍵 foreign key
:如果一個(gè)實(shí)體(student)的某個(gè)字段(class_id)指向(引用)另外一個(gè)實(shí)體(class)的主鍵(class_id),就稱student實(shí)體的class_id是外鍵.被指向的實(shí)體,稱之為主實(shí)體(主表,父實(shí)體),對(duì)應(yīng)的另外一個(gè)實(shí)體稱之為從實(shí)體(從表,子實(shí)體,子表)
外鍵的作用: 保證數(shù)據(jù)的完整性,用于約束處于關(guān)系的內(nèi)的實(shí)體.增加子表記錄的時(shí)候,是否有與之對(duì)應(yīng)的父表記錄.在刪除或者更新的主表記錄時(shí),從表應(yīng)該如何處理相關(guān)的記錄.
//定義一個(gè)外鍵
在從表上在,增加一個(gè)外鍵字段,指向主表的主鍵.使用關(guān)鍵字foreign key;
foreign key (外鍵字段) references 主表名 (關(guān)聯(lián)字段)[主表記錄刪除時(shí)的動(dòng)作][主表記錄更新時(shí)的動(dòng)作];
drop table if eixsts class;
create table class (
class_id int primary key auto_increment,
class_name varchar(10) not null default `php` comment `班級(jí)名稱`
)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;
設(shè)置級(jí)聯(lián)操作:
在主表數(shù)據(jù)發(fā)生改變時(shí),與之關(guān)聯(lián)的從表數(shù)據(jù)應(yīng)該如何處理:
主表更新:on update,主表刪除 on delete
允許的聯(lián)級(jí)操作,cascade:關(guān)聯(lián)操作,如果主表被更新或者刪除,那么從表也會(huì)執(zhí)行相應(yīng)的操作.set null:設(shè)置為null,表示從表不指向任何主表記錄,restrict:拒絕主表的相關(guān)操作
修改外鍵:先刪除,再新建.通過(guò)修改表完成
alter table_name drop foreign key field;
刪除外鍵需要通過(guò)指定外鍵名稱達(dá)到目的,可以在創(chuàng)建外鍵時(shí),指定名稱或者使用MySQL默認(rèn)生成的名稱;
alter table student drop foreign key class_id;
//增加外鍵
alter table student add foreign key (class_id) references class (class_id) on delete set null; //刪除時(shí),將從表外鍵,設(shè)置為null;
alter table student add foreign key (class_id) references class (class_id) on delete cascade; //刪除時(shí),將從表外鍵刪除;
alter table student add foreign key (class_id) references class (class_id) on delete cascade on update restrict; //刪除時(shí),將從表外鍵上刪除,更新時(shí)拒絕更新;
- 數(shù)據(jù)庫(kù)存儲(chǔ)引擎
默認(rèn)的服務(wù)器表類型,通過(guò)mu.ini可以配置:default-storeage-engine=INNODB
在創(chuàng)建表時(shí),或者編輯表時(shí),可以指定表的存儲(chǔ)引擎
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區(qū)別
保存的文件的方式不同:
myisam,一個(gè)表,三個(gè)文件
Tbl_name.frm 結(jié)構(gòu) (frame)
Tbl_name.myd 數(shù)據(jù) (data)
Tbl_name.myi 索引 (index)
innodb:
一個(gè)表一個(gè)文件:
Tbl_name.frm 結(jié)構(gòu)
所有的innodb表,都使用相同的innodb存儲(chǔ)空間在保存數(shù)據(jù)和索引;
選擇存儲(chǔ)引擎的依據(jù): 1 功能, 2 性能
特點(diǎn) | Myisam | InnoDB | BDB | Memory | Archive |
---|---|---|---|---|---|
事務(wù)安全 | 支持 | 支持 | |||
全文索引 | 支持 | 5.5版本支持 | |||
鎖機(jī)制 | 表鎖 | 行鎖 | 頁(yè)鎖 | 表鎖 | 行鎖 |
存儲(chǔ)限制 | 沒(méi)有 | 64TB | 沒(méi)有 | 有 | 沒(méi)有 |
B樹索引 | 支持 | 支持 | 支持 | 支持 | |
哈希索引 | 支持 | 支持 | |||
集群索引 | 支持 | ||||
數(shù)據(jù)緩存 | 支持 | 支持 | |||
索引緩存 | 支持 | 支持 | 支持 | ||
數(shù)據(jù)可壓縮 | 支持 | 支持 | |||
空間使用 | 低 | 高 | 低 | N/A | 非常低 |
內(nèi)存使用 | 低 | 高 | 低 | 中等 | 低 |
支持外鍵 | 支持 |
innoDB&Myisam:
數(shù)據(jù)和索引的保存的文件不同: Myisam是分開保存的,innoDB是保存到表空間
Myisam支持索引壓縮,而innoDB索引和數(shù)據(jù)是綁定保存不壓縮,體積大;
innoDB很多時(shí)候是行級(jí)鎖,而myisam是表級(jí)鎖,innodb的并發(fā)高;
innodb不支持fulltext類型的索引(新的版本的innodb支持);
innodb支持事務(wù),外鍵,數(shù)據(jù)的完整性約束要強(qiáng),二myisam不支持.
innodb中不保存表的具體行數(shù),所以在執(zhí)行 select count(*) from table_name 時(shí),innodb要掃描一遍整個(gè)表來(lái)計(jì)算有多少行,但myisam只需要簡(jiǎn)單的讀取保存好的行數(shù)即可.注意的是,當(dāng)count(*)語(yǔ)句包含where時(shí),兩種表的操作是一樣的;
對(duì)于auto_increment類型的字段,innodb中必須包含只有該字段的索引,但是在myisam中,可以和其它字段一起建立聯(lián)合.
- 范式 (Normal Form)
用于規(guī)范表的設(shè)計(jì)的一套原則體系.
規(guī)范表的結(jié)構(gòu):
體系:1NF,2NF,3NF,4NF...
1NF:
要求: 表,所有的列(屬性),不能再分,具有原子性.通常認(rèn)為,不符合第一范式的表,不具有關(guān)系模型的定義;
2NF:
滿足第一個(gè)范式的基礎(chǔ)上.
要求:每一行(記錄)必須能夠唯一標(biāo)識(shí).同時(shí)要求:不存在非主鍵字段,不能對(duì)主鍵有部分函數(shù)依賴.(在組合鍵前提下,表中非主鍵字段,有依賴于組合主鍵內(nèi)的個(gè)別字段依賴的情況). 比如:非主鍵關(guān)鍵字(教室號(hào)碼),依賴主鍵內(nèi)的部分字段(班級(jí)id),非主鍵關(guān)鍵字(教師性別),依賴于主關(guān)鍵字內(nèi)部分字段(教師)
解決方案:常用方案是增加一個(gè)單子段主鍵即可,可以保證唯一標(biāo)識(shí),而且也不能形成部分函數(shù)依賴(一個(gè)獨(dú)立的字段)
3NF:
不錯(cuò)出現(xiàn)傳遞依賴:不能出現(xiàn) A->B->C
這樣的結(jié)構(gòu),如果出現(xiàn),就說(shuō)C傳遞依賴A
實(shí)體上表示,一個(gè)關(guān)系(二維表),只能保持一個(gè)實(shí)體的信息,不能保存多個(gè)信息
通用原則:
1街立,每個(gè)實(shí)體一個(gè)表(可以采取常用信息和詳細(xì)信息分開保存的思路)
2舶衬,為一個(gè)關(guān)系(二維表)增加,一個(gè)邏輯主鍵(不屬于真實(shí)實(shí)體屬性的字段)赎离,用于做標(biāo)識(shí)逛犹。
3,出現(xiàn)二維表對(duì)應(yīng)的關(guān)系梁剔,采用1:1, 1:N, M:n的形式
將關(guān)聯(lián)關(guān)系設(shè)計(jì)虽画。
注意:
實(shí)際的開發(fā)中,常常會(huì)為了操作方便荣病,編碼容易码撰,做一些逆規(guī)范化的事情。
例如个盆,每次得到授課信息時(shí)脖岛,都需要得到教室號(hào)。如果不做逆規(guī)范話颊亮,每次都
需要2個(gè)表內(nèi)獲得數(shù)據(jù)柴梆。可以考慮终惑,將教室號(hào)绍在,放入到 代課信息內(nèi)。查詢?nèi)菀妆⒂校幋a簡(jiǎn)單偿渡。
- 校對(duì)規(guī)則
每一套編碼字符集都有與之相關(guān)的校對(duì)規(guī)則.即,在當(dāng)前編碼規(guī)則下,字符間的比較規(guī)則,順序;
每個(gè)字符集都支持不定數(shù)量的校對(duì)規(guī)則,可以通過(guò)指令:show collation 查看字符集地區(qū)名比較規(guī)則(ci,cs,bin)(不區(qū)分大小寫,區(qū)分大小寫,字節(jié)比較)
show collation like `gbk%`;
在設(shè)置字符集的時(shí)候,可以設(shè)置當(dāng)前字符集所采用的校對(duì)規(guī)則,如果不設(shè)置校對(duì)規(guī)則,那么每個(gè)字符集都有一個(gè)默認(rèn)的校對(duì)規(guī)則;
以gbk為例子,比較chinese_ci bin 之間的區(qū)別,一個(gè)chinese_ci,一個(gè)chinese_bin,插入相同的數(shù)據(jù):
當(dāng)使用order by 進(jìn)行排序時(shí),數(shù)據(jù)會(huì)按照某個(gè)字段進(jìn)行排序.由于排序規(guī)則不同,排序會(huì)不一致
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;
- 查詢語(yǔ)句 select
select語(yǔ)法: select [查詢選項(xiàng)][查詢表達(dá)式(字段)] [from 子句][where 子句][having 子句][order by 子句][limit 子句];
要求子句可以不出現(xiàn).如果出現(xiàn),要求必須按照順序書寫;
表達(dá)式:字段,值,返回值的語(yǔ)句,函數(shù)的返回值
列子句
select id+10,concat(t_name,'-',gender),c_name from teacher_class;
//concat字符串拼接函數(shù),字段可以作為參數(shù),也可以進(jìn)行加法運(yùn)算
別名: 通常一個(gè)表達(dá)式,形式不夠好,不容易讀取,起一個(gè)可以容易讀取的別名即可:
使用關(guān)鍵字 as: 標(biāo)識(shí)符 [as] 別名;as可以省略,建議保留
from子句:表示查詢的目標(biāo)數(shù)據(jù)源,通常情況下是表名,表名也支持別名
select * from teacher_class,num_2;
表名也是一個(gè)列表:如果沒(méi)有任何條件的兩個(gè)表名,會(huì)得到表1乘表2的所有數(shù)據(jù).交叉連接,笛卡爾積;
from可以省略,但是有些數(shù)據(jù)庫(kù)不支持,MySQL支持;使用dual作為虛擬表存在
select now() from dual;
where 子句:
用于通過(guò)條件過(guò)濾數(shù)據(jù),得到真實(shí)的結(jié)果;
MySQL支持的操作符:邏輯運(yùn)算符和關(guān)系運(yùn)算符
=,>,<,>=,<=.!= (<>)
字符串匹配運(yùn)算符:like 可以利用通配符,完成模糊匹配
通配符: _ 匹配一個(gè)字符,%匹配多個(gè)任意字符,%匹配%,_匹配_
判斷某個(gè)值是否為null: is null, is not null;
isnull()結(jié)構(gòu)可以判斷null值;
<=>功能與 = 一致,特別的功能在于可以比較null值
select null is not null,null is null;
select null<=>null, 10 <=> null;
between and:
between valueA and valueB:范圍取值
范圍比較,閉區(qū)間: valuesA<=expr<=valueB;
select * from teacher_class where id between 3 and 5; //3,4,5三個(gè)id的值
select * from teacher_class where id in (3,5) //兩個(gè)值,3,5
in| not in:集合之內(nèi)(外);
in| not in(集合元素);
.interval:
獲得一個(gè)集合元素的集合:interval(值A(chǔ),元素1,元素2....);
一次判斷值與元素之間的大小,如果值A(chǔ)小于元素1,則返回0;如果值A(chǔ)小于元素2,則返回1,依次類推;
select t_name ,days,interval(days,10,20,30) from teacher_class where interval(days,10,20,30) = 1;
邏輯運(yùn)算符: And && ,Or ||, Not ! ;
null值的特殊性: not null,! null 為null
異或:xor ,有null就是null
. group by:分組聚合查詢語(yǔ)句:通過(guò)列內(nèi),不同的值,完成數(shù)據(jù)統(tǒng)計(jì);
分組的目錄,通常是組內(nèi)統(tǒng)計(jì):統(tǒng)計(jì)是通過(guò)MySQL的統(tǒng)計(jì)函數(shù)完成的;
sum()計(jì)算所有表達(dá)式的和
select t_name,sum(days) from teacher_class where 1 group by t_name; //所有老師的上課天數(shù)
select c_name, sum(days) as sum_days from teacher_class where 1 group by c_name; //所有班級(jí)的上課天數(shù)
如果合計(jì)函數(shù)的使用,沒(méi)有與group by配合,統(tǒng)計(jì)所有的數(shù)據(jù),將所有的數(shù)據(jù)當(dāng)作一組.
select sum(days) from teacher_class where 1;
排序group by:會(huì)通過(guò)排序字段,為數(shù)據(jù)進(jìn)行重新排序,默認(rèn)升序(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; 類似多字段主鍵,使用組合的字段進(jìn)行標(biāo)識(shí);
. rollup:在使用多字段分組時(shí),通常需要做上級(jí)統(tǒng)計(jì):
select t_name,c_name,sum(days) from teacher_class where 1 group by t_name,c_name with rollup;
使用 with rollup ,可以相當(dāng)于利用組合條進(jìn)行統(tǒng)計(jì)后霸奕,
再使用上一條件再次統(tǒng)計(jì)一次卸察。
注意,會(huì)統(tǒng)計(jì)到 沒(méi)有分組的情況铅祸,整個(gè)都是一組的情況
是否可以得到 大于某些代課天數(shù)的講師信息?
select t_name, sum(days) from teacher_class where sum(days)>50 group by t_name;
分析發(fā)現(xiàn):
where先執(zhí)行坑质,group by 后執(zhí)行合武。
Sum()在計(jì)算的時(shí)候,沒(méi)有分組的呢
無(wú)法在在where內(nèi)使用合計(jì)函數(shù):
需要一個(gè)涡扼,可以在結(jié)果內(nèi)稼跳,再次過(guò)濾的功能:
having
slect t_name,sum(days) from teacher_class where days > 10 group by t_name; //where會(huì)影響group的統(tǒng)計(jì),說(shuō)明where執(zhí)行在前;
. having :負(fù)責(zé)在結(jié)果(where查詢到的)中進(jìn)行再次過(guò)濾,可以像使用where一樣,having進(jìn)行處理;
select t_name,sum(days) from teacher_class where 1 group by t_name having sum(days) > 50;
- 聚合函數(shù)
Sum(),Avg(),Max(),Min(),Count()
Count():統(tǒng)計(jì)總的記錄數(shù),統(tǒng)計(jì)的是非null的記錄數(shù),通常用count(*)來(lái)統(tǒng)計(jì).
group_concat(): 組內(nèi)字符串連接,做了分組,只能顯示組內(nèi)信息.如果需要對(duì)其它列進(jìn)行顯示,可以把結(jié)果連起來(lái);
- order by
校對(duì)規(guī)則,決定排序關(guān)系;按照字段值進(jìn)行排序,order by 字段 asc | desc;
默認(rèn)升序asc;
允許多字段排序:先按照第一個(gè)字段排序,如果說(shuō),不能區(qū)分,才使用第二個(gè)字段,依次類推
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;
如果是分組,應(yīng)該用對(duì)應(yīng)字段group by,進(jìn)行排序的group by語(yǔ)法.
. limit
限制獲得的記錄數(shù)量;
limit offset,row_count;
;offset偏移量,默認(rèn)從零開始,0可省略,row_count要取的記錄數(shù),不足,全部取了;
select * from teacher_class limit 3,5;
select * from teacher_class limit 5;
. distinct: 去除重復(fù)記錄
重復(fù)的記錄指的是字段值,都相同的記錄,而不是部分字段相同的記錄
相對(duì)的是all,表示所有.默認(rèn)就是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;
聯(lián)合查詢:
將多條select語(yǔ)句的結(jié)果,合并到以前,稱為聯(lián)合操作.
使用的場(chǎng)景: 獲得數(shù)據(jù)的條件,出現(xiàn)邏輯沖突,或者很難在一個(gè)邏輯內(nèi)表示,可以拆分多個(gè)邏輯,分別實(shí)現(xiàn),最后吧結(jié)果合并到一起.
//獲取兩個(gè)不同班級(jí)上課天數(shù)最多的老師
(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:環(huán)境
如果union的結(jié)果存在重復(fù)的記錄,會(huì)自動(dòng)消除重復(fù).如果不想消除重復(fù),使用union all達(dá)到目的.
(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)
排序:子語(yǔ)句結(jié)果的排序,1 . 將子句包裹在括號(hào)內(nèi), 2. 子語(yǔ)句的order by 只有在order by配合limit時(shí)才生效.union在做子語(yǔ)句時(shí),會(huì)對(duì)沒(méi)有l(wèi)imit的子語(yǔ)句優(yōu)化(忽略)
(select t_name,days,from teacher_class where c_name='1234' order by days) union all //沒(méi)有l(wèi)imit,結(jié)果無(wú)序的
(select t_name,days,from teacher_class where c_name='2221' order by days desc limit 10)
如果要對(duì)所有結(jié)果進(jìn)行排序,只需要在最后一個(gè)select語(yǔ)句后進(jìn)行排序.
(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; //括號(hào)不是必須的,但提高了可讀性
多個(gè)select語(yǔ)句的檢索到的字段數(shù),必須一致.更加嚴(yán)格的是,數(shù)據(jù)類型上也要一致.MySQL內(nèi)部會(huì)做類型轉(zhuǎn)換,前提是能夠轉(zhuǎn)換成功. 檢索結(jié)果中列的名稱是根據(jù)第一條select語(yǔ)句決定的.
- 子查詢:語(yǔ)句內(nèi)部的查詢語(yǔ)句,就是子語(yǔ)句查詢
如果一個(gè)表內(nèi),有多個(gè)相同的結(jié)果時(shí)取數(shù)據(jù)的思路: 比如并列第一的情況
select t_name,gender from teacher_class order by days limit 1;
//方案:先獲取條件數(shù),作為判斷依據(jù)變量,這是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);
子查詢分類: 分類的依據(jù): 出現(xiàn)的位置和返回值的形式
返回值分類:
單一值,一列,多列,表(多行,多列)
出現(xiàn)的位置:
where 型,where 后
from型:from 后
exists 型
集合運(yùn)算符:in,not in, any, all , !=all(not in)
返回一行:
在參與比較時(shí),使用括號(hào)可以構(gòu)建一行:
(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);
返回一個(gè)表:
如果用于在from子句內(nèi),from子句內(nèi),要求使用一個(gè)表,是一個(gè)結(jié)果.
應(yīng)該給這個(gè)結(jié)果起個(gè)名稱,別名.
select * from (select t_name,c_name,days from teacher_class where days > 15) as temp_name where t_name like '李%';
exists(subquery):如果子查詢的可以返回?cái)?shù)據(jù),則認(rèn)為exists表達(dá)式返回真. 否則返回假;
//這兩個(gè)語(yǔ)句完成的是同樣的語(yǔ)句
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);
//兩個(gè)語(yǔ)句的思路
exists:先獲得每一條teacher_class的數(shù)據(jù),然后獲得ID字段,去teacher 表內(nèi)查詢對(duì)應(yīng)值,找到.
in:先找到所有的ID 的可能性.再在檢索teacher_class數(shù)據(jù)時(shí),判斷當(dāng)前的id是否在id集合內(nèi).
- join
每一個(gè)實(shí)體,每一個(gè)表,一個(gè)業(yè)務(wù)邏輯,使用多個(gè)實(shí)體的數(shù)據(jù),多張表應(yīng)該在一起使用,將多個(gè)表的記錄連接起來(lái).
總體的思路:將所有的數(shù)據(jù),按照某種條件,連接起來(lái),在進(jìn)行篩選處理.
連接的分類: 內(nèi)連接,外連接,自然連接
//內(nèi)連接:數(shù)據(jù)內(nèi)部的連接,要求連接的多個(gè)數(shù)據(jù)必須存在才能進(jìn)行連接
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;
//外連接:如果負(fù)責(zé)連接的一個(gè)或者多個(gè)數(shù)據(jù)不真實(shí)存在,則稱之為外鏈接.
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;
內(nèi)連接的處理:
內(nèi)連接,在連接時(shí),是可以省略連接條件的.意味著所有的左表的數(shù)據(jù)都要與右表的記錄做一個(gè)連接,共存M*N個(gè)連接.這種連接稱為交叉連接或者笛卡爾積;
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;
此時(shí),可以用cross join 代替inner join.可以通過(guò)多表查詢,不使用where做到笛卡爾積.
在MySQL中cross join和inner join相同,但在數(shù)據(jù)庫(kù)的定義上,交叉連接就是笛卡爾積.是沒(méi)有條件的inner join.MySQL inner join是默認(rèn)的連接方案,可以省略join
. 有條件的內(nèi)連接: 會(huì)在連接時(shí)過(guò)濾掉非法的連接.
where的寫法:在數(shù)據(jù)過(guò)濾上,數(shù)據(jù)交叉連接完成后,再做數(shù)據(jù)過(guò)濾.
on的寫法:在連接時(shí),就對(duì)數(shù)據(jù)進(jìn)行判斷;
using的寫法:using要求,負(fù)責(zé)連接的兩個(gè)實(shí)體之間的字段名稱一致.
建議在有同名字段時(shí)用using,而在通用的條件時(shí),用on.在數(shù)據(jù)過(guò)濾時(shí)(不是指連接過(guò)濾)使用where.
查詢條件,與外鏈接通用(外鏈接,不能使用where作為連接條件)
//后面再補(bǔ)充
- select
將檢索到的數(shù)據(jù),保存到服務(wù)器的文件內(nèi).可以自動(dòng)創(chuàng)建文件,但是不能重寫已經(jīng)存在的文件,否則報(bào)錯(cuò);
生成的文件格式:
默認(rèn)的吃沪,采用行來(lái)區(qū)分記錄汤善,而采用制表符,來(lái)區(qū)分字
為了滿足某種特別的需求票彪,會(huì)采用不同的分割方式红淡。
支持,在導(dǎo)出數(shù)據(jù)時(shí)降铸,設(shè)置記錄在旱,與字段的分割符。
通過(guò)如下的選項(xiàng):
fields:設(shè)置字段選項(xiàng)
Lines: 設(shè)置行選項(xiàng)(記錄選項(xiàng))
先看默認(rèn)值:
字段:fields terminated by '\t' enclosed by '' escaped by '\‘
記錄:lines terminated by '\n' starting by ''
可以自己設(shè)定
:
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';
注意:
常規(guī)的推掸,所有的記錄桶蝎,應(yīng)該通過(guò)行來(lái)顯示
例外是保存二進(jìn)制數(shù)據(jù):
//
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;
- 新增數(shù)據(jù)Insert&replace&loaddata
Insert into tbl_name (字段列表)values (值列表)
可以不將所有的字段都插入數(shù)據(jù)。
如果說(shuō)需要完成部分字段的插入谅畅,需要必須存在 字段列表
沒(méi)有插入的字段登渣,使用默認(rèn)值:
insert into teacher_class (t_name) values ('張三豐');
如果是插入部分字段, 可以使用下面的set語(yǔ)句:
insert into teacher_class set t_name='張無(wú)忌';
insert into teacher_class set t_name='趙敏', c_name='武術(shù)';
值列表的語(yǔ)法毡泻,可以一次性插入多條數(shù)據(jù):
每條數(shù)據(jù)采用記錄構(gòu)造符 括號(hào)完成即可:
insert into teacher_class (t_name, c_name) values
('張君寶', '太極'),
('楊過(guò)', '黯然銷魂掌');
插入數(shù)據(jù)時(shí)胜茧,如果主鍵沖突會(huì)如何?
默認(rèn)有 主鍵約束仇味,不會(huì)插入成功
但是可以在insert語(yǔ)法內(nèi)呻顽,控制
在主鍵沖突時(shí),改成執(zhí)行更新操作邪铲。
Update 后 不跟 set芬位。
insert into teacher_class (id, t_name, c_name) values
(13, '楊露嬋', '太極')
on duplicate key update
t_name='楊露嬋', c_name='太極'
;
插入的數(shù)據(jù)源:
除了使用自定義數(shù)據(jù)外,
還可以是使用 select 語(yǔ)句
查詢到數(shù)據(jù)带到,作為插入的數(shù)據(jù)源昧碉。
insert into teacher_class (t_name, c_name) select t_name, c_name from teacher_class;
數(shù)據(jù)可以來(lái)源于其他數(shù)據(jù)表,要求揽惹,字段數(shù)量和類型一致即可:
insert into teacher_class (t_name, c_name) select t_name, class_name from teacher;
通過(guò)強(qiáng)制使用 default關(guān)鍵字被饿,或者default()函數(shù),使用默認(rèn)值搪搏;
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;
導(dǎo)入 select * into outfile 'file' 命令
導(dǎo)出的內(nèi)容;
上面兩個(gè)命令 互補(bǔ)疯溺。
注意:
導(dǎo)入時(shí)论颅,涉及到數(shù)據(jù)增加哎垦,需要考慮,
是否沖突的情況恃疯。
通常漏设,可以在導(dǎo)出時(shí),將主鍵導(dǎo)出成null今妄。
利用自動(dòng)增長(zhǎng)的特性郑口。可以形成新的主鍵:
同樣:
在導(dǎo)入數(shù)據(jù)時(shí)盾鳞,需要同樣指定數(shù)據(jù)的分割犬性,
起止符號(hào)等。
保證 導(dǎo)出數(shù)據(jù)的格式與導(dǎo)入數(shù)據(jù)需要的格式
是一致的即可
刪除數(shù)據(jù):Delete
允許使用條件(刪除符合條件的數(shù)據(jù))
允許使用 limit :
限制刪除的記錄數(shù)腾仅。
Limit N;
常見的是
Limit 配合 order by來(lái)使用:
先將結(jié)果排序乒裆,再刪除固定數(shù)量的記錄:
delete from teacher order by days limit 10;
只有 order by 是沒(méi)有意義的
;
允許連接刪除:允許使用類似join的語(yǔ)法,同時(shí)刪除多個(gè)表內(nèi)的記錄;需要先提供表名,再提供連接條件;可以拆分成 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:不會(huì)返回刪除的記錄數(shù). 會(huì)重建自動(dòng)增長(zhǎng)的主鍵
delete逐行刪除
,truncate刪除表,新建表
- 更新數(shù)據(jù)
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
三個(gè)文件,保存攒砖,備份即可缸兔。
需要的時(shí)候日裙,直接解壓到移動(dòng)
到相應(yīng)的數(shù)據(jù)庫(kù)目錄內(nèi)即可
注意吹艇,如果是同樣的方法,處理的
innodb表結(jié)構(gòu)的文件昂拂。
則使用showtables時(shí)受神,也可以看到
但是不能使用的;
方案2:
通用的方案:
思路是:將建表結(jié)構(gòu),與插入數(shù)據(jù)的sql語(yǔ)句生成并保存,下次如果需要該結(jié)構(gòu)和數(shù)據(jù)
直接將數(shù)據(jù)語(yǔ)句 執(zhí)行即可格侯。
利用 mysql提供的工具完成的:
不是sql語(yǔ)言的一部分客叉。
不需要在 mysql命令行客戶端執(zhí)行遂蛀,
直接運(yùn)行即可。
將備份的數(shù)據(jù)庫(kù)還原:
就是將剛剛生成的sql語(yǔ)句,執(zhí)行即可;
將備份的數(shù)據(jù)庫(kù)還原:
就是將剛剛生成的sql語(yǔ)句鲤嫡,執(zhí)行即可。
在mysql客戶端侮东,直接執(zhí)行即可:
如何執(zhí)行 保存在文件內(nèi)的sql語(yǔ)句:
使用 source 指令墩瞳,可以指定需要執(zhí)行sql語(yǔ)句的源代碼文件:
常用的備份操作:
1,備份整個(gè)數(shù)據(jù)內(nèi)的表:
Mysqldump -uroot -p db_name > bak.sql
2收苏,備份數(shù)據(jù)庫(kù)內(nèi)的某張表:
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
- 視圖
創(chuàng)建視圖:
Create view view_name
AS select_statement;
create view v_teacher as select id,t_name from info_teacher;
視圖就是一個(gè)存在與數(shù)據(jù)庫(kù)中的虛擬表了;視圖亿卤,本身沒(méi)有數(shù)據(jù),只是通過(guò)執(zhí)行相應(yīng)的select語(yǔ)句完成獲得相應(yīng)的數(shù)據(jù)鹿霸。
視圖管理
刪除視圖:
Drop view [if exists] view_name;
修改視圖:
Alter view view_name
修改視圖內(nèi)排吴,所使用的字段的名稱:
視圖名稱后,使用 (字段列表即可)
縮減業(yè)務(wù)邏輯:
通過(guò)視圖還可以懦鼠,使復(fù)雜的業(yè)務(wù)邏輯钻哩,簡(jiǎn)單的完成屹堰,先使用視圖完成一定的邏輯,在在視圖的基礎(chǔ)上街氢,完成另外的邏輯双藕。
通常,視圖完成的邏輯阳仔,都是相對(duì)來(lái)說(shuō)比較基礎(chǔ)的邏輯忧陪。
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;
視圖的執(zhí)行過(guò)程:
視圖的執(zhí)行算法:
存在兩種執(zhí)行算法:
1,merge
2近范,temptable
指的是一個(gè)視圖是在什么
時(shí)候執(zhí)行嘶摊,依據(jù)哪些方式執(zhí)行:
merge:合并的執(zhí)行方式,每當(dāng)執(zhí)行的時(shí)候评矩,現(xiàn)將我們視圖的sql語(yǔ)句
與外部查詢視圖的sql語(yǔ)句叶堆,混合在一起。最終執(zhí)行:
Temptable:臨時(shí)表斥杜,模式虱颗,每當(dāng)查詢的時(shí)候,將視圖所使用select語(yǔ)句
生成一個(gè)結(jié)果的臨時(shí)表蔗喂。再在當(dāng)前的臨時(shí)表內(nèi)進(jìn)行查詢忘渔。
當(dāng)用戶創(chuàng)建視圖時(shí),mysql默認(rèn)使用一種 undefine的處理算法:就是會(huì)自動(dòng)在
合并和臨時(shí)表內(nèi)進(jìn)行選擇缰儿。
- 事務(wù)
一組sql語(yǔ)句操作單元畦粮。
組內(nèi)所有sql語(yǔ)句完成一個(gè)業(yè)務(wù)。
如果整組成功:意味著全部sql都實(shí)現(xiàn)
如果其中任何一個(gè)失敗乖阵。意味著整個(gè)操作都失敗宣赔。
失敗,意味著整個(gè)過(guò)程都是沒(méi)有意義的瞪浸。應(yīng)該
是數(shù)據(jù)庫(kù)回到 操作前的初始狀態(tài)儒将。
上面的特性,就是事務(wù)对蒲。
如何處理钩蚊?
1,失敗后齐蔽,可以回到開始位置
2两疚,沒(méi)都成功之前,別的用戶(進(jìn)程含滴,會(huì)話)是不能看到
操作內(nèi)的數(shù)據(jù)修改的诱渤。
思路:就是在 一組操作之間,設(shè)計(jì)一個(gè)記號(hào)谈况,備份點(diǎn)勺美。
實(shí)現(xiàn):
利用 innodb存儲(chǔ)引擎的递胧,事務(wù)日志功能:
SQL執(zhí)行分成2個(gè)階段:1,執(zhí)行階段 2,將執(zhí)行結(jié)果,提交的數(shù)據(jù)庫(kù)的階段;
其中,我們的事務(wù)日志,就是保存執(zhí)行階段的結(jié)果.如果用于選擇提交,則才將執(zhí)行的結(jié)果提交到數(shù)據(jù)庫(kù);默認(rèn)的執(zhí)行方式叫自動(dòng)提交,執(zhí)行完畢,自動(dòng)完成提交,因此.
需要關(guān)閉自動(dòng)提交功能.
自動(dòng)提交
存在一個(gè)系統(tǒng)的變量,
Autocommit 可以對(duì)自動(dòng)提交進(jìn)行配置
show variables like autocommit
;
關(guān)閉后赡茸,再次執(zhí)行相應(yīng)的更新語(yǔ)句:
發(fā)現(xiàn)缎脾,在其他連接中,查看數(shù)據(jù)占卧,
沒(méi)有發(fā)生變化遗菠,因?yàn)榻Y(jié)果沒(méi)有提交.
提交或回滾。
在此基礎(chǔ)上华蜒,執(zhí)行完所有的sql語(yǔ)句辙纬。
判斷是否都成功(出現(xiàn)錯(cuò)誤,包括語(yǔ)法錯(cuò)誤叭喜,和邏輯錯(cuò)誤
服務(wù)器錯(cuò)誤)贺拣。
成:將結(jié)果提交
利用 commit
敗:回到開始位置捂蕴。
Rollback
常見的事務(wù)的指令:
開啟事務(wù)
Start transaction; 可以使用begin譬涡。
關(guān)閉自動(dòng)提交。如果事務(wù)結(jié)束了啥辨,
成或敗涡匀,都會(huì)將自動(dòng)提交機(jī)制,回到start時(shí)的狀態(tài)委可。
成功:commit;
失斣ò稀:rollback腊嗡;
限定:
在innodb下生效(DBD)
事務(wù)的特點(diǎn):
1着倾,原子性。
2燕少,一致性卡者。
3,隔離性客们。
4崇决,持久性。
ACID底挫。
- 觸發(fā)器
監(jiān)聽數(shù)據(jù)進(jìn)行操作:在當(dāng)前的表上,設(shè)置一個(gè)對(duì)每行數(shù)據(jù)的一個(gè)監(jiān)聽器,監(jiān)聽相關(guān)事件,每當(dāng)事件發(fā)生時(shí).會(huì)執(zhí)行一段有SQL完成的一段功能代碼;
觸發(fā)器的元素:事件,執(zhí)行代碼
創(chuàng)建觸發(fā)器: create trigger 名字 事件 執(zhí)行代碼;
事件:insert,delete,update
事件的時(shí)機(jī):執(zhí)行之前和執(zhí)行之后,after/before
由時(shí)機(jī)和事件在一起形成了6種事件:before insert,before delete...
事件規(guī)定在哪個(gè)表上的什么時(shí)機(jī)的什么動(dòng)作上;
觸發(fā)程序:特定事件發(fā)生,即觸發(fā):
update addMoney set stu_money = stu_money + 20 where id = 1;
觸發(fā)器不能同名,目前MySQL只支持一類事件設(shè)置一個(gè)觸發(fā)器
create trigger my_trigger after update on addMoney for each row update class set cz_money=cz_money+20;
管理觸發(fā)器:
刪除:
Drop trigger trigger_name;
查看:
Show create trigger trigger_name;
在觸發(fā)器內(nèi)恒傻,獲得觸發(fā)該觸發(fā)程序時(shí)的數(shù)據(jù):
Old new
利用 觸發(fā)程序內(nèi)的 new 和 old來(lái)完成;
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:
監(jiān)聽事件所在表上的數(shù)據(jù)建邓,在事件發(fā)生之前時(shí)的數(shù)據(jù)盈厘。舊的數(shù)據(jù)。
New:
監(jiān)聽表上官边,事件發(fā)生之后沸手,新處理完畢的數(shù)據(jù)外遇。
數(shù)據(jù),就是觸發(fā)該事件的記錄契吉。
事件是insert呢跳仿? 不能使用old
事件是 delete呢?不能使用new
如果一個(gè)觸發(fā)程序,由多條SQL語(yǔ)句組成;
應(yīng)該:1.語(yǔ)句組成語(yǔ)句塊(begin end)來(lái)標(biāo)示語(yǔ)句塊.
2.語(yǔ)句塊的語(yǔ)句需要獨(dú)立的語(yǔ)句結(jié)束符,分號(hào);
命令行:由于觸發(fā)器程序內(nèi)使用分號(hào)作為語(yǔ)句結(jié)束符,那么當(dāng)命令行客戶端碰到分號(hào)時(shí),就應(yīng)該理解成觸發(fā)程序內(nèi)子語(yǔ)句結(jié)束,而不是整個(gè)觸發(fā)器的語(yǔ)句結(jié)束.
應(yīng)該通過(guò)修改命令行的語(yǔ)句結(jié)束符達(dá)到目的.delimiter語(yǔ)句可以完成設(shè)置語(yǔ)句結(jié)束符;
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:結(jié)構(gòu)化查詢語(yǔ)言捐晶。
是一門編程語(yǔ)言菲语。是由于管理數(shù)據(jù)的編程語(yǔ)言。
元素:
數(shù)據(jù),
數(shù)據(jù)類型,
變量,
函數(shù),
控制流程,
運(yùn)算符 ,
注釋;
注釋:
行:
--[空格]
塊:
/* */
結(jié)束符:
命令行:\g \G
可以使用 delimiter 來(lái)修改語(yǔ)句結(jié)束符
Delimiter $$
變量:
字段名就是變量惑灵。
php有許多系統(tǒng)默認(rèn)變量例如:
show variables like 'char%';
用戶自定義變量:
定義一個(gè)變量:set
Set 變量名 = 變量值谨究。
注意,為了區(qū)分 系統(tǒng)變量和字段與用戶自定義變量泣棋,需要在用戶變量前胶哲,增加@標(biāo)識(shí)符。
set @who = "haha";
通過(guò) select 語(yǔ)句可以獲得當(dāng)前的變量的值:
select @who;
Set是專門的為變量賦值的形式潭辈,甚至可以子查詢
set @total = (select count(*) from join_teacher);
定義一個(gè)變量 select info:
Select 字段列表 表達(dá)式 鸯屿。。把敢。 Into 變量列表寄摆。
select 10,14,20 into @a,@b,@c;
select c_name from join_class where id = 2 into @c_name;
注意,select into @var 要求修赞,只能返回一行婶恼。如果返回多行,會(huì)語(yǔ)法錯(cuò)誤柏副,或者只將最后一行的數(shù)據(jù)勾邦,注入到變量?jī)?nèi)。
//會(huì)報(bào)錯(cuò)
select c_name from join_class where 1 into @c_name;
利用 select語(yǔ)句的部分表達(dá)式達(dá)到為變量賦值的目的:
select @who = 'xiaoming'; //=是關(guān)系判斷
使用 := 的形式割择;
select @who := 'xiaoming';
注意眷篇,=應(yīng)該賦值,但是在 select語(yǔ)句內(nèi)荔泳,就成了 關(guān)系等于蕉饼。使用專門的賦值運(yùn)算符 :=。
同樣適用于 set玛歌。
set @i := '111';
select * from teacher where @who:='xiaoming';
使用變量是在表達(dá)式昧港,或者使用select查詢到即可。
1支子,作用域创肥。用戶定義的函數(shù),是全局的(函數(shù)內(nèi)可用)。存在局部作用域變量瓤的,函數(shù)內(nèi)定義的變量休弃。
2,有效期圈膏。會(huì)話結(jié)束(連接結(jié)束)塔猾。
運(yùn)算符:
- 函數(shù)
內(nèi)置函數(shù)
數(shù)值:
Rand()得到1-0之間的隨機(jī)數(shù)
select rand();
如何得到5到10?
5+(0-5)
5+rand()*5;
取整:
select floor(rand()*5+5);
格式化:
format
select format(2132432.12323,2); //2位小數(shù)顯示
時(shí)間日期:
Now();
Unix_timestamp();
select unix_timestamp();
select from_unixtime(123456);
select from_unixtime(unix_timestamp());
字符串:
Concat()字符串連接
Substring(原字符串稽坤,開始位置丈甸,截取長(zhǎng)度);
開始位置 從1開始
Char_length();
Length();
Lpad(需要補(bǔ)足的字符串,補(bǔ)足后的長(zhǎng)度尿褪,補(bǔ)字符串);
左邊補(bǔ)足:
其他:
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");
數(shù)值函數(shù)
Abs(X)睦擂,絕對(duì)值 abs(-10.9) = 10
Format(X,D)杖玲,格式化千分位數(shù)值 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)顿仇,算術(shù)平方根
Rand(),隨機(jī)數(shù)
TRUNCATE(X,D) 截取D位小數(shù)
時(shí)間日期函數(shù)
Now(),current_timestamp(); 當(dāng)前日期時(shí)間
Current_date();當(dāng)前日期
current_time();當(dāng)前時(shí)間
Date(‘yyyy-mm-dd HH;ii:ss’);獲取日期部分
Time(‘yyyy-mm-dd HH;ii:ss’);獲取時(shí)間部分
Date_format(‘yyyy-mm-dd HH;ii:ss’,’ %D %y %a %d %m %b %j');
Unix_timestamp();獲得unix時(shí)間戳
From_unixtime();//從時(shí)間戳獲得時(shí)間
字符串函數(shù)
LENGTH (string ) //string長(zhǎng)度,字節(jié)
CHAR_LENGTH(string) //string的字符個(gè)數(shù)
SUBSTRING (str , position [,length ]) //從str的position開始,取length個(gè)字符
REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替換search_str
INSTR (string ,substring ) //返回substring首次在string中出現(xiàn)的位置
CONCAT (string [,... ]) //連接字串
CHARSET(str) //返回字串字符集
LCASE (string ) //轉(zhuǎn)換成小寫
LEFT (string ,length ) //從string2中的左邊起取length個(gè)字符
LOAD_FILE (file_name ) //從文件讀取內(nèi)容
LOCATE (substring , string [,start_position ] ) //同INSTR,但可指定開始位置
LPAD (string ,length ,pad ) //重復(fù)用pad加在string開頭,直到字串長(zhǎng)度為length
LTRIM (string ) //去除前端空格
REPEAT (string ,count ) //重復(fù)count次
RPAD (string ,length ,pad) //在str后用pad補(bǔ)充,直到長(zhǎng)度為length
RTRIM (string ) //去除后端空格
STRCMP (string1 ,string2 ) //逐字符比較兩字串大小
流程函數(shù):
CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END 多分支
IF(expr1,expr2,expr3) 雙分支摆马。
聚合函數(shù)
Count()
Sum();
Max();
Min();
Avg();
Group_concat()
其他常用函數(shù)
Md5();
Default();
- 自定義函數(shù)
要素:
函數(shù)名,
參數(shù)列表,
函數(shù)體,
返回值;
語(yǔ)法:
定義:
Create function 函數(shù)名 (參數(shù)列表) 返回值類型
函數(shù)體
delimiter $$
create function sayHi() returns varchar(20);
begin
return 'Hi';
end
$$
delimiter;
//調(diào)用
select sayHi();
注意:函數(shù)是與當(dāng)前的數(shù)據(jù)庫(kù)綁定的臼闻,可以使用庫(kù)名.函數(shù)名的形式調(diào)用;
select one.sayHi();
sql中的流程控制:
分支
If 條件1 then
條件1滿足執(zhí)行的語(yǔ)句
Elseif 條件2 then
條件2滿足執(zhí)行的語(yǔ)句
….
Else
上面的條件全都不滿足囤采,執(zhí)行的語(yǔ)句
End if;
Elseif 和 else 都是可以省略的述呐。
循環(huán)
While 條件 do
循環(huán)體
End while
循環(huán)的提前終止
Leave break 終止循環(huán)
Iterate continue 終止當(dāng)前循環(huán)
注意,不是根據(jù)leave和iterate所在的位置來(lái)決定終止哪個(gè)循環(huán)蕉毯,而是由循環(huán)的標(biāo)簽來(lái)決定的乓搬。
循環(huán)的標(biāo)簽,給循環(huán)起名字代虾。
標(biāo)簽 : while
End while 標(biāo)簽;
函數(shù)內(nèi)使用的變量
@var的形式进肯,相當(dāng)于 全局變量,函數(shù)內(nèi)和函數(shù)外通用褐着。
函數(shù)的參數(shù):
參數(shù)坷澡,同樣需要確定類型。
參數(shù)名 類型
一個(gè)函數(shù)含蓉,可以有多個(gè)參數(shù),使用 逗號(hào)分割项郊。
函數(shù)聲明的局部變量:
使用 declare聲明局部變量馅扣。 需要指定類型,可以指定默認(rèn)值 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;