1. 程式人生 > 其它 >MySQL約束條件及外來鍵的關係

MySQL約束條件及外來鍵的關係

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)