1. 程式人生 > >淺談資料庫(四)

淺談資料庫(四)

**

淺談資料庫(四)

**
**

```
1、外來鍵(foreign key)
  1、定義 :讓當前表的欄位值在另一張表的範圍內去選擇
  2、語法格式
    foreign key(參考欄位名)
    references 主表(被參考欄位名)
    on delete 級聯動作
    on update 級聯動作;
  3、使用規則
    1、主表、從表字段資料型別要一致
    2、主表 :被參考欄位是主鍵
  4、示例
    1、表1:繳費資訊表(財務) :jftab
           id  姓名    班級  繳費金額
	    1  唐伯虎  AID07    300
	    2  點秋香  AID07    300
       表2:學生資訊表(班主任) :bjtab
           stu_id  姓名   繳費金額
    2、建立表 
      表1 :jftab
        create table jftab(
	id int primary key,
	name varchar(20) not null,
	class char(5),
	money smallint
	)character set utf8;
	insert into jftab values
	(1,"唐伯虎","AID07",300),
	(2,"點秋香","AID07",300),
	(3,"文徵明","AID07",300);
      表2 :bjtab
        create table bjtab(
	stu_id int,
	name varchar(20),
	money smallint,
	foreign key(stu_id) references jftab(id)
	on delete cascade
	on update cascade
	)character set utf8;
    3、刪除外來鍵
      alter table 表名 drop foreign key 外來鍵名;
      外來鍵名檢視 :show create table 表名;
    4、已有表新增外來鍵
      alter table 表名 add 
      foreign key(stu_id) references jftab(id)
      on delete 級聯動作
      on update 級聯動作;
    5、級聯動作
      1、cascade 
        資料級聯刪除,級聯更新(參考欄位)
      2、restrict(預設)
        從表中有相關聯記錄,不允許主表操作
      3、set null
        主表刪除、更新,從表相關聯記錄欄位值為NULL
2、巢狀查詢(子查詢)
  1、定義 :把內層的查詢結果作為外層的查詢條件
  2、語法
    select ... from 表名 where 欄位名 運算子 (select ... from 表名 where 條件);
  3、練習
    1、把攻擊值小於平均攻擊值的名字和攻擊值顯示出來
      1、先求平均值
        select avg(gongji) from sanguo;
      2、找結果
        select name,gongji from sanguo where gongji<值;
      select name,gongji from sanguo where 
      gongji<(select avg(gongji) from sanguo);
    2、找出每個國家攻擊力最高的英雄的名字和攻擊值
      # 有問題語句
      select name,gongji from sanguo
      where
      gongji in(select max(gongji) from sanguo group by country);
      # 無問題語句
      select name,gongji from sanguo
      where
      (country,gongji) in(select country,max(gongji) from sanguo group by country);
3、多表查詢
  1、兩種方式
    1、笛卡爾積 :不加where條件
      select ... from 表1,表2;
    2、加where條件
      select ... from 表1,表2 where 條件;
    3、
      1、記錄多的表的每一條記錄,去匹配另一張表的所有記錄
      2、2張表記錄條數相同,則後表的每一條記錄去匹配前表的所有記錄
  2、練習
    1、顯示 省、市詳細資訊
      河北省   石家莊市
      河北省   廊坊市
      廣東省   廣州市
      廣東省   深圳市
      select sheng.s_name,city.c_name from sheng,city where 
      sheng.s_id=city.cfather_id;
    2、顯示省、市、縣詳細資訊
      select sheng.s_name,city.c_name,xian.x_name from 
      sheng,city,xian
      where
      sheng.s_id=city.cfather_id and city.c_id=xian.xfather_id;
4、連線查詢
  1、內連線(inner join)
    1、語法格式
      select 欄位名列表 from 表1
      inner join 表2 on 條件
      inner join 表3 on 條件;
    2、練習
      1、顯示省、市詳細資訊(只顯示匹配到的)
        select sheng.s_name,city.c_name from sheng 
        inner join city
        on sheng.s_id=city.cfather_id;
      2、顯示省市縣詳細資訊
        select sheng.s_name,city.c_name,xian.x_name from sheng
        inner join city on sheng.s_id=city.cfather_id
        inner join xian on city.c_id=xian.x_father_id;
  2、外連線
    1、左連線(left join)
      1、以 左表為主 顯示查詢結果
      2、select 欄位名列表 from 表1
         left join 表2 on 條件
	 left join 表3 on 條件;
      3、練習
        1、顯示省、市詳細資訊,要求省全部顯示
	
	2、顯示省市縣詳細資訊,要求省全部顯示
	  select sheng.s_name,city.c_name,xian.x_name from sheng
          left join city on sheng.s_id=city.cfather_id
          left join xian on city.c_id=xian.xfather_id;
    2、右連線(right join)
      以右表為主顯示查詢結果,用法同左連線
5、鎖
  1、目的 :解決客戶端併發訪問的衝突問題
  2、鎖分類
    1、鎖型別 
      1、讀鎖(共享鎖)
        查詢(select):加讀鎖之後,別人不能更改表記錄,但可以進行查詢
      2、寫鎖(互斥鎖、排他鎖)
        更新(update):加寫鎖之後別人不能查、不能改
    2、鎖粒度
      1、行級鎖 :Innodb
        select :加讀鎖,鎖1行
	update :加寫鎖,鎖1行
      2、表級鎖 :MyISAM
        select :加讀鎖,鎖1張表
	update :加寫鎖,鎖1張表
6、儲存引擎(engine :處理表的處理器)
  1、基本操作命令
    1、檢視所有儲存引擎
      show engines;
    2、檢視已有表的儲存引擎
      show create table 表名;
    3、建立表指定儲存引擎
      create table 表名(...)engine=myisam,charset=utf8;
    4、已有表
      alter table 表名 engine=myisam;
  2、常用儲存引擎的特點
    1、InnoDB特點
      1、支援事務、外來鍵、行級鎖
      2、共享表空間
        表名.frm :表結構和索引資訊  
	表名.ibd : 表記錄
    2、MyISAM特點
      1、支援表級鎖
      2、獨享表空間
        表名.frm :表結構
	表名.MYD :表記錄
	表名.MYI :索引資訊
    3、Memory儲存引擎
      1、資料儲存在記憶體中,速度快
      2、伺服器重啟、MySQL服務重啟後表記錄消失
  3、如何決定使用哪個儲存引擎
    1、查詢操作多的表使用MyISAM(使用InnoDB浪費資源)
    2、寫操作多的表使用InnoDB
7、MySQL使用者賬戶管理
  1、開啟MySQL遠端連線(改配置檔案)
    1、sudo -i
    2、cd /etc/mysql/mysql.conf.d/
    3、cp mysqld.cnf mysqld.cnf.bak2
    4、vi mysqld.cnf
      #bind-address=127.0.0.1
      把前面 # 去掉,儲存退出
      vi mysqld.cnf
      按a -> 改內容 -> 按ESC -> 按 shift + : -> wq
    5、/etc/init.d/mysql restart
  2、用root使用者新增授權使用者
    1、用root使用者登入mysql
      mysql -uroot -p123456
    2、授權
      grant 許可權列表 on 庫名.表名 
      to "使用者名稱"@"%" identified by "密碼"
      with grant option;
      許可權列表 :all privileges、select、update
      庫名.表名 :db4.* 、*.*(所有庫的所有表)
    3、示例
      1、新增授權使用者tiger,密碼123,對所有庫的所有表有所有許可權,可從任何IP去連線
        grant all privileges on *.* 
        to "tiger"@"%"
        identified by "123"
        with grant option;
      2、新增授權使用者rabbit,密碼123,對db4庫所有表只有查詢許可權,可從任何IP去連線
        grant select on db4.* 
        to "rabbit"@"%" identified by "123"
        with grant option;
8、作業講解
  1、/etc/passwd 匯入到資料庫表中
     tarena:x:1000:1000:tarena,,,:/home/tarena:/bin/bash
    1、建立對應的表
      create table userinfo(
      username varchar(20),
      password char(1),
      uid int,
      gid int,
      comment varchar(50),
      homedir varchar(50),
      shell varchar(50)
      );
    2、複製檔案到 /var/lib/mysql-files/
      sudo cp /etc/passwd /var/lib/mysql-files/
    3、輸入匯入語句
      load data infile "/var/lib/mysql-files/passwd"
      into table db4.userinfo
      fields terminated by ":"
      lines terminated by "\n";
  2、在userinfo表中第一列新增id欄位,主鍵、自增長、顯示寬度為3,位數不夠用0填充
    alter table userinfo add 
    id int(3) zerofill primary key auto_increment first;
```

**