1. 程式人生 > 其它 >mysql外來鍵,鎖

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.01
sec) 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';