mysql外來鍵,鎖
mysql外來鍵:
場景:用於建立兩個表之間的聯絡,讓A表中一個欄位,可以在另一個表中欄位值的範圍去查詢
注意事項:
(1)被參照表和參照表字段屬性必須一致
(2)參照表必須設定主鍵
(3)必須選擇支援外來鍵的
外來鍵:foreign key 表A欄位名
references 表B 欄位名
如何新增外來鍵:
例子:建立test5員工姓名錶,和test6員工工資表,在test6表查詢員工工資 mysql> create table test5 (name char(30),primary key(name),age tinyint(90)); Query OK, 0 rows affected (0.01sec) mysql> desc test5; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | name | char(30) | NO | PRI | NULL | | | age | tinyint(90) | YES | | NULL | |
插入兩個員工資訊 mysql> insert test5 values ('zhangsan',30),('lisi',40);
檢視下test5表內容 mysql> select * from test5; +----------+------+ | name | age | +----------+------+ | lisi | 40 | | zhangsan | 30 | +----------+------+
建立test6表,並設定外來鍵 mysql> create table test6 (name char(40),money int(100),foreign key(name) references test4(name)); #foreign key(當前表外來鍵欄位) #references test4(name)被參照表的表名和欄位,中間不能有逗號
如果在test6表中插入數值,範圍必須從test5中的主鍵欄位裡面選值
先檢視下test5的資料內容 mysql> select * from test5; +----------+------+ | name | age | +----------+------+ | lisi | 40 | | zhangsan | 30 | +----------+------+ 去test6表插入其他名字的欄位會有外來鍵約束 mysql> insert test6 values ('www',99),('zhongguo',57); ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`db1`.`test6`, CONSTRAINT `test6_ibfk_1` FOREIGN KEY (`name`) REFERENCES `test4` (`name`)) 插入lisi 看看 mysql> insert test6 values ('zhangsan',99); Query OK, 1 row affected (0.01 sec) mysql> select * from test6; +----------+-------+ | name | money | +----------+-------+ | lisi | 22 | | zhangsan | 99 | +----------+-------+
如何修改外來鍵,同步修改同步刪除:on update cascade on delete cascade
mysql> create table test6 (name char(100),money int(99),foreign key(name) references test5(name) on update cascade on delete cascade);
mysql> update test5 set name='hhh' where age=55; Query OK, 1 row affected (0.01 sec)
檢視test5和test6的值就是一樣的
如何刪除外來鍵裡面的資料:
mysql> delete from test5 where name='zhangsan'; Query OK, 1 row affected (0.01 sec) mysql> select * from test5; +------+------+ | name | age | +------+------+ | hhh | 55 | +------+------+ 1 row in set (0.00 sec) mysql> select * from test6; +------+-------+ | name | money | +------+-------+ | hhh | 888 | +------+-------+ 1 row in set (0.00 sec)
如何檢視外來鍵:
show create table test5;
如何刪除外來鍵約束:
匯入資料(需禁用SElinux):
格式:load date infile '檔案的絕對路徑' into table table_name fields terminated by '檔案分隔符' lines terminated by '\n';
數值比較:
select name,UID from table_name where UID > 0; #查詢UID大於0的名字
select name,UID from table_name where UID > 0 and UID < 100 #查詢UID在0-100間的名字
select name from table_name where describe = 'root'; 檢視
limit排序,限制顯示行數
select * from table_name limit 1,2;
#第一行不顯示,顯示第二三行
如何設定屬性的預設值
mysql> create table t7 (name char(30),primary key(name),age tinyint(90) default 23); #建立t7表,建立名字欄位並且設定為主鍵,建立age欄位,預設是23 插入資料: mysql> insert t7 (name) values ('zhangsan'); Query OK, 1 row affected (0.00 sec) mysql> select * from t7; +----------+------+ | name | age | +----------+------+ | zhangsan | 23 | +----------+------+ 1 row in set (0.00 sec)
不進入資料庫查詢某個表的一列欄位
select 表名.欄位名 from 資料庫名.表名; 例子:mysql> select t7.name from db1.t7 ; +----------+ | name | +----------+ | zhangsan | +----------+
多表查詢:
格式:select * from 表1名,表2名 where 表1名.欄位名=表2名.欄位名; 例子:mysql> select * from test3,test4 where test3.name=test4.name; +------+--------+--------+---------+-------+------+------+ | name | gender | hobby3 | address | money | name | age | +------+--------+--------+---------+-------+------+------+ | lisi | NULL | NULL | NULL | NULL | lisi | 30 | +------+--------+--------+---------+-------+------+------+
左連線查詢:
格式:select 欄位名 from 表a left join 表2 on 表1名.欄位名=表1名.欄位名; 例子:檢視下test3和4 mysql> select * from test4; +----------+------+ | name | age | +----------+------+ | lisi | 30 | | wanger | 10 | | zhangsan | 10 | +----------+------+ 3 rows in set (0.00 sec) mysql> select * from test3; +------+--------+--------+---------+-------+ | name | gender | hobby3 | address | money | +------+--------+--------+---------+-------+ | lisi | NULL | NULL | NULL | NULL | | 10 | NULL | NULL | NULL | NULL | +------+--------+--------+---------+------- 以3為準左連查詢: mysql> select test3.name from test3 left join test4 on test3.name=test4.name; +------+ | name | +------+ | lisi | | 10 | +------+ 以test4為準右連查詢: mysql> select test3.name from test3 right join test4 on test3.name=test4.name; +------+ | name | +------+ | lisi | | NULL | | NULL | +------+ 3 rows in set (0.00 sec)
#以test4為準,test3裡面沒有這個值所有顯示Null
mysql儲存引擎
1.MyISAM
特點:mysql5.5之前預設是MyISAM版的儲存引擎
不支援事務
表級鎖
讀寫相互阻塞,寫的時候不能讀,讀的時候不能寫
讀取速度快,佔用資源少
不支援mvcc高併發
崩潰恢復性較差
使用場景:只讀,寫入情況比較少,表比較小,能接受長時間進行修復操作
MyISAM物理檔案:
.frm表格式定義
.myd資料檔案
.myi索引檔案
2,InnoDB
特點:支援行級鎖
支援MVCC多併發控制
支援事務,適合處理大量短期事務
讀寫阻塞與事務隔離級別有關
崩潰恢復性好
5.5後作為預設儲存引擎
InnoDB資料檔案:
表資料和索引在同一個表空間
資料檔案:ibdatal datadir
表格式檔案:frm datadir 下的資料庫對應目錄下
檢視所有的儲存引擎:
show engines;
檢視當前預設儲存引擎:
show variables like '%storage_engine%'; +----------------------------------+--------+ | Variable_name | Value | +----------------------------------+--------+ | default_storage_engine | InnoDB | | default_tmp_storage_engine | InnoDB | | disabled_storage_engines | | | internal_tmp_disk_storage_engine | InnoDB | +----------------------------------+--------+
mysql鎖機制
讀鎖:共享鎖 S 只讀不可寫,包含當前事務,多個讀不阻塞
寫鎖,X寫鎖會影響其他事務的讀寫操作,不包含當前事務
讀鎖例子: 格式:locak table 表名 read; 例子: lock table test3 read; 檢視這個表:select * from test3; 插入資料:insert test3 (name) values ('wanger'); ERROR 1099 (HY000): Table 'test3' was locked with a READ lock and can't be updated 寫鎖: 格式:lock table 表名 write; 例子:
案例:找到未完成的導致 阻塞的事務
#在第一個會話中開啟一個事務
mysql> use db1;
mysql> begin;
mysql> update date set name="centos";
mysql> select * from date;
#在第二個會話中執行(不需要開啟一個事務)
mysql> select * from db1.date;
mysql> update date set name="rhel";
#在運維管理會話
mysql> show engine innodb status\G;
#檢視當前正在進行的事務
mysql> select * from information_schema.innodb_trx\G;
#檢視當前鎖定的事務
mysql> select * from information_schema.innodb_locks\G;
#檢視當前等鎖的事務
mysql> select * from information_schema.innodb_lock_waits\G;
如何解決?
#檢視事務列表
mysql> show processlist;
mysql> show processlist; +----+------+-----------+------+---------+------+---------------------------------+----------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------+------+---------+------+---------------------------------+----------------------+ | 3 | root | localhost | db1 | Sleep | 6800 | | NULL | | 4 | root | localhost | NULL | Sleep | 3850 | | NULL | | 5 | root | localhost | db1 | Sleep | 56 | | NULL | | 6 | root | localhost | db1 | Query | 19 | Waiting for table metadata lock | select * from test4 | | 9 | root | localhost | NULL | Query | 0 | starting | show processlist | +----+------+-----------+------+---------+------+---------------------------------+----------------------+ 5 rows in set (0.01 sec)
殺死lock:
mysql >kill 事務id;
可以通過show processlist和檢視系統事務得到
#檢視事務鎖的超時時長,預設50s
mysql> show global variables like 'innodb_lock_wait_timeout';