MySQL約束條件及外來鍵的關係
阿新 • • 發佈:2021-07-28
MySQL約束條件及外來鍵的關係
約束條件
-
unsigned
設定無符號, 針對整形,這樣一設定比如說 tinyint本來是(-127--128),設定之後儲存範圍就變成了255 mysql> create table t1 (id int unsigned); Query OK, 0 rows affected (0.07 sec) mysql> desc t1; +-------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+-------+ | id | int unsigned | YES | | NULL | | +-------+--------------+------+-----+---------+-------+ 1 row in set (0.01 sec) mysql> insert into t1 values(-1); # 這裡不能插入負數 ERROR 1264 (22003): Out of range value for column 'id' at row 1 mysql> insert into t1 values(1); Query OK, 1 row affected (0.01 sec)
-
zerofill
用0來填充 mysql> create table t1 (id int(10) zerofill);# 注意這裡的10不是指儲存範圍或則長度, 整形的儲存範圍之和他的型別名有關係,10代表的是最大顯示寬度 Query OK, 0 rows affected, 2 warnings (0.04 sec) mysql> insert into t1 values (11); Query OK, 1 row affected (0.01 sec) mysql> select * from t1; +------------+ | id | +------------+ | 0000000011 | +------------+ 1 row in set (0.00 sec) mysql> desc t1; +-------+---------------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------------------------+------+-----+---------+-------+ | id | int(10) unsigned zerofill | YES | | NULL | | +-------+---------------------------+------+-----+---------+-------+ 1 row in set (0.00 sec) int(M) M指示最大顯示寬度。最大有效顯示寬度是255。顯示寬度與儲存大小或型別包含的值的範圍無關
-
not null
非空 mysql> create table t1 (id int, name varchar(16)); Query OK, 0 rows affected (0.04 sec) mysql> create table t2 (id int, name varchar(16) not null); Query OK, 0 rows affected (0.04 sec) mysql> insert into t1 values (1, 'egon'); Query OK, 1 row affected (0.01 sec) mysql> insert into t1(id) values (1); Query OK, 1 row affected (0.01 sec) mysql> insert into t1(id, name) values (1, ''); # 注意這裡的 '' 和 空是不一樣的 Query OK, 1 row affected (0.01 sec) mysql> select * from t1; +------+------+ | id | name | +------+------+ | 1 | egon | | 1 | NULL | | 1 | | +------+------+ 3 rows in set (0.00 sec) mysql> insert into t2(id, name) values(1, 'egon'); Query OK, 1 row affected (0.01 sec) mysql> insert into t2(id, name) values(1, ''); Query OK, 1 row affected (0.01 sec) mysql> insert into t2(id) values(1); # 報錯,因為給name這個欄位設定了非空 mysql> select * from t2; +------+------+ | id | name | +------+------+ | 1 | egon | | 1 | | +------+------+ 2 rows in set (0.00 sec) mysql> desc t1; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int | YES | | NULL | | | name | varchar(16) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.00 sec) mysql> desc t2; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int | YES | | NULL | | | name | varchar(16) | NO | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.00 sec) # 注意這裡的 '' 和 空是不一樣的
-
default
設定預設值 mysql> create table t1 (id int, name varchar(32) default 'egon'); Query OK, 0 rows affected (0.04 sec) mysql> desc t1; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int | YES | | NULL | | | name | varchar(32) | YES | | egon | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.00 sec) 預設值可傳可不傳
-
unique
唯一: 單列唯一: mysql> create table t1 (id int, name varchar(32) unique); Query OK, 0 rows affected (0.06 sec) mysql> desc t1; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int | YES | | NULL | | | name | varchar(32) | YES | UNI | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.00 sec) mysql> insert into t1 values(1, 'qwe'); Query OK, 1 row affected (0.01 sec) mysql> insert into t1 values(1, 'qwe'); # qwe上面已經傳過一次了; ERROR 1062 (23000): Duplicate entry 'qwe' for key 't1.name' mysql> 多列唯一: mysql> create table t1 (id int, host varchar(16), port int, unique(host, port)); # 這個就是host和port加起來唯一,單個可以重複 Query OK, 0 rows affected (0.07 sec) mysql> insert into t1 values (1, '127.0.0.1', 3306); Query OK, 1 row affected (0.01 sec) mysql> insert into t1 values (1, '127.0.0.1', 3306); ERROR 1062 (23000): Duplicate entry '127.0.0.1-3306' for key 't1.host' mysql> insert into t1 values (1, '127.0.0.2', 3306); Query OK, 1 row affected (0.01 sec) mysql> insert into t1 values (1, '127.0.0.2', 3302); Query OK, 1 row affected (0.00 sec)
-
primary key
# 1. 從限制角度來說, 主鍵相當於非空且唯一 id int primary key <==> id int not null unique # 2. InnoDB儲存引擎規定表中必須要有一個主鍵 在之前建立的表中,主鍵給我們隱藏了,隱藏意味著看不到,也不能用 # 主鍵的功能 查詢速度快, 主鍵本身也是一種索引
-
auto_increment
每次自增1 create table t1 (id int primary key auto_increment) # id欄位 建立的標準語法
-
foreign key
這個是外來鍵關係
清空表資料
# 第一種:
delete from t1; # 刪除了,下次插入資料,主鍵不是從1開始
# 第二種
truncate table t1; # 推薦
binlog 恢復資料用的,,我們寫的sql語句和資料都在這個裡面
外來鍵關係的判斷
表呢有三種關係:
一對一
一對多
多對多
###############一對一##################
eg:
作者表和作者詳情表
一個作者對應一個作者詳情
一個作者詳情對應一個作者
# 這樣的關係就是一對一, 建立外來鍵的時候,推薦建立在查詢頻率高的一方
###############一對多##################
eg:
書籍表和出版社表
一個書籍只能有一個出版社
一個出版社可以有多個書籍
# 這樣的關係就是一對多,外來鍵建立在多的一方
###############多對多##################
eg:
作者表和書籍表
一個作者可以寫多本書
一本書可以有多個作者
# 這樣的關係就是多對多, 這個建立一張第三方的關係表
程式碼實現上述需求
###############一對一##################
create table author (
id int primary key auto_increment,
name varchar(16),
author_detail_id int unique,
foreign key (author_detail_id) references author_detail(id)
on update cascade # 級聯更新
on delete cascade # 級聯刪除
)
create table author_detail(
id int primary key auto_increment,
phone bigint,
email varchar(16),
gender enum('male', 'female') default 'male'
)
###############一對多##################
create table book(
id int primary key auto_increment,
title varchar(16),
price decimal,
publish_id int,
foreign key (publish_id) references publish(id)
on update cascade
on delete cascade
)
create table publish(
id int primary key auto_increment,
name varchar(16),
addr varchar(16)
)
###############對多對##################
create table author(
id int primary key auto_increment,
name varchar(16)
)
create table book(
id int primary key auto_increment,
title varchar(16),
price decimal
)
create table author_book(
id int primary key auto_increment,
book_id int,
author_id int,
foreign key (book_id) references author(id)
on update cascade
on delete cascade,
foreign key (author_id) references book(id)
on update cascade
on delete cascade
)
聚合函式
max 最大值
min 最小值
sun 求和
count 計數
avg 平均值
模糊查詢--like
like
關鍵符合:
%: 匹配任意個數的任意字元
_: 匹配單個個數的任意字元
# 注意: 模糊查詢第一個%不走索引,如果想要走索引就把資料同步到esc(elasticsearch)中
查詢前期準備資料
create table emp(
id int primary key auto_increment,
name varchar(20) not null,
sex enum('male','female') not null default 'male', #大部分是男的
age int(3) unsigned not null default 28,
hire_date date not null,
post varchar(50),
post_comment varchar(100),
salary double(15,2),
office int, #一個部門一個屋子
depart_id int
);
#插入記錄
#三個部門:教學,銷售,運營
insert into emp(name,sex,age,hire_date,post,salary,office,depart_id) values
('tom','male',78,'20150302','teacher',1000000.31,401,1),
('kevin','male',81,'20130305','teacher',8300,401,1),
('tony','male',73,'20140701','teacher',3500,401,1),
('owen','male',28,'20121101','teacher',2100,401,1),
('jack','female',18,'20110211','teacher',9000,401,1),
('jenny','male',18,'19000301','teacher',30000,401,1),
('sank','male',48,'20101111','teacher',10000,401,1),
('哈哈','female',48,'20150311','sale',3000.13,402,2),#以下是銷售部門
('呵呵','female',38,'20101101','sale',2000.35,402,2),
('西西','female',18,'20110312','sale',1000.37,402,2),
('樂樂','female',18,'20160513','sale',3000.29,402,2),
('拉拉','female',28,'20170127','sale',4000.33,402,2),
('僧龍','male',28,'20160311','operation',10000.13,403,3), #以下是運營部門
('程咬金','male',18,'19970312','operation',20000,403,3),
('程咬銀','female',18,'20130311','operation',19000,403,3),
('程咬銅','male',18,'20150411','operation',18000,403,3),
('程咬鐵','female',18,'20140512','operation',17000,403,3);
查詢關鍵字之where
# 1. 查詢id大於等於3小於等於6的資料
select * from emp where id >=3 and id <= 6;
select * from emp where id between 3 and 6;
"""
between and 在什麼之間
"""
# 2.查詢薪資是20000或者18000或者17000的資料
select * from emp where salary =20000 or salary =18000 or salary = 17000;
select * from emp where salary in (20000, 17000, 18000);
"""
in 後面跟一個集合 在這個集合裡面
"""
# 3. 查詢姓名中帶有字母o的員工姓名和薪資
select name, salary from emp where name like '%o%';\
# 4. 查詢姓名由四個字元組成的員工姓名和薪資
select * from emp where name like '____';
select * from emp where char_length(name) = 4;
"""
char_length() # 計算長度
"""
# 5.查詢id小於3或者大於6的資料
select * from emp where id < 3 or id > 6;
select * from emp where not id between 3 and 6;
"""
not 取反
"""
# 6.查詢薪資不在20000,18000,17000範圍的資料
select * from emp where salary not in (20000, 18000, 17000);
"""
not in 不走索引
"""
# 7.查詢崗位描述為空的員工名與崗位名 針對null不能用等號,只能用is
select name, post from emp where post_comment is null;
"""
針對null不能用等號,只能用is
"""
查詢關鍵字之group by 分組
分組:
將單個單個的個體按照指定的條件分成一個整體
分組之後預設只能直接取到分組的依據, 其他欄位無法直接獲取(可以間接獲取)
# 嚴格模式
set global sql_mode='STRICT_TRANS_TABLES,PAD_CHAR_TO_FULL_LENGTH,only_full_group_by'
# 1. 每個部門的最高薪資
select post, max(salary) from emp group by post;
# 2.每個部門的最低薪資
select post, min(salary) from emp group by post;
# 3. 每個部門的平均薪資
select post, avg(salary) from emp group by post;
# 4.每個部門的人數
select post, count(salary) from emp group by post;
# 5.每個部門的月工資總和
select post, sum(salary) from emp group by post;
# as 可以給欄位起別名
select post, sum(salary) as sum_salary from emp group by post;
# 6. 查詢分組之後的部門名稱和每個部門下所有的員工姓名
"""
group_concat() 獲取分組以外的欄位資料 並且支援拼接操作
concat() 未分組之前使用的拼接功能
concat_ws()
"""
mysql> select group_concat(name, ':', salary) from emp group by post;
+--------------------------------------------------------------------------------------------------+
| group_concat(name, ':', salary) |
+--------------------------------------------------------------------------------------------------+
| 僧龍:10000.13,程咬金:20000.00,程咬銀:19000.00,程咬銅:18000.00,程咬鐵:17000.00 |
| 哈哈:3000.13,呵呵:2000.35,西西:1000.37,樂樂:3000.29,拉拉:4000.33 |
| tom:1000000.31,kevin:8300.00,tony:3500.00,owen:2100.00,jack:9000.00,jenny:30000.00,sank:10000.00 |
+--------------------------------------------------------------------------------------------------+
3 rows in set (0.00 sec)
mysql> select concat(name, ':', salary) from emp where id <3;;
+---------------------------+
| concat(name, ':', salary) |
+---------------------------+
| tom:1000000.31 |
| kevin:8300.00 |
+---------------------------+
2 rows in set (0.00 sec)
ERROR:
No query specified
mysql> select concat_ws(':', name, salary, post) from emp;
+------------------------------------+
| concat_ws(':', name, salary, post) |
+------------------------------------+
| tom:1000000.31:teacher |
| kevin:8300.00:teacher |
| tony:3500.00:teacher |
| owen:2100.00:teacher |
| jack:9000.00:teacher |
| jenny:30000.00:teacher |
| sank:10000.00:teacher |
| 哈哈:3000.13:sale |
| 呵呵:2000.35:sale |
| 西西:1000.37:sale |
| 樂樂:3000.29:sale |
| 拉拉:4000.33:sale |
| 僧龍:10000.13:operation |
| 程咬金:20000.00:operation |
| 程咬銀:19000.00:operation |
| 程咬銅:18000.00:operation |
| 程咬鐵:17000.00:operation |
+------------------------------------+
17 rows in set (0.00 sec)