MySql

MySql

1 概念

  • database:數據庫,存儲數據的集合。
  • 數據庫管理系統:DataBase Management System,DBMS。用于建立,使用和維護數據庫,對數據庫
    進行統一管理和控制的大型軟件,保證了數據庫的完整性和安全性。

一般我們說的數據庫指的是存儲數據的集合和數據庫管理系統。即存儲,維護和管理數據。

常見的數據庫:MYSQL,Oracle,DB2等等

2 SQL語句

2.1 SQL分類

  • DDL:Data Definition language,數據定義語言,用于定義數據庫對象:數據庫,表,列。關鍵字:create,show,drop,alter等。(結構)
  • DML:Data Manipulation language,用于對數據庫中的記錄進行更新。關鍵字:insert,delete,update等(數據)。
  • DQL:Data Query language,用于查詢數據庫中表的記錄。關鍵字:select,from,where等。【重點】
  • DCL:Data Control language,用于定義數據庫的訪問權限和安全級別及創建用戶。關鍵字:grant等。(了解即可)

2.2 對數據庫的操作(create,drop,alter,show)

增:  
    create database 庫名 [character set gbk collate gbk_chinese_ci];
刪:
    drop database 庫名;
改:
     alter database 庫名 character set utf8;  修改某數據庫的字符集
查:
    show databases;     顯示所有的數據庫
    show create database 庫名;    顯示某個數據庫
其它:
    use 庫名; 使用某個數據庫
    select database();  顯示當前所用的數據庫

2.3 對表單的操作:(create,drop,alter,show)

以下表名均用stu代替:    
增:
    create table stu(
        字段名1 類型1(長度)[約束],
        字段名2 類型2(長度)[約束]...
    );

    約束:
        唯一約束:unique,唯一
        非空約束:not null,非空
        主鍵約束:primary key    ,唯一和非空的組合。

刪:
    alter table stu drop 字段名;   刪除列
    drop table stu; 刪除表單 
改:
    *alter table stu add 字段名 類型1(長度)[約束];       增加一列
    *alter table stu modify 字段名 類型1(長度)[約束];        修改列的長度和約束
    *alter table stu change 舊列名 新列名 類型1(長度)[約束];    修改列名
    *alter table stu drop 字段名;  刪除列
    *alter table stu character set utf8;        修改表的字符集
    *rename table 舊表名 to 新表名;       修改表名
查:
    show tables;    查看所有表單
    desc 表名;        查看表單結構

2.4 對表單中數據的操作(insert into,update,delete)

增:
    方式1:插入部分/所有列的值
    insert into 表名(字段名1,字段名2...字段名n) values(與前面對應的值);
    
    方式2:插入所有列的值
    insert into 表名 values(所有列的對應的值);    

    1.列名和后面values里面的列名數以及順序必須一致。
    2.列名的類型和插入的值必須一致,插入的值不能超過最大長度。
    3.值如果是字符串或者日期必須加上''單引號。

刪:
    delete from 表名 [where]...;  不加判斷條件即為刪除整個表格
    truncate table 表名;      刪除整個表格
    
    delete和truncate的區別:
    1:delete是一行一行的刪除數據,不清空auto_increment記錄數,刪除的數據可以一個事務中恢復
    2:truncate是直接把表格刪除,再創建一個新的表格,清空auto_increment,所以效率較delete高。
    這是徹底刪除,無法恢復
改:
    *update 表名 set 字段名=值,字段名=值...;
    *update 表名 set 字段名=值,字段名=值...where條件;
查:
    select */列名1,列名2.. from 表名;     查詢全部/部分列的信息

3 SQL查詢

3.1 簡單查詢

語法:select [distinct] */列名,列名 from 表名 [where條件];
    distinct表示去重。

例子:
1.查詢所有商品:   select * from 表名;
2.查詢商品名和商品價格:   select name,price from 表名;
3.別名查詢,使用關鍵字as。as可省略
    select name as '商品名' from 表名;/select name '商品名' from 表名;
4.去重查詢: select distinct name from 表名;   
5.將所有商品價格加上10進行顯示。
    select price+10 from 表名;

2.2 條件查詢

> < <= >= = <> : 大于,小于,小于等于,大于等于,等于,不等于 

where 等同于java中的 if,但是在where語句后進行判斷操作時使用'=',而不是用'=='。
* between...and...  在...和...之間
* in(數據1,數據2...數據n);    在幾個數據中
* and:  和,并且
* or:  或
* like:     模糊查詢,占位符%和_,%表示占0或多個字符,_表示占一個字符
* is null:判斷是否為空。(了解)

2.3 排序

order by 字段名 asc/desc :     默認asc升序,desc為降序。ascending,descending

例子:
1:查詢所有的商品,按價格進行降序排序
    select * from product order by price desc;
2:查詢所有名稱含有"士"的商品,并按價格降序排序
    select * from product where name like '%士%' order by price desc;

order by 的排序在篩選完成后進行,因此order by語句放在sql語句最后面。

2.4 聚合函數

聚合函數不統計null值。

* count(*|字段名); 對全部/某列的數據計數
* sum():求和
* max:求最大值
* min:求最小值
* avg:求平均值

例子:
1:獲得所有商品的價格的總和:
    select sum(price) from product;
2:獲得所有商品的平均價格:
    select avg(price) from product;
3:獲得所有商品的個數
    select count(*) from product; 統計所有商品一般用*

2.5 分組

group by 字段名    :
group_concat():組合在一起

案例:group by結合聚合函數使用(聚合函數前寫得字段名必須是用于分組的字段名)
-- 創建數據庫mydb1
CREATE DATABASE mydb1;
-- 使用數據庫mydb1
USE mydb1;
-- 創建表單product
CREATE TABLE product(
    id INT,NAME VARCHAR(50),price INT
);
-- 往表格中添加數據
INSERT INTO product VALUES(1,'蘋果',20);
INSERT INTO product VALUES(2,'李子',2);
INSERT INTO product VALUES(3,'葡萄',55);
INSERT INTO product VALUES(4,'桃子',40);
INSERT INTO product VALUES(5,'西瓜',22);
INSERT INTO product VALUES(88,'冬瓜',10);
-- 將所有商品的id值變為1
UPDATE product SET id=1;
-- 將部分商品的id值變為2
UPDATE product SET id=2 WHERE price BETWEEN 10 AND 30;
-- 1:根據id字段分組,分組后統計商品的個數
SELECT id,COUNT(*) AS '商品數量' FROM product GROUP BY id;
-- 2:根據id字段分組,分組統計每組商品的平均價格,并且平均價格大于20
SELECT id,AVG(price) AS 平均價格 FROM product GROUP BY id HAVING AVG(price)>20;
-- 3:根據id字段分組,顯示每組里面的成員,這個時候如果只用group by就只能顯示每組的第一個成員,因此要加上group_concat():括號內不能用*
SELECT id,GROUP_CONCAT(NAME) FROM product group by id;

1:

2:

3:

2.6 分組后篩選(having)

  • having是分組后篩選

where和having的區別

  • 1.having是在分組后對數據進行過濾.where是在分組前對數據進行過濾
  • 2.having后面可以使用聚合函數(統計函數)where后面不可以使用聚合函數。理解:沒有篩選出某一列數據之前當然不能用聚合函數進行統計。
  • 3.having后面加的條件一定要與分組有關,因為他是分組后進行篩選的關鍵字。
  • 4.WHERE是分組前記錄的條件,如果某行記錄沒有滿足WHERE子句的條件,那么這行記錄不會參加分組;而HAVING是對分組后數據的約束。

2.7 分頁查找(limit)

sql查詢語句完整格式
select [distinct] */列名,列名... from 表名 where 條件 group by 按照?列名分組
order by[asc/desc] having 分組后篩選條件 limit m,n;

distinct去重,where是在分組前的篩選條件,group by一般和聚合函數或者group_concat一起使用,
單獨使用沒意義。order by默認排序asc,having后接分組后的篩選條件。limit中m代表從第m行開始,
顯示n行。
分頁顯示:limit (current-1)*n,n; current為當前頁面,下一頁的limit格式就是這樣寫

3 數據完整性

為了確保用戶輸入的數據保存到數據庫中是正確的,在創建表的時候要給表中的列添加約束。

完整性的分類

  • 實體完整性
  • 域完整性
  • 引用完整性

3.1 實體完整性

實體中的每一行就代表一個實體。實體完整性的作用:標識的每一行記錄都不重復

約束類型:主鍵約束(primary key),唯一約束(unique),自動增長列(auto_increment)

3.1.1 主鍵約束(primary key)

注意:每個表中都必須要有一個主鍵

特點:數據唯一,且不能為null,相當于unique和not null的結合

三種添加主鍵的方式:

方式一:直接在建表字段定義時添加
create table user(
    id int primary key
);

方式二:建表時在最后添加,好處時可以創建聯合主鍵
create table user(
    id int,username varchar(50),
    primary key(id)
);

create table user(
    id int,
    name varchar(50),
    primary key(id,name)
);

方式三:通過sql語句添加:
create table user(id int,name varchar(50));
alter table user add constraint user_pk primary key(id);

3.1.2 唯一約束(unique)

特點:數據不能重復

create table user(id int,username varchar(50) unique);

3.1.3 自動增長列(auto_increment)

特點:給主鍵添加自動增加的數值,列只能是整數類型

create table user(
    id int primary key auto_increment,username varchar(50)
);

3.2 域完整性

域完整性的作用:限制此單元格的數據正確

域完整性約束:

  • 非空約束:not null
  • 默認值約束:default

3.2.1 非空約束(not null)

create table user(
    id int,name varchar(50) not null
);
name被限制不能為空

3.2.2 默認約束(default)

create table user(
    id int,name varchar(50),sex varchar(20) default '男'
);
insert into user values(1,'小芳','女');
insert into user values(1,'小芳',default);

3.3 引用完整性(foreign key:外鍵約束)

外鍵約束的兩種添加方式:

create table student(
    sid int primary key auto_increment,
    username varchar(50) not null,
    sex varchar(10) default '男'
);

create table score(
    id int primary key auto_increment,
    score int,
    sid int
);
方式一:直接在建表時表中添加
create table score(
    id int primary key auto_increment,name varchar(50) not null,
    sid int,
    constraint fk_score_sid foreign key(sid) references student(sid)
);
    
方式二:sql語句添加外鍵
alter table  score add constraint fk_score foreign key(sid) references student(sid);

3.4 表與表之間的關系

外鍵指向主鍵

3.4.1 一對一

對其中任意一個表添加一個外鍵列,并且要給外鍵列添加唯一約束,否則就不是一對一而是一對多了

3.4.2 一對多(多對一):相對而言

在多的一方添加外鍵列,創建外鍵約束指向一的表的主鍵。

3.4.3 多對多

需要創建一個第三方表格,至少要有兩個外鍵列,分別指向兩個表的主鍵

4 多表查詢

多表查詢有以下幾種:

  • 連接查詢【重要】
    • 內連接查詢 --- 隱式連接、顯式連接
    • 外連接查詢 --- 左外連接、右外連接
  • 子查詢【非常重要】
  • 聯合查詢

4.1 連接查詢【重要】

連接查詢就是求出多個表的乘積,例如t1連接t2,那么查詢出的結果就是t1*t2。

連接查詢會產生笛卡兒積,這樣的查詢結果會有大量的無用數據,所以就需要使用篩選得到可用數據

4.1.1 內連接查詢

語法:

隱式內連接:
select [*][列名,列名...] from t1,t2 [where條件];
顯式內連接:
select [*][類名,列名...] from t1 [inner] join t2 on [篩選條件] [where條件];
4.1.2 外連接查詢

語法:

左外連接查詢:
select [*][列名,列名...] from t1 left [outer] join t2 on[篩選條件][where條件];
右外連接查詢:
select [*][列名,列名...] from t1 right [outer] join t2 on[篩選條件][where條件]

外連接和內連接的區別:

  • 內連接放在前面的顯示作為主表,右邊的作為從表。外連接則跟左右連接有關。

  • 內連接查詢特點:查詢結果必須滿足條件,不滿足條件不顯示。

      例:張三的部門deptno為50,而在dept表中只有10、20、30、40部門,
      那么內連接查詢結果中就不會出現“張三”這條記錄,
      因為它不能滿足e.deptno=d.deptno這個條件。
    
  • 外連接查詢特點:查詢出的結果存在不滿足條件的可能。滿足條件的顯示出來,不滿足條件的顯示NULL。

      emp表中“張三”這條記錄中,部門編號為50,
      而dept表中不存在部門編號為50的記錄,
      所以“張三”這條記錄不能滿足e.deptno=d.deptno這條件。
      但在左連接中,因為emp表是左表,所以左表中的記錄都會查詢出來,
      即“張三”這條記錄也會查出,但相應的右表部分顯示NULL。
    

4.2 子查詢【非常重要】

子查詢就是嵌套查詢,即select包含select

子查詢出現的位置:
1:where后面,作為被查詢條件的一部分
2:from后面,作表
具體使用見例子

當子查詢結果集形式為多行單列時可以使用ALL或ANY關鍵字

例如:
1:查詢工資高于30號部門所有人的員工信息
select * from emp where sal>(select max(sal) from emp where deptno=30);
等價于:
select * from emp where sal>ALL(select sal from emp where deptno=30);

2:查詢工作和工資與MARTIN完全相同的員工信息
select * from emp where (job,sal) in (select job,sal from emp where name='martin');

3:有2個以上直接下屬的員工信息
select * from emp where mgr in(select mgr from emp group by mgr having count(*)>=2);

4:求各個部門薪水最高的員工所有信息
select * from emp e,(select max(sal) as maxsal,deptno from emp group by deptno) as a 
where e.sal=a.maxsal and a.deptno=e.deptno;

4.3 聯合查詢

聯合查詢就是把兩個select語句的查詢結果合并到一起

被合并的兩個結果:列數、列類型必須相同。

合并查詢的兩種方式:
union:去除重復記錄
    select * from t1 union select * from t2;

union all:不去除重復記錄
    select * from t1 union select * from t2;

5 多表查詢的練習

-- mysql

-- 新建一個day09_exercise的數據庫
CREATE DATABASE day09_exercise;
USE day09_exercise;
SELECT DATABASE();

-- 創建用戶user表
CREATE TABLE USER(
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50)
);
DESC USER;
-- 創建訂單表
CREATE TABLE orders(
    id INT PRIMARY KEY AUTO_INCREMENT,
    price DOUBLE,
    user_id INT
);
DESC orders;
-- 給訂單表添加外鍵約束\  一對多,向多的表格添加外鍵
ALTER TABLE orders ADD CONSTRAINT user_fk FOREIGN KEY(user_id) REFERENCES USER(id);

-- 向user表中添加數據
INSERT INTO USER VALUES(3,'張三'),(4,'李四'),(5,'王五'),(6,'趙六');
SELECT * FROM USER;
-- 向orders表中插入數據
INSERT INTO orders VALUES(1,1314,3),(2,1314,3),(3,15,4),(4,315,5),(5,1014,NULL);
SELECT * FROM orders;

-- mysql練習三:
-- --查看用戶為張三的訂單詳情
-- 思路:多表查詢
-- 內連接查詢---隱式查詢:
SELECT * FROM USER u,orders o WHERE u.id=o.user_id AND u.username='李四';
-- 內連接查詢---顯式查詢:
SELECT * FROM USER u INNER JOIN orders AS o ON u.id=o.user_id WHERE u.username='李四';
SELECT * FROM orders AS o INNER JOIN USER u ON u.id=o.user_id AND u.username='李四';
-- 上面查詢時,on后面接and表示并且查詢也可以,但不建議,推薦除了主從表的條件用on,其他條件用where
-- 在前面的作為主表,顯示時出現在前面
-- 外連接查詢---左連接查詢
SELECT * FROM USER u LEFT OUTER JOIN orders o ON u.id=o.user_id WHERE u.username='李四';
--- 外連接查詢---右連接查詢
SELECT * FROM USER u RIGHT OUTER JOIN orders o ON u.id=o.user_id WHERE u.username='李四';
-- 外連接和內連接的區別:
-- 

-- 查詢出訂單的價格大于300的所有用戶信息。
SELECT * FROM USER WHERE id=(SELECT user_id FROM orders WHERE price>300); -- 錯誤
-- 上面式子錯誤,子查詢得到的結果是多個的,用id=只能等于一個數,因此用in
SELECT * FROM USER WHERE id IN (SELECT user_id FROM orders WHERE price>300);

-- 查詢訂單價格大于300的訂單信息及相關用戶的信息。
SELECT * FROM USER,orders WHERE user.id=orders.user_id AND price>300;
-- 上面兩個式子,前者user中沒有price列,所以要到orders里面找到price來進行篩選,
-- 而后者則是拼接后進行篩選,這個時候的表格中已經有price列了,因此直接篩選即可

sql語句具體的用法見 練習題

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1、MySQL啟動和關閉(安裝及配置請參照百度經驗,這里不再記錄。MySQL默認端口號:3306;默認數據類型格式...
    強壯de西蘭花閱讀 678評論 0 1
  • 回顧 字段類型(列類型):數值型,時間日期型和字符串類型 數值型:整型和小數型(浮點型和定點型) 時間日期型:da...
    翊溪閱讀 982評論 0 0
  • .數據庫 數據庫的發展: 文件系統(使用磁盤文件來存儲數據)=>第一代數據庫(出現了網狀模型,層次模型的數據庫)=...
    小Q逛逛閱讀 1,010評論 0 2
  • MySQL技術內幕:SQL編程 姜承堯 第1章 SQL編程 >> B是由MySQL創始人之一Monty分支的一個版...
    沉默劍士閱讀 2,475評論 0 3
  • 1.MySQL數據庫 2.SQL語句 第一節課 ###1(MySQL數據庫)數據庫概念.avi 5...
    碼了個農啵閱讀 1,242評論 1 16