連接查詢,視圖,事物,索引,外鍵(第四章)


連接查詢

--創建學生表
create table students (
id int unsigned not null auto_increment primary key,
name varchar(20) default '',
age tinyint unsigned default 0,
high decimal(5,2),
gender enum('', '', '中性', '保密') default '保密',
cls_id int unsigned default 0,
is_delete bit default 0
);

 

--創建班級表
create table classes(
id int unsigned auto_increment primary key not null,
name varchar(20) not null
);

--往students表里插入數據
insert into students values
(0,'小明',18,180.00,2,1,0),
(0,'小月月',19,180.00,2,2,0),
(0,'彭於晏',28,185.00,1,1,0),
(0,'劉德華',58,175.00,1,2,0),
(0,'黃蓉',108,160.00,2,1,0),
(0,'鳳姐',44,150.00,4,2,1),
(0,'王祖賢',52,170.00,2,1,1),
(0,'周傑倫兒',34,null,1,1,0),
(0,'程坤',44,181.00,1,2,0),
(0,'和珅',55,166.00,2,2,0),
(0,'劉亦菲',29,162.00,3,3,0),
(0,'金星',45,180.00,2,4,0),
(0,'靜香',18,170.00,1,4,0),
(0,'郭靜',22,167.00,2,5,0),
(0,'周傑',33,178.00,1,1,0),
(0,'錢小豪',56,178.00,1,1,0),
(0,'謝霆鋒',38,175.00,1,1,0);


--向classes表里插入數據
insert into classes values (0, '雲唯_01期'),(0, '雲唯_02期');

 

 

-- 連接查詢(內關聯)
-- inner join ... on
-- 兩個表連接查詢
select * from students inner join classes
-- 查詢能夠對應班級的學生以及班級信息
select * from students inner join classes on students.cls_id=classes.id;
-- 按照要求顯示姓名,班級
select students.*, classes.name from students inner join classes on students.cls_id=classes.id;

-- 給數據表起名字
select s.name, c.name from students as s inner join classes as c on s.cls_id=c.id;

-- 查詢 有能夠對應班級的學生以及班級信息,顯示學生的所有信息,只顯示班級名稱
select students.*, classes.name from students inner join classes on students.cls_id=classes.id;

-- 在以上查詢中將班級姓名顯示在第一列
select classes.name,students.* from students inner join classes on students.cls_id=classes.id;

-- 查詢有能夠對應班級的學生以及班級信息,按照班級進行排序
select classes.id, students.* from students inner join classes on students.cls_id=classes.id order by classes.id;

-- 當是同一個班級的時候,按照學生的id從小到大
select classes.id, students.* from students inner join classes on students.cls_id=classes.id order by classes.id, students.id;

--連接查詢(左關聯,右關聯)
--左關聯,以左邊表為基准,條件對應不上的顯示null
select * from students left join classes on students.cls_id=classes.id; 

--右關聯,以后邊為基准,條件對應不上的顯示null
select * from classes left join students on students.cls_id=classes.id; 



-- 自關聯
create table areas(
aid int primary key auto_increment,
name varchar(20),
pid int
);
-- 查詢出河北省所有市
select * from areas as province inner join areas as city on province.aid=city.pid having name='河北省';

select province.name,city.name from areas as province inner join areas as city on province.aid=city.pid having province.name='河北省';

-- 子查詢
-- 標量子查詢
-- 查詢出北京市所有區的信息
select * from areas where pid=(select aid from areas where name='北京市');


select * from areas where pid in (select aid from areas where name='北京市');

 

 

數據庫的備份與恢復

mysqldump備份工具

 

#備份testdb數據庫(-l代表備份單個數據庫時鎖定該庫的所有表;-x當對所有數據庫備份時鎖定所有數據庫的所有表)
mysqldump -uroot -proot -l --databases testdb > testdb.sql
#備份所有數據庫
mysqldump -uroot -proot --all-databases > all_databases.sql
#備份testdb數據庫下的students表
mysqldump -uroot -proot testdb students > students.sql
#還原數據(sql命令行下)
source testdb.sql

 

利用binlog恢復數據

  #第一步
  vim /etc/my.cnf.d/server.cnf

  [server]
  log-bin=mysql-bin

  

  #第二步,查看二進制文件

  mysqlbinlog /var/lib/mysql/mysql-bin.000001

  

  #第三步,刪除一些數據

  

  #第四步,恢復

  mysqlbinlog mysql-bin.000001 | mysql -uroot -proot

 

視圖

  • 對於復雜的查詢,在多個地方被使用,如果需求發生了改變,需要更改sql語句,則需要在多個地方進行修改,維護起來非常麻煩

 

  1. 假如因為某種需求,需要將user拆房表usera和表userb,該兩張表的結構如下:
          測試表:usera有id,name,age字段
          測試表:userb有id,name,sex字段
       這時如果php端使用sql語句:select * from user;那就會提示該表不存在,這時該如何解決呢。解決方案:創建視圖。以下sql語句創建視圖:
          create view user as select a.name,a.age,b.sex from usera as a, userb as b where a.name=b.name;
  • 視圖本質就是對查詢的封裝
  • 定義視圖,建議以v_開頭
     create view 視圖名稱 as select語句;
  • 查看視圖:查看表會將所有的視圖也列出來
    show tables;
  • 刪除視圖
    drop view 視圖名稱;
    例:
    drop view v_stu_score_course;
  • 使用:視圖的用途就是查詢
    select * from v_stu_score_course;

例:
  • 學生表




  • 班級表

 


create view v_student_info as select classes.c_name as '班級', students.name as '學生' from students inner join classes on students.cls_id=classes.id order by classes.id;

 

 

 

事務

為什么要有事務

   事務具有ACID特性:原子性(A,atomicity)、一致性(C,consistency)、隔離性(I,isolation)、持久性(D,durabulity)。

  • 事務廣泛的運用於訂單系統、銀行系統等多種場景
  • 例如:A用戶和B用戶是銀行的儲戶,現在A要給B轉賬500元,那么需要做以下幾件事:
      1. 檢查A的賬戶余額>500元;
      2. A 賬戶中扣除500元;
      3. B 賬戶中增加500元;
  • 上述3個步驟的操作必須打包在一個事物中,任何一個步驟失敗,則必須回滾所有步驟
  • 可以用start transaction語句開始一個事物,然后要么使用commit提交將修改的數據持久保存,要么使用rollback撤銷所有修改,事物sql的樣本如下:
  • start transation;
  1. select balance from checking where customer_id=1024232;
  2. update checking set balance=balance-200.00 where customer_id=1024232;
  3. update savings set balance=balance+200.00 where customer_id=1024232;
  4. commit;
  • 原子性:事務內的所有操作要么都執行,要么都不執行,它是一個不可分割的工作單位。
  • 一致性:數據庫總是從一個一致性的狀態轉換到另一個一致性的狀態(在前面的例子當中,一致性確保了,即使在執行第三、四條語句之間系統崩潰,支票賬戶也不會損失200美元,因為事物最終沒有被提交,所以事物中所做的修改也不會保存到數據庫中)
  • 隔離性:一個事物所做的修改在最終提交之前,對其他事物是不可見的(在前面的例子中,當執行完第三條語句、第四條語句還未開始時,此時有另外一個賬戶匯總程序開始運行,則其看到的支票賬戶的余額並沒有被減去200美元。)
  • 持久性:事務完成后,該事務內涉及的數據必須持久性的寫入磁盤保證其持久性。當然,這是從事務的角度來考慮的的持久性,從操作系統故障或硬件故障來說,這是不一定的。

事務命令

  • 要求:表的引擎類型必須是innodb類型才可以使用事務,這是mysql表的默認引擎
  • 查看表的創建語句,可以看到engine=innodb
show create table students;
  • 修改數據的命令會觸發事務,包括insert、update、delete

  • 開啟事務,命令如下:

    • 開啟事務后執行修改命令,變更會維護到本地緩存中,而不維護到物理表中
begin;
  • 提交事務,命令如下
    • 將緩存中的數據變更維護到物理表中
commit;
  • 回滾事務,命令如下:
    • 放棄緩存中變更的數據
rollback;
 

索引

  • 思考:在圖書館中是如何找到一本書的?
  • 一般的應用系統對比數據庫的讀寫比例在10:1左右,而且插入操作和更新操作很少出現性能問題,遇到最多的,也是最容易出問題的,還是一些復雜的查詢操作,所以查詢語句的優化顯然是重中之重
  • 當數據庫中數據量很大時,查找數據會變得很慢
  • 優化方案:索引

語法

  • 查看索引
show index from 表名;
  • 創建索引

方式一:建表時創建索引

create table create_index(
id int primary key,
name varchar(10) unique,
age int,
key (age)
);

方式二:對於已經存在的表,添加索引

如果指定字段是字符串,需要指定長度,建議長度與定義字段時的長度一致
字段類型如果不是字符串,可以不填寫長度部分

create index 索引名稱 on 表名(字段名稱(長度))
例:
create index age_index on create_index(age);
  • 刪除索引:
drop index 索引名稱 on 表名;

 

 

  • 測試時間
set profiling=1;#打開sql語句執行時間

show profiles;#查看sql執行時間

 

外鍵foreign key

  • 如果一個實體的某個字段指向另一個實體的主鍵,就稱為外鍵。被指向的實體,稱之為主實體(主表),也叫父實體(父表)。負責指向的實體,稱之為從實體(從表),也叫子實體(子表)

  • 對關系字段進行約束,當為從表中的關系字段填寫值時,會到關聯的主表中查詢此值是否存在,如果存在則填寫成功,如果不存在則填寫失敗並報錯

語法

 

  • 查看外鍵

 

  show create table 表名
  •  添加外鍵
  1. alter table students add constraint fk_students_gid foreign key (gid) references grade(gid) on delete cascade;

 

  • 刪除外鍵

 

  1. show create table 表名
  2.  alter table students drop foreign key 外鍵名字;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM