為什麼需要外來鍵

2021-09-26 05:05:51 字數 3998 閱讀 7352

例如:如何將乙個使用者的使用者資訊及其多個郵寄商品位址儲存到資料庫中?(資料特點:有較多的冗餘資料,即賬戶和密碼相同其他資訊有差別)

方案一:

create table user_info(#建立共享資訊**

id char(36) primary key,#id資訊為主鍵

user_name varchar(30) not null,#user_name不能為空

password varchar(30) not null,#password不能為空

real_name varchar(8),

mobile char(11),

address varchar(150)

);insert into user_info (id,user_name,password,real_name,mobile,address)#傳入資料

values ('51b28fe1-4ebf-41ac-a17b-d5e276861fd0','fuliuqingfeng','123456','張三','18920120206','河南安陽');

insert into user_info (id,user_name,password,real_name,mobile,address)

values ('cc95772b-75a2-4702-bd99-4c3b0322d606','fuliuqingfeng','123456','李四','18617297545','北京海淀');

insert into user_info (id,user_name,password,real_name,mobile,address)

values ('c63028fd-cf8d-4dac-a278-b5cc8fd61e3c','fuliuqingfeng','123456','王五','17694976949','山西大同');

mysql資料庫執行結果:

問題:這種表結構存在嚴重的字段冗餘(user_name和password列),如果個人資訊字段比較多這一問題表現的越嚴重。

方案二:將**拆分,使兩者存在物理上的從屬關係

create table user_info(#建立共享資訊**

id char(36) primary key,

user_name varchar(30) not null,

password varchar(30) not null

)insert into user_info (id,user_name,password) values ('51b28fe1-4ebf-41ac-a17b-d5e276861fd0','fuliuqingfeng','123456');#新增資料

create table address(#其他特有資訊

id char(36) primary key,#實則為外來鍵

user_info_id char(36),

real_name varchar(8) not null,

mobile char(11) not null,

address varchar(150) not null

)insert into address (id,user_info_id,real_name,mobile,address) #向特有資訊**新增資料

values ('bfb9472a-7911-4e6f-a479-3b719454ebab','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','張三','18920120206','河南安陽');

insert into address (id,user_info_id,real_name,mobile,address)

values ('5227c6b9-45a2-44aa-8ac0-1f63a38d3b65','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','李四','18617297545','北京海淀');

insert into address (id,user_info_id,real_name,mobile,address)

values ('30b8584b-aa6a-4516-a623-03f487058586','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','王五','17694976949','山西大同');

問題:這種表結構消除了字段冗餘,但由於只是邏輯上的「外來鍵」關係,所以依然無法保證資料完整性,例如可以將user_info中id為51b28fe1-4ebf-41ac-a17b-d5e276861fd0的資料刪除,但此時位址表中資料將不再完整——找不到這些位址屬於哪個使用者;再例如也可以向address表中新增一條user_info_id不存在的位址資訊(如:insert into address (id,user_info_id,real_name,mobile,address) values ('7da42cc6-36a6-4ad5-9998-71dbc30c8e17','ddc376dd-f8b3-42a6-b42a-db22abed1941','xiaowang','18338970095','北京東城區');)——同樣,該條資料並不完整,依然找不到這些位址屬於哪個使用者。

方案三:使用外來鍵,這種情況下address中只要使用共享資訊,則user——info**將不會被刪除,此時也不會產生「髒資料」

create table user_info(

id char(36) primary key,

user_name varchar(30) not null,

password varchar(30) not null

)insert into user_info (id,user_name,password) values ('51b28fe1-4ebf-41ac-a17b-d5e276861fd0','fuliuqingfeng','123456');

create table address(

id char(36) primary key,

user_info_id char(36),

real_name varchar(8) not null,

mobile char(11) not null,

address varchar(150) not null,

constraint address_user_info_id_fk foreign key(user_info_id) references user_info(id)

)insert into address (id,user_info_id,real_name,mobile,address)

values ('bfb9472a-7911-4e6f-a479-3b719454ebab','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','張三','18920120206','河南安陽');

insert into address (id,user_info_id,real_name,mobile,address)

values ('5227c6b9-45a2-44aa-8ac0-1f63a38d3b65','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','李四','18617297545','北京海淀');

insert into address (id,user_info_id,real_name,mobile,address)

values ('30b8584b-aa6a-4516-a623-03f487058586','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','王五','17694976949','山西大同');

說明:這種方案為user_info_id新增了外來鍵,指向user_info表的主鍵,該約束起到了保護資料完整性的作用:如果刪除的使用者資訊id已經在address表中使用,則該條資料無法刪除;無法向address表中新增使用者id不存在的位址資訊。

為什麼需要外來鍵?

1.如何將京東fuliuqingfeng的使用者資訊及其多個郵寄商品位址儲存到資料庫中?values 51b28fe1 4ebf 41ac a17b d5e276861fd0 fuliuqingfeng 123456 張三 18920120206 河南安陽 insert into user info...

為什麼需要外來鍵

生活中例子的引入 如何將京東fuliuqingfeng的使用者資訊及其多個郵寄商品位址儲存到資料庫中?第一種方法是逐條輸入資料 create table user info id char 36 primary key,user name varchar 30 not null,password v...

為什麼需要外來鍵

情景 create table user info id char 36 primary key,user name varchar 30 not null password varchar 30 not null real name varchar 8 mobile char 11 address...