1. 程式人生 > 實用技巧 >mysql表操作

mysql表操作

約束操作

一 介紹

約束條件與資料型別的寬度一樣,都是可選引數
作用:用於保證資料的完整性和一致性

主要分為:

primary key (pk) 標識該欄位為該表的主鍵,可以唯一的標識記錄
foreign key (fk) 標識該欄位為該表的外來鍵
not null 標識該欄位不能為空
unique key (uk) 標識該欄位的下的記錄是唯一的值
auto_increment 標識該欄位的值自動增長(整數型別,而且為主鍵)
default 為該欄位設定預設值
unsigned 無符號
zerofill 使用0填充

說明:

1. 是否允許為空,預設null,可設定not null,欄位不允許為空,必須賦值
2. 欄位是否有預設值,預設值是null,如果插入記錄不給欄位賦值,此欄位使用預設值
create table t1(sex  not null default'male');

create table t2(age int unsigned not null defult 20) 必須為正值(無符號) 不允許為空 預設是20
3.是否是key
主鍵 primary key
外來鍵 foreign key
索引 (index,unique...)

二 not null與default

是否可空,null表示空,非字串
not null - 不可空
null - 可空

預設值,建立列時可以指定預設值,當插入資料時如果為主動設定,則自動新增預設值

=============not null==============
mysql> create table t1(id int); #此時id預設可以插入空
mysql> decs t1; #查看錶結構
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
mysql> insert t1 values(); #插入空成功
Query OK, 1 row affected (0.00 sec)


mysql> create table t2(id int not null); #設定欄位id不能為空
mysql> desc t2;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | NO   |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
mysql> insert t2 values(); #插入沒成功,顯示需要預設值
ERROR 1364 (HY000): Field 'id' doesn't have a default value

=============defualt==============
mysql> create table t3(id int default 1);
mysql> insert t3 values();
Query OK, 1 row affected (0.00 sec)

mysql> alter table t3 modify id int not null default 1;
mysql> insert t3 values();
Query OK, 1 row affected (0.00 sec)
#設定id欄位有預設值後,則無論id欄位是null還是not null,都可以插入空,插入空預設填入default指定的預設值

三 unique

==========設定唯一約束 unique==========

方法一(單列唯一):
create table t1(
id int,
name varchar(10) unique,
work varchar(10)
);

mysql> insert t1 values(1,'egon','aaaa');
Query OK, 1 row affected (0.00 sec)

mysql> insert t1 values(2,'egon','bbbb');
ERROR 1062 (23000): Duplicate entry 'egon' for key 'name'

#設定了單列唯一指在該欄位的記錄不能重複必須都唯一。

方法二(聯合唯一):

create table server(id int,
name varchar(10),
inip varchar(10),port int,
unique(ip,port),
unique(name)
);

mysql> insert server values(1,'egon','11.11.11',8080);
Query OK, 1 row affected (0.01 sec)

mysql> insert server values(1,'arther','11.11.11',8181);
Query OK, 1 row affected (0.00 sec)

mysql> insert server values(1,'arther','11.11.11',8181);
ERROR 1062 (23000): Duplicate entry '11.11.11-8181' for key 'ip'

#設定聯合的兩個欄位,其下新寫入的記錄如果是完全一樣則報錯,
最多有一個欄位下的記錄是重複的能成功寫入。


ps:
# not null 和unique的化學反應=>會被識別成表的主鍵
create table t4(id int,name varchar(10) not null unique);
create table t5(id int,name varchar(10) unique);

四 primary key

主鍵primary key
特點
1、主鍵的約束效果是not null+unique
2、innodb表有且只有一個主鍵,但是該主鍵可以聯合主鍵

瞭解:
create table t7(
id int,
name varchar(5),
primary key(id,name)
);

主鍵做為架構整個表的主要引數,一般預設使用id作為欄位表示,並且配上傳入空時則傳入預設值以及自動增值的方法。

五 auto_increment

約束欄位為自動增長,被約束的欄位必須同時被Key約束。

#不指定id,則自動增長
create table student(
id int primary key auto_increment,
name varchar(10),
sex enum('male','female') default 'male');
mysql> desc student
+-------+-----------------------+------+-----+---------+----------------+
| Field | Type                  | Null | Key | Default | Extra          |
+-------+-----------------------+------+-----+---------+----------------+
| id    | int(11)               | NO   | PRI | NULL    |auto_increment |      
| name  | varchar(10)           | YES  |     | NULL    |                |
| sex   | enum('male','female') | YES  |     | male    |                |
+-------+-----------------------+------+-----+---------+----------------+
mysql> insert student(name) values ('egon');
Query OK, 1 row affected (0.00 sec)
#直接傳入非預設的name,其他標題自動以預設值插入

#對於自增的欄位,在用delete刪除後,再插入值,該欄位仍按照刪除前的位置繼續增長
mysql> delete from student;
Query OK, 4 rows affected (0.00 sec)

mysql> select * from student;
Empty set (0.00 sec)

mysql> insert into student(name) values('ysb');
mysql> select * from student;
+----+------+------+
| id | name | sex  |
+----+------+------+
|  8 | ysb  | male |
+----+------+------+

#應該用truncate清空表,比起delete一條一條地刪除記錄,truncate是直接清空表,在刪除大表時用它





六 foreign key

1. 快速理解foreign key

員工資訊表有三個欄位:工號 姓名 部門

公司有3個部門,但是有1個億的員工,那意味著部門這個欄位需要重複儲存,部門名字越長,越浪費

解決方法:

我們完全可以定義一個部門表

然後讓員工資訊表關聯該表,如何關聯,即foreign key

#表型別必須是innodb儲存的(由於我在配置檔案已經指定所以不必重複寫)
create table dep(
id int primary key auto_increment,
name varchar(20) not null);

#由於部門是被關聯,所以需要先建立,等著員工去關聯

#d_id外來鍵,關聯父表(dep主鍵id),同步更新,同步刪除
create table emp(
id int primary key auto_increment,
name varchar(20) not null,
dep_id int,
foreign key(dep_id) references dep(id) on delete cascade on update cascade);

#先往父表dep中插入記錄
mysql>insert dep(name) values('sell'),('tech');

#再往子表emp中插入記錄
mysql> insert emp values
    -> (1,'egon',1),
    -> (2,'alex1',2),
    -> (3,'alex2',2),
    -> (4,'alex3',2);
    
#刪除父表dep,子表同步更新
mysql> delete from dep where id=1;
mysql> select * from emp;
+----+-------+--------+
| id | name  | dep_id |
+----+-------+--------+
|  2 | alex1 |      2 |
|  3 | alex2 |      2 |
|  4 | alex3 |      2 |
+----+-------+--------+

#更新父表dep,子表中的內容也跟著改
mysql> update dep set id=222 where id=2;
mysql> select * from emp;
+----+-------+--------+
| id | name  | dep_id |
+----+-------+--------+
|  2 | alex1 |    222 |
|  3 | alex2 |    222 |
|  4 | alex3 |    222 |
+----+-------+--------+

2.如何找出兩張表之間的關係

分析步驟:
1.先站在左表的角度去找
是否左表的多條記錄可以對應右表的一條記錄,如果是,則證明左表的一個欄位foreign key 右表一個欄位(通常是id),由此建立左表與右表的關聯。

2.再站在右表的角度去找
是否右表的多條記錄可以對應左表的一條記錄如果是,則證明右表的一個欄位foreign key 左表一個欄位(通常是id),由此建立右表與左表的關聯。

3.總結
#多對一:
如果只有步驟1成立,則是左表多對一右表
如果只有步驟2成立,則是右表多對一左表

#多對多
如果步驟1與步驟2同時成立,則證明這兩張表互相多對一,即多對多,需要定義一個第三張表專門放這兩張表的關聯關係。

#一對一
如果1和2都不成立,而是左表的一條記錄唯一對應右表的一條記錄,反之亦然。這種情況很簡單,就是在左表foreign key右表的基礎上,將左表的外來鍵欄位設定成unique即可。


3.建立表之間的關係

#一對多
兩張表:出版社, 書
一對多:一個出版社可以出很多書
關聯方式:foreign key+一張新的表

#先建立被關聯者
create table press(
id int primary key auto_increment,
name varchar(20));

#再建立主動關聯者
create table book(
id int primary key auto_increment,
name varchar(20),
pid int not null,
foreign key(pid) references press(id) 
on delete cascade 
on update cascade);

insert into press(name) values
('beijing press'),
('people press'),
('wuhan press');

insert into book(name,pid) values
('best life',1),
('dream true',2),
('dog die',2),
('snow white',3),
('destory life',3);

mysql> select * from book;
+----+--------------+-----+
| id | name         | pid |
+----+--------------+-----+
|  1 | best life    |   1 |
|  2 | dream true   |   2 |
|  3 | dog die      |   2 |
|  4 | snow white   |   3 |
|  5 | destory life |   3 |
+----+--------------+-----+

#嚴格意義上在欄位name應該設定一個唯一約束unique,保證不能重複建立書本名確保一對多的可讀性,不然將會出現如下的多對多的情況,造成閱讀的混亂。
mysql> insert book values(6,'dog die',1);
mysql> select * from book;
+----+--------------+-----+
| id | name         | pid |
+----+--------------+-----+
|  1 | best life    |   1 |
|  2 | dream true   |   2 |
|  3 | dog die      |   2 |
|  4 | snow white   |   3 |
|  5 | destory life |   3 |
|  6 | dog die      |   1 |
+----+--------------+-----+

#多對多
兩張表:作者,書
多對多:一個作者可以寫多本書,一本書也可以有多個作者,雙向的一對多
關聯方式:foreign key + 一張新的表

create table author(
id int primary key auto_increment,
name varchar(20));

create table book(
id int primary key auto_increment,
name varchar(20));

#最後建立新表去主動關聯

create table author2book(
id int primary key auto_increment,
aid int not null,
bid int not null,
foreign key(aid) references author(id) 
on delete cascade 
on update cascade,
foreign key(bid) references book(id) 
on delete cascade 
on update cascade,
evaluate varchar(20));

#可以在新表建立兩者關聯的東西,如對這本書以及作者的評價

insert into book(name) values
('best life'),
('dream true'),
('dog die'),
('snow white'),
('destory life');

insert into author(name) values
('arther'),
('egon'),
('tank');

#建立通過ID作者與書的關係
1.arther:
	1.('best life'),
	2.('dream true'),
	
2.('egon'):
	3.('dog die'),
	4.('snow white'),
	5.('destory life');

3.('tank'):
	2.('dream true'),
	3.('dog die'),
	4.('snow white'),
	
insert into author2book(aid,bid,evaluate) values
(1,1,'good'),
(1,2,'perfect'),
(2,3,'bad'),
(2,4,'not bad'),
(2,5,'so so'),
(3,2,'good'),
(3,3,'bad'),
(3,4,'good');

mysql> select * from author2book;
+----+-----+-----+----------+
| id | aid | bid | evaluate |
+----+-----+-----+----------+
|  1 |   1 |   1 | good     |
|  2 |   1 |   2 | perfect  |
|  3 |   2 |   3 | bad      |
|  4 |   2 |   4 | not bad  |
|  5 |   2 |   5 | so so    |
|  6 |   3 |   2 | good     |
|  7 |   3 |   3 | bad      |
|  8 |   3 |   4 | good     |
+----+-----+-----+----------+


#一對一
兩張表:顧客表和會員表
一對一:一個顧客是一個客戶,一個客戶有可能成為會員,即一對一的關係。
因身份的轉換,所用的表也不同。
關聯方式:foreign key+unique

#現有顧客再有會員,所以先建立顧客,然後由會員去關聯顧客
create table customer(
id int primary key auto_increment,
name varchar(20));

create  table member(
id int primary key auto_increment,
name varchar(20),
cid int unique,
foreign key(cid) references customer(id) 
on delete cascade 
on update cascade); 
#設定了unique代表此欄位下的記錄唯一,就不會出現一對多的情況

insert customer(name) values
('arther'),
('egon'),
('tank');

insert member(name,cid) values
('arther',1),
('egon',2),
('tank',3);

mysql> select * from member;
+----+--------+------+
| id | name   | cid  |
+----+--------+------+
|  1 | arther |    1 |
|  2 | egon   |    2 |
|  3 | tank   |    3 |
+----+--------+------+