181
技術社區[雲棲]
MySQL外鍵-涉及天氣預報的小小思考
MySQL中“鍵”和“索引”的定義相同, 所以外鍵和主鍵一樣也是索引的一種。不同的是MySQL會自動為所有表的主鍵進行索引,但是外鍵字段必須由用戶進行明確的索引。
表間一對一關係示例:
有兩張表,第一張表是記錄公司有多少人,都有誰,也就是員工編號及員工姓名這些基本表。另一張表記錄每個月發給用戶多少工資,所謂工資表是也。
但是工資表裏麵不能以員工姓名為主鍵,同樣要通過員工id,因為員工的姓名是可能重複的啊。部門經理叫張三,小弟也叫張三,那這倆張三的工資能一樣嗎?並且員工表裏麵的每個人都有工資,否則誰也不給你幹活,且一個人隻能有一份工資,否則老板也不同意了。所以員工表和工資表是通過員工id進行關聯的一對一關係。
/* 建立員工表 */ create table employees ( id int(5) not null auto_increment , name varchar(8) not null, primary key (id) ) type=innodb; /* 建立工資表 */ create table payroll( id int(5) not null, emp_id int(5) not null, name varchar(8) not null, payroll float(4,2) not null, primary key(id), index emp_id (emp_id), foreign key (emp_id) references employees (id) ) type = innodb;
天氣預報模仿整一個一對一的
城市表
create table city_info(
-> city_id int(5) not null auto_increment,
-> city_code int(5) not null,
-> city_name varchar(8) not null,
-> primary key(city_id)
-> );
天氣表
create table weather_info(
-> id int(5) not null,
-> city_id int(5) not null,
-> weather_date varchar(20) not null,
-> weather_year varchar(20) not null,
-> weather_week varchar(20) not null,
-> weather_temp varchar(20) not null,
-> weather_winddirection varchar(20) not null,
-> weather_windpower varchar(20) not null,
-> weather_description varchar(50) not null,
-> primary key(id),
-> index city_id(city_id),
-> foreign key(city_id) references city_info(city_id)
-> );
搞個例子,簡單演示一下使用,做dage和xiaodi兩個表,大哥表是主鍵,小弟表是外鍵:
建表:
CREATE TABLE `dage` (2
`id` int(11) NOT NULL auto_increment,3
`name` varchar(32) default '',4
PRIMARY KEY (`id`)5
) ENGINE=InnoDB DEFAULT CHARSET=latin1;6

7
CREATE TABLE `xiaodi` (8
`id` int(11) NOT NULL auto_increment,9
`dage_id` int(11) default NULL,10
`name` varchar(32) default '',11
PRIMARY KEY (`id`),12
KEY `dage_id` (`dage_id`),13
CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`dage_id`) REFERENCES `dage` (`id`)14
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
插入個大哥:
mysql> insert into dage(name) values('銅鑼灣');2
Query OK, 1 row affected (0.01 sec)3
mysql> select * from dage;4
+----+--------+5
| id | name |6
+----+--------+7
| 1 | 銅鑼灣 |8
+----+--------+9
1 row in set (0.00 sec)
插入個小弟:
mysql> insert into xiaodi(dage_id,name) values(1,'銅鑼灣_小弟A');2
Query OK, 1 row affected (0.02 sec)3

4
mysql> select * from xiaodi;5
+----+---------+--------------+6
| id | dage_id | name |7
+----+---------+--------------+8
| 1 | 1 | 銅鑼灣_小弟A |9
+----+---------+--------------+
把大哥刪除:
mysql> delete from dage where id=1;2
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`bstar/xiaodi`, CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`dage_id`) REFERENCES `dage` (`id`))
提示:不行呀,有約束的,大哥下麵還有小弟,可不能扔下我們不管呀!
插入一個新的小弟:
mysql> insert into xiaodi(dage_id,name) values(2,'旺角_小弟A'); 2
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`bstar/xiaodi`, CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`dage_id`) REFERENCES `dage` (`id`))3
提示:小子,想造反呀!你還沒大哥呢!
把外鍵約束增加事件觸發限製:
mysql> show create table xiaodi;2



3
CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`dage_id`) REFERENCES `dage` (`id`)4



5
mysql> alter table xiaodi drop foreign key xiaodi_ibfk_1; 6
Query OK, 1 row affected (0.04 sec)7
Records: 1 Duplicates: 0 Warnings: 8
mysql> alter table xiaodi add foreign key(dage_id) references dage(id) on delete cascade on update cascade;9
Query OK, 1 row affected (0.04 sec)10
Records: 1 Duplicates: 0 Warnings: 0
再次試著把大哥刪了:
mysql> delete from dage where id=1;2
Query OK, 1 row affected (0.01 sec)3

4
mysql> select * from dage;5
Empty set (0.01 sec)6

7
mysql> select * from xiaodi;8
Empty set (0.00 sec)
得,這回對應的小弟也沒了,沒辦法,誰讓你跟我on delete cascade了呢!
例子說明的應該蠻清楚了吧,其他功能對應手冊自己實踐吧!:-)
經過一天的思考,見表思路如下;
城市ID 城市名 [主鍵(城市ID)] 1000 北京 1001 上海
1002 重慶
1003 四川
序號 城市ID 日期 溫度[主鍵(序號)][外鍵(城市ID)]
1 1000 20011101 10
2 1000 20011102 10
3 1000 20011103 10
4 1000 20011104 10
第一張表的建立:
CREATE TABLE `city_info` ( `city_id` int(11) NOT NULL , `city_name` varchar(32) default '', PRIMARY KEY (`city_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
第二章表的建立:
CREATE TABLE `weather_info` (
`id` int(11) NOT NULL auto_increment,
`city_id` int(11) default NULL,
`weather_date` varchar(32) default '',
`weather_year` varchar(32) default '',
`weather_week` varchar(32) default '',
`weather_temp` varchar(32) default '',
`weather_winddirection` varchar(32) default '',
`weather_windpower` varchar(32) default '',
`weather_description` varchar(32) default '',
PRIMARY KEY (`id`),
KEY `city_id` (`city_id`),
CONSTRAINT `weather_info_ibfk_1` FOREIGN KEY (`city_id`) REFERENCES `city_info` (`city_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
最後更新:2017-04-02 06:52:09