1. 程式人生 > >mysql資料庫筆記

mysql資料庫筆記

sql筆記

資料庫定義

【資料庫】

 儲存資料的倉庫

 本質:檔案系統加伺服器

 常見資料庫產品:

 mysql

 oracle

 sql server

 sqlite

 db2

 庫 - 資料夾 , 存放的是表

 表 - 檔案, 存放的是真正的資料

【SQL】

 結構化查詢語言

 相當於資料庫中的“普通話”

 每種資料庫可能會有自己特殊的命令 - "方言"

 1. DDL: 資料定義語言, 建表建庫

 2. DML: 資料操縱語言, 增刪改,

      - DQL 查

 3. DCL: 資料控制語言, 新增使用者 賦予許可權

【操作】

桌面執行mysql方法

修改環境變數,path的值後面加’;’加mysql.exe的父目錄

桌面shift+右鍵在當前介面執行cmd

 1. 進入

 mysql -u root -p

 Password:

 2. 檢視庫

 show databases;

 3. 建庫

 create database bwf;

 4. 使用庫

 use bwf;

 5. 檢視庫中的表

 show tables;

 6. 建表

  學生表

student

id name age

create table student(

id INT PRIMARY KEY AUTO_INCREMENT,

name varchar(20) NOT NULL,

age INT NOT NULL DEFAULT 18);

DDL(資料庫定義語言)

建表

id name age

Drop talbe if esists student

create table student(

id INT PRIMARY KEY AUTO_INCREMENT,

name varchar(20) NOT NULL,

age INT NOT NULL DEFAULT 18);

新增外來鍵約束

constraint fk_uid  foreign key  (欄位) references  外來鍵的表(外來鍵表的欄位)

新增聯合主鍵約束

PRIMARY KEY (欄位1,欄位2)

刪除表

DROP TABLE student;

修改表

增加欄位(整數)

ALTER TABLE student ADD height INT;

修改欄位(浮點數)

ALTER TABLE student MODIFY height DOUBLE;

修改欄位(欄位名,浮點數)

ALTER TABLE student CHANGE height DOUBLE;

刪除欄位

ALTER TABLE student DROP COLUMN height;

索引

 1. 提高查詢效率的資料庫物件

 2. 通過關聯關鍵字的方式提高查詢效率(類似於書的目錄)

 3. 資料庫會自動為主鍵和唯一列新增索引

 什麼時候適合使用索引呢?

 1. 經常出現在where子句中的欄位

 2. 經常出現在group by子句中的欄位

 3. 重複值很少的欄位

 什麼時候不適合用索引呢

 1. 重複值很多的欄位

 2. 很大的欄位

操作:

提高查詢效率 -> 從效率瓶頸出發

減少磁碟讀取的次數 -> B樹

查詢18歲的學生

select *

from student

where age='18';

根據年齡建立索引

create index index_age

on student(age);

刪除索引

drop index index_age

on student;

DML(資料庫操縱語言)

插入 1, 張三, 18  注意: 字串和日期時間 必須加上 ''

插入完整記錄

INSERT INTO student VALUES (1, '張三', 18);

插入部分記錄

INSERT INTO student (name, age) VALUES ('張三', 18);

插入多條完整記錄

INSERT INTO student VALUES (3, '李四', 19),(4, '王武', 28),(5, '趙柳', 39);

刪(不做)

全部刪除

DELETE FROM student;

刪除部分(條件)

DELETE FROM student WHERE id > 3;

UPDATE student SET age=18;

大於20歲的人全部改回20歲

UPDATE student SET age = 20 WHERE age > 20;

DQL資料查詢語言)

查詢所有的列

SELECT * FROM student;

SELECT id, name FROM student;

查看錶結構

DESC student;

SHOW CREATE TABLE student;

結果:

CREATE TABLE `student` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(20) NOT NULL,

  `age` int(11) NOT NULL DEFAULT '18',

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8

引擎:預設innodb,預設字符集為utf-8,一個漢字佔3個位元組,gbk佔2個位元組

【函式】

【數學函式】

求絕對值

SELECT ABS(-5);

求比這個數大的最小整數

SELECT CEILING(-6.1);

SELECT CEIL(-6.1);

求比這個數小的最大整數

SELECT FLOOR(-6.1);

求最大值

SELECT GREATEST(100,5,13);

求最小值

SELECT LEAST(5,3,7);

求模 %

SELECT MOD(10, 6);

四捨五入

SELECT ROUND(10.5);

SELECT ROUND(10.516, 2);

截斷

SELECT TRUNCATE(10.51999, 2);

求隨機數

SELECT RAND();

SELECT RAND(5);

求平方根

SELECT SQRT(100);

【字串函式】

字串長度

SELECT LENGTH('hello');

SELECT LENGTH('你好');

Utf-8編碼格式,一個漢字佔3個位元組

全部小寫

SELECT LCASE('hELlo');

SELECT LOWER('hELlo');

全部大寫

SELECT UCASE('hELlo');

SELECT UPPER('hELlo');

子串位置 - MYSQL中索引從1開始

SELECT POSITION('a' IN 'java');

替換

SELECT REPLACE('yesy','y','hh');

插入 - 從第2個位置開始的1個字元 替換成 xx

SELECT INSERT ('hello', 2, 1, 'xx');

拼接 -

SELECT CONCAT('hello','my','sql');

間隔符拼接

SELECT CONCAT_WS(',', 'hello','my','sql');

取左邊的字元

SELECT LEFT('hello', 3);

取右邊的字元

SELECT RIGHT('hello', 3);

往左邊填充字元

SELECT LPAD('hello',10,'x');

往右邊填充字元

SELECT RPAD('hello',10,'y');

去左邊空格

SELECT LTRIM('              h    e  ll o           ');

去右邊空格

SELECT RTRIM('              h    e  ll o           ');

去左右空格

SELECT TRIM('             h    e  ll o           ');

子串

從第3位開始取, 取5個

SELECT SUBSTRING('51testing', 3, 5);

從第3位開始取, 取到底

SELECT SUBSTRING('51testing', 3);

【日期時間函式】

當前系統時間

SELECT SYSDATE();

SELECT NOW();

當前日期

SELECT CURRENT_DATE();

當前時間

SELECT CURRENT_TIME();

當前時間戳

SELECT CURRENT_TIMESTAMP();

獲取年份

SELECT YEAR('98/9/3');

獲取月份

SELECT MONTH('2018-9-3');

獲取月份的名字

SELECT MONTHNAME('2018-9-3');

日期加法

SELECT DATE_ADD(NOW(),INTERVAL 3 MONTH);

【聚合函式】

求平均值

SELECT AVG(age) FROM student;

求最大值

SELECT MAX(age) FROM student;

求最小值

SELECT MIN(age) FROM student;

求和

SELECT SUM(age) FROM student;

求記錄數

SELECT COUNT(age) FROM student;

【建表】

 學生表

CREATE TABLE student(

id INT PRIMARY KEY AUTO_INCREMENT,

name VARCHAR(255) NOT NULL,

age INT DEFAULT 18,

height DOUBLE);

 課程表

CREATE TABLE lesson(

id INT PRIMARY KEY AUTO_INCREMENT,

name VARCHAR(255) NOT NULL,

teacher VARCHAR(255) DEFAULT '陳老師');

 分數表

CREATE TABLE score(

sid INT,

lid INT,

score INT NOT NULL,

CONSTRAINT fk_sid FOREIGN KEY (sid) REFERENCES student(id),

CONSTRAINT fk_lid FOREIGN KEY (lid) REFERENCES lesson(id),

-- 聯合主鍵

CONSTRAINT pk_sid_lid PRIMARY KEY (sid, lid));

加入資料

INSERT INTO student VALUES (1, '張三', 18, 169);

INSERT INTO student VALUES (2, '李四', 16, 160);

INSERT INTO student VALUES (3, '王五', 19, 181);

INSERT INTO student VALUES (4, '趙六', 29, 175);

INSERT INTO student VALUES (5, '田七', 37, 170);

INSERT INTO student VALUES (6, '王八', 108, 16);

INSERT INTO lesson VALUES (1, '前置課程', '陳老師');

INSERT INTO lesson VALUES (2, 'javaSE', '陳老師');

INSERT INTO lesson VALUES (3, '資料庫', '錢老師');

INSERT INTO lesson VALUES (4, '網頁製作', '董老師');

INSERT INTO lesson VALUES (5, 'javaEE', '朱老師');

INSERT INTO lesson VALUES (6, 'javaSE', '韓老師');

單表查詢

SELECT * FROM student;

SELECT id, name, age, height FROM student;

別名查詢(AS可以省略)

SELECT id AS 學號, name AS 姓名, age AS 年齡, height AS 身高 FROM student;

SELECT id 學號, name 姓名, age 年齡, height 身高 FROM student;

去重查詢

查詢所有課程的種類

SELECT DISTINCT name FROM lesson;

查詢所有參加考試的學生學號

SELECT DISTINCT sid FROM score;

運算查詢

SELECT score + 10 FROM score;

SELECT id, name, age + 10, height FROM student;

條件記錄查詢

保留170以上的

SELECT * FROM student WHERE height > 170;

保留[160, 170]

SELECT * FROM student WHERE height >= 160 AND height <= 170;

SELECT * FROM student WHERE height BETWEEN 160 AND 170;

空值查詢

查詢身高是空的學生資訊

SELECT * FROM student WHERE height IS NULL;

查詢身高不是空的學生資訊

SELECT * FROM student WHERE height IS NOT NULL;

集合中記錄查詢

查詢分數是59 69 79分的記錄

SELECT * FROM score WHERE score IN (59, 69 ,79);

查詢分數不是59 69 79分的記錄

SELECT * FROM score WHERE score NOT IN (59, 69 ,79);

模糊查詢

查詢所有姓王的學生記錄  _ 匹配一個字元  % 可以匹配任意多字元

SELECT * FROM student WHERE name LIKE '王_';

SELECT * FROM student WHERE name LIKE '王%';

排序查詢

按照年齡排序 預設是升序

SELECT * FROM student ORDER BY age (ASC);

按照年齡降序

SELECT * FROM student ORDER BY age DESC;

多欄位排序

年齡排序, 年齡相同時按照身高排序

SELECT * FROM student ORDER BY age DESC, height;

從成績表中查詢記錄, 按照成績降序排序, 成績相同按照課程id升序排序, 成績和課程id都相同, 按照學號升序排序

SELECT * FROM score ORDER BY score DESC, lid ASC, sid ASC;

限制數量查詢(重點)

只看前5條

SELECT * FROM student LIMIT 5;

前2條不要了, 再拿5條

SELECT * FROM student LIMIT 2,5;

分頁查詢(重點)

每頁顯示2條

第1頁

SELECT * FROM student LIMIT 0,2;

第2頁

SELECT * FROM student LIMIT 2,2;

第3頁

SELECT * FROM student LIMIT 4,2;

第4頁

SELECT * FROM student LIMIT 6,2;

規律: 後面一個引數就是每頁顯示個數, 前面一個引數是 (頁數-1)*每頁顯示個數

分組查詢

SELECT lid, AVG(score) FROM score GROUP BY lid;

SELECT lid, score FROM score GROUP BY lid;

多表查詢

SELECT * FROM student;

SELECT * FROM score;

 1. 交叉連線 8 * 4 , 7 * 3  -> 56 , 7

SELECT * FROM student, score;

SELECT * FROM student CROSS JOIN score;

 2. 內連線 - 只能保留兩個表都有的資料

SELECT * FROM student, score WHERE student.id = score.sid;

SELECT * FROM student INNER JOIN score WHERE id = sid;

查詢所有學生的學號 姓名 考試科目 任課老師和考試分數

SELECT student.id, student.name, lesson.name, lesson.teacher, score.score

FROM student, lesson, score

WHERE student.id = score.sid AND score.lid = lesson.id;

 3. 外連線

 左外連線 - 保留左表全部資料的前提下, 把右表拼接上來

SELECT *

FROM student LEFT JOIN score

ON student.id = score.sid;

SELECT *

FROM score LEFT JOIN student

ON student.id = score.sid;

 右外連線 - 保留右表全部資料的前提下, 把左表拼接上來

SELECT *

FROM score RIGHT JOIN student

ON student.id = score.sid;

子查詢

單行單列子查詢

查詢年齡比張三大的學生資訊

SELECT *

FROM student

WHERE age > (SELECT age FROM student WHERE name = '張三');

查詢考了100分的學生資訊

SELECT *

FROM student

WHERE id = (SELECT sid FROM score WHERE score = 100);

SELECT student.*

FROM student,score

WHERE id = sid AND score = 100;

查詢年齡和身高都和張三一樣的學生資訊

SELECT *

FROM student

WHERE age = (SELECT age FROM student WHERE name = '張三')

AND height = (SELECT height FROM student WHERE name = '張三')

單行多列子查詢

SELECT *

FROM student

WHERE (age, height) = (SELECT age, height FROM student WHERE name = '張三');

多行單列子查詢

查詢考了59分的學生資訊

 1. IN 關鍵字 - 查詢的條件是在子查詢的查詢結果中

SELECT *

FROM student

WHERE id IN (SELECT sid FROM score WHERE score = 59);

查詢所有參加過考試的學生資訊

SELECT *

FROM student

WHERE id IN (SELECT DISTINCT sid FROM score);

 2. ANY 關鍵字 - 查詢的條件滿意子查詢返回結果的任意一條記錄

 查詢比張三, 李四, 王五中任意一個人年齡大的學生資訊

SELECT *

FROM student

WHERE age > ANY (SELECT age FROM student WHERE name IN('張三', '李四', '王五'));

SELECT *

FROM student

WHERE age > (SELECT MIN(age) FROM student WHERE name IN('張三', '李四', '王五'));

 3.  ALL 關鍵字 - 查詢的條件滿足子查詢返回結果的所有記錄

 查詢比張三,李四,王五年齡都大的學生資訊

SELECT *

FROM student

WHERE age > ALL (SELECT age FROM student WHERE name IN ('張三','李四','王五'));

SELECT *

FROM student

WHERE age > (SELECT MAX(age) FROM student WHERE name IN('張三','李四','王五'));

 4. EXISTS 關鍵字: 查詢時遍歷外表, 每次查詢都會執行exists子句, 存在記錄時為真

SELECT * FROM student WHERE age > 20;

查詢參加過考試的學生

SELECT *

FROM student

WHERE EXISTS (

SELECT *

FROM score

WHERE student.id = score.sid);

SELECT *

FROM score

WHERE 4 = score.sid

疑點

select 要顯示的結果,可以帶聚合函式

From

Where 在記錄之前就對記錄進行過濾

Group by 分類聚合的欄位

Having :對聚合(分組)後的記錄過濾

select count(*)和select count(1)的區別

一般情況下,Select Count (*)和Select Count(1)兩著返回結果是一樣的

    假如表沒有主鍵(Primary key), 那麼count(1)比count(*)快,

    如果有主鍵的話,那主鍵作為count的條件時候count(主鍵)最快

    如果你的表只有一個欄位的話那count(*)就是最快的

   count(*) 跟 count(1) 的結果一樣,都包括對NULL的統計,而count(column) 是不包括NULL的統計

TPL(事務處理語言)

【事務 Transaction】

1. 概念

 作為一個單獨單元的一條或者多條SQL語句組成

 這個單元的每一條SQL語句都是相互依賴的

 必須每一條SQL語句都成功的執行, 才可以說這個事務成功的執行了

 如果有一條語句執行出錯, 那麼整個事務就會回滾

 回到事務開始以前的狀態

 轉賬

 A給B轉100元

 餘額表

 使用者名稱 餘額

 A 100

 B 50

 A-100 B-50

 UPDATE 餘額表 SET 餘額 = 餘額 - 100 WHERE 使用者名稱 = 'A';

 A-0 B-50

 UPDATE 餘額表 SET 餘額 = 餘額 + 100 WHERE 使用者名稱 = 'B';

 A-0 B-150

2. 事務的特點 ACID:

 原子性(Atomicity):

  事務的多條SQL語句是一個不可分割的完整邏輯單元

 一致性(Consistency):

  事務中的每條SQL語句要麼都是成功執行的, 要麼都失敗了

  如果一個事務成功執行了, 那麼裡面的每一條SQL語句都成功執行了

  如果一個事務失敗了, 那麼裡面的每一條SQL語句都失敗了

 隔離性(Isolation)

  不同的事務是相互隔離的

  不同的事務相互訪問的時候

  得到的資料要麼是事務發生以前的資料

  要麼是事務發生以後的資料

 永續性(Durability)

  一旦事務完成提交, 對資料的修改就是永久的

3. 操作

 開啟事務 START TRANSACTION;

 儲存到S1 SAVEPOINT s1;

設定一個節點

 回滾到S1, ROLLBACK TO s1;

回到s1節點,然後繼續執行ROLLBACK TO s1後面的語句!

 回滾 ROLLBACK;

回到開頭,然後繼續執行ROLLBACK後面的語句!

 提交 COMMIT;

檢視 View

 一張或多張表的資料子集的邏輯表現

 1. 檢視不是表,不是一個物理的實體,只是一個邏輯表現

 2. 檢視中的資料是來源於表的

 3. 檢視的本質就是子查詢

 作用:

 1. 對資料安全保護

 2. 簡化查詢語句

 3. 更清晰的表達查詢

建立檢視

create  view v_emp10

as

select  empno,ename,job from emp where deptno=10;

建立檢視,如果已存在檢視則替換,並把列名自定義

create or replace view v_emp10 (id,name,job)

as

select  empno,ename,job from emp where deptno=10;

select *from v_emp10;

刪除

drop view v_emp10 ;

新建部門檢視

CREATE VIEW v_dept

AS

SELECT * FROM dept;

從部門檢視中查詢資料

SELECT * FROM v_dept;

往檢視中插入資料

INSERT INTO v_dept VALUES (50, '教學部', '漕河涇');

從表中查詢資料

SELECT * FROM dept;

問題: 能不能修改檢視中的資料呢?

錯誤答案1: 能

錯誤答案2: 不能

正確答案: 有的檢視能, 有的檢視不能

建立一個各個部門平均工資檢視

CREATE VIEW v_dept_avgsal

AS

SELECT dname, avg(sal)

FROM emp RIGHT JOIN dept

ON emp.deptno = dept.deptno

GROUP BY dname;

從檢視中查詢資料

SELECT * FROM v_dept_avgsal;

INSERT INTO v_dept_avgsal VALUES ('教研部', 20000);

插入失敗,因為avg(sal)資料根本不存在

儲存過程和函式

【儲存過程】

定義一個儲存過程

CREATE PROCEDURE proc1()

BEGIN

SELECT 1+1;

SELECT NOW();

SELECT LEFT('HAHA',2);

END

刪除儲存過程

DROP PROCEDURE proc1;

呼叫儲存過程

CALL proc1();

使用者變數

可以先在使用者變數中儲存值, 然後再引用它

這樣就可以將值從一條語句傳遞到另一條語句

* 使用者變數和連線有關

SET @x = 'hello';

SELECT @x;

SELECT 'world' INTO @y;

SELECT @y;

SET @z = 1+2+3;

SELECT @z;

查詢的結果儲存到x變數中:

SELECT (@x:=age) FROM student WHERE name = '張三';

SELECT @x;

SELECT * FROM student WHERE age = @x;

建立帶引數的儲存過程

引數型別

IN - 只能將引數的值傳入過程, 在過程中的修改對變數沒有影響, 就是個預設值

OUT - 引數的值傳不進過程中, 但是在過程中對其修改的結果會影響變數的結果

INOUT - 既能傳入, 對其進行的修改又能傳出來

CREATE PROCEDURE proc2(IN p INT)

BEGIN

SELECT p;

SET p = 2;

SELECT p;

END

DROP PROCEDURE proc2;

SET @p = 1;

CALL proc2(@p);

SELECT @p;

結果:1,2,1

CREATE PROCEDURE proc3(OUT p INT)

BEGIN

SELECT p;

SET p = 2;

SELECT p;

END

SET @p = 1;

CALL proc3(@p);

SELECT @p;

結果:null,2,2

CREATE PROCEDURE proc4(INOUT p INT)

BEGIN

SELECT p;

SET p = 2;

SELECT p;

END

SET @p = 1;

CALL proc4(@p);

SELECT @p;

結果:1,2,2

【函式】

CREATE FUNCTION func1() RETURNS INT

BEGIN

RETURN 1;

END

函式必須放在查詢語句中呼叫

SELECT func1();

SELECT NOW();

已經寫好的函式

函式和儲存過程的區別:

  1. 呼叫方式不同
  2. 儲存過程沒有返回值,函式有返回值