数据库主键和外键
? ? ? ? ? ? 剛開始學數據庫的時候,剛接觸到的一個較為陌生的概念就是主鍵和外鍵。啥叫主鍵,從字面意思上來看感覺一臉懵。簡單點說主鍵就類似每個人的身份證,代表一個唯一的某個人,而且主鍵不能為空,估計你也沒見過哪個人沒有身份證的。
? ? ? ? ? ? ?那外鍵是啥,一個表中的某一個或多個字段是關聯另一個表的主鍵,那我們把這一個或多個字段稱為這個表的外鍵,外鍵可以是這個表的主鍵也可以不是。外鍵的作用是保證引用數據的完整性。
? ? ? ? ? ? 來看看書上是怎么定義主鍵的。主鍵:又稱主碼,是表中一列或多列的組合。下面來展示如何創建主鍵。
create table stu( id int PRIMARY KEY, name varchar(10), hobby varchar(20) ); Query OK, 0 rows affected (0.03 sec)mysql> show create table stu; +-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | stu | CREATE TABLE `stu` (`id` int(11) NOT NULL,`name` varchar(10) DEFAULT NULL,`hobby` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 | +-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)主鍵id顯示的是NOT NULL,PRIMARY KEY (`id`)表明id是主鍵,上面是單字段主鍵。
mysql> create table stu1( id int , name varchar(10), hobby varchar(20),primary key(id,name) ); Query OK, 0 rows affected (0.02 sec)mysql> show create table stu1; +-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | stu1 | CREATE TABLE `stu1` (`id` int(11) NOT NULL,`name` varchar(10) NOT NULL,`hobby` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`,`name`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 | +-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)mysql>上面是多字段主鍵。
mysql> create table stu2( id int primary key, stu_id int, name varchar(20),constraint fk_stu foreign key(stu_id) references stu(id) ); Query OK, 0 rows affected (0.04 sec)mysql> mysql> mysql> show create table stu2; +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | stu2 | CREATE TABLE `stu2` (`id` int(11) NOT NULL,`stu_id` int(11) DEFAULT NULL,`name` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`),KEY `fk_stu` (`stu_id`),CONSTRAINT `fk_stu` FOREIGN KEY (`stu_id`) REFERENCES `stu` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 | +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)mysql>在表stu2上添加了fk_stu的外鍵約束,外鍵名稱為stu_id,其依賴于表stu的主鍵id。下面來看外鍵保證引用數據的完整性 。
mysql> select * from stu2; +----+--------+------+ | id | stu_id | name | +----+--------+------+ | 1 | 1 | lisi | +----+--------+------+ 1 row in set (0.00 sec)mysql> select * from stu; +----+----------+-------+ | id | name | hobby | +----+----------+-------+ | 1 | zhangdan | daqiu | +----+----------+-------+ 1 row in set (0.00 sec)上面是2個表中的數據。表stu2的外鍵stu_id和stu的主鍵一一對應?,F在再想表stu2中插入數據。
mysql> insert into stu2 values(1,2,"wangwu"); ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY' mysql>插入記錄報錯了,因為表stu中沒有id=2的記錄。
mysql> insert into stu values(2,"wangwu","chifan"); Query OK, 1 row affected (0.00 sec)mysql> select * from stu; +----+----------+--------+ | id | name | hobby | +----+----------+--------+ | 1 | zhangdan | daqiu | | 2 | wangwu | chifan | +----+----------+--------+ 2 rows in set (0.00 sec) mysql> insert into stu2 values(2,2,"zhaoliu"); Query OK, 1 row affected (0.00 sec)mysql> select * from stu2; +----+--------+---------+ | id | stu_id | name | +----+--------+---------+ | 1 | 1 | lisi | | 2 | 2 | zhaoliu | +----+--------+---------+ 2 rows in set (0.00 sec)mysql>我們先向表stu表插入id=2的字段,再對stu2操作就成功了。主表先動,從表才能動。從表是含有外鍵約束的那個表,主表就是那個含有外鍵約束對應主鍵的那個表。再想想,如果試著刪除某一行會發生啥。
mysql> delete * from stu2 where id=2; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '* from stu2 where id=2' at line 1 mysql> delete * from stu where id=2; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '* from stu where id=2' at line 1 mysql>不管對stu還是stu2進行刪除操作都會失敗,因為2個表已經有了約束關系,誰也離不開誰了。
?
?
?
?
?
總結
- 上一篇: lsof根据端口查进程
- 下一篇: is null和is not null运