mysql 增刪改查


sql語句規范

sql是Structured Query Language(結構化查詢語言)的縮寫。SQL是專為數據庫而建立的操作命令集,是一種功能齊全的數據庫語言。

在使用它時,只需要發出“做什么”的命令,“怎么做”是不用使用者考慮的。SQL功能強大、簡單易學、使用方便,已經成為了數據庫操作的基礎,並且現在幾乎所有的數據庫均支持sql。

<1> 在數據庫系統中,SQL語句不區分大小寫(建議用大寫) 。但字符串常量區分大小寫。建議命令大寫,表名庫名小寫;

<2> SQL語句可單行或多行書寫,以“;”結尾。關鍵詞不能跨多行或簡寫。

<3> 用空格和縮進來提高語句的可讀性。子句通常位於獨立行,便於編輯,提高可讀性。

1
2
SELECT  FROM  tb_table
             WHERE  NAME = "YUAN" ;

<4> 注釋:單行注釋:--

               多行注釋:/*......*/

<5>sql語句可以折行操作

 

數據類型

數值類型

    

  作用:存儲年齡,等級,id,手機號,身高,薪水等數字

無符號類型

=========有符號和無符號tinyint==========
#tinyint默認為有符號
MariaDB [db1]> create table t1(x tinyint); #默認為有符號,即數字前有正負號
MariaDB [db1]> desc t1;
MariaDB [db1]> insert into t1 values
    -> (-129),
    -> (-128),
    -> (127),
    -> (128);
MariaDB [db1]> select * from t1;
+------+
| x    |
+------+
| -128 | #-129存成了-128
| -128 | #有符號,最小值為-128
|  127 | #有符號,最大值127
|  127 | #128存成了127
+------+



#設置無符號tinyint
MariaDB [db1]> create table t2(x tinyint unsigned);
MariaDB [db1]> insert into t2 values
    -> (-1),
    -> (0),
    -> (255),
    -> (256);
MariaDB [db1]> select * from t2;
+------+
| x    |
+------+
|    0 | -1存成了0
|    0 | #無符號,最小值為0
|  255 | #無符號,最大值為255
|  255 | #256存成了255
+------+
符號和無符號tinyint

 

顯示長度和存儲字節

mysql> create table test(id int);
Query OK, 0 rows affected (0.01 sec)

mysql> desc test;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
int(11)是默認的顯示寬度,因為int是用4個字節存儲,所以能存儲的最大數就是4294967295,是一個十位數字,對於無符號類型,所以默認顯示寬度就是11;
同理:tinyint的默認顯示寬度是4位。

decimal類型

float:浮點型,含字節數為4,32bit,        數值范圍為-3.4E38~3.4E38(7個有效位)

double:雙精度實型,含字節數為8,64bit     數值范圍-1.7E308~1.7E308(15個有效位)

decimal:數字型,128                    數值范圍 ±1.0 × E28 to ±7.9 × E28(28個有效位)

decimal的精度比double大,所能儲存的最大數卻比double要小 。decimal是存在精度損失的,只不過較小而已!

BIT

  BIT(M)可以用來存放多位二進制數,M范圍從1~64,如果不寫默認為1位。
  注意:對於位字段需要使用函數讀取
      bin()顯示為二進制
      hex()顯示為十六進制

mysql> create table t(id bit);
Query OK, 0 rows affected (0.03 sec)

mysql> desc t;
+-------+--------+------+-----+---------+-------+
| Field | Type   | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| id    | bit(1) | YES  |     | NULL    |       |
+-------+--------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> insert t values (1);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t;
+------+
| id   |
+------+
|      |
+------+
1 row in set (0.00 sec)

mysql> select bin(id) from t;
+---------+
| bin(id) |
+---------+
| 1       |
+---------+
1 row in set (0.00 sec)
mysql> alter table t modify id bit(5);
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into t values(8);
Query OK, 1 row affected (0.00 sec)

mysql> select bin(id),hex(id) from t;
+---------+---------+
| bin(id) | hex(id) |
+---------+---------+
| 1       | 1       |
| 1000    | 8       |
+---------+---------+
2 rows in set (0.00 sec)

字符串類型

存儲字符串:

CHAR系列 :CHAR VARCHAR
TEXT系列 : TINYTEXT TEXT MEDIUMTEXT LONGTEXT

存儲二進制數據:

BINARY系列: BINARY VARBINARY
BLOB 系列 :  TINYBLOB BLOB MEDIUMBLOB LONGBLOB 

解析:

 char (m)
   
      CHAR列的長度固定為創建表時聲明的長度: 0 ~ 255。其中m代表字符串的長度。
      PS: 即使數據小於m長度,也會占用m長度
  varchar(m)
      VARCHAR列中的值為可變長字符串,長度: 0 ~ 65535。其中m代表該數據類型所允許保存的字符串
      的最大長度,只要長度小於該最大值的字符串都可以被保存在該數據類型中。

      注:雖然varchar使用起來較為靈活,但是從整個系統的性能角度來說,char數據類型的處理速度
      更快,有時甚至可以超出varchar處理速度的50%。因此,用戶在設計數據庫時應當綜合考慮各方面的因素,以求達到最佳的平衡

  text
      text數據類型用於保存變長的大字符串,可以組多到65535 (2**16 − 1)個字符。

  mediumtext
      A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.

  longtext
      A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) 
      characters.
char text

注意:

在查詢的時候,CHAR列刪除了尾部的空格,而VARCHAR則保留這些空格。
mysql> create table t1(x char(5),y varchar(5));
mysql> insert into t1 values('你瞅啥  ','瞅你妹                 ');
mysql> select x,length(x),y,length(y) from t1;
+--------+-----------+----------+-----------+
| x      | length(x) | y        | length(y) |
+--------+-----------+----------+-----------+
| 你瞅啥 |         9 | 瞅你妹   |        11 |
+--------+-----------+----------+-----------+

日期類型

表示時間值的日期和時間類型為DATETIME、DATE、TIMESTAMP、TIME和YEAR。

每個時間類型有一個有效值范圍和一個"零"值,當指定不合法的MySQL不能表示的值時使用"零"值。

作用:存儲用戶注冊時間,文章發布時間,員工入職時間,出生時間,過期時間等

year

===========year===================

create table t_year(born_year year); insert into t_year values (1901), (2155); select * from t_year; +-----------+ | born_year | +-----------+ | 1901 | | 2155 | +-----------+ 2 rows in set (0.00 sec)

date time datetime

mysql> select now();
+---------------------+
| now()                                |
+---------------------+
| 2017-08-01 19:38:54          |
+---------------------+
1 row in set (0.00 sec)

 
         
============date,time,datetime===========

create table t_mul(d date,t time,dt datetime);
insert into c07(1901,"1901-08-07", "2017-08-01 19:42:22"); # 注意:date和datetime類型插入數據時需要加引號,year 類型不用 insert into t_mul values(now(),now(),now()); select * from t_mul; mysql> select * from t_mul; +------------+----------+---------------------+ | d | t | dt | +------------+----------+---------------------+ | 2017-08-01 | 19:42:22 | 2017-08-01 19:42:22 | +------------+----------+---------------------+ 1 row in set (0.00 sec)

timestamp

create table t_stamp(t TIMESTAMP);

insert into t_stamp values();
insert into t_stamp values(NULL );

select * from t_stamp;

+---------------------+
| t                   |
+---------------------+
| 2017-08-01 19:46:24 |
| 2017-08-01 19:46:24 |
+---------------------+
2 rows in set (0.00 sec)
 
 在實際應用的很多場景中,MySQL的這兩種日期類型都能夠滿足我們的需要,存儲精度都為秒,
    但在某些情況下,會展現出他們各自的優劣。下面就來總結一下兩種日期類型的區別。

1.DATETIME的日期范圍是1001——9999年,TIMESTAMP的時間范圍是1970——2038年。

2.DATETIME存儲時間與時區無關,TIMESTAMP存儲時間與時區有關,顯示的值也依賴於時區。
  在mysql服務器,操作系統以及客戶端連接都有時區的設置。

3.DATETIME使用8字節的存儲空間,TIMESTAMP的存儲空間為4字節。因此,TIMESTAMP比DATETIME的
  空間利用率更高。

4.DATETIME的默認值為null;TIMESTAMP的字段默認不為空(not null),默認值為當前時間
 (CURRENT_TIMESTAMP),如果不做特殊處理,並且update語句中沒有指定該列的更新值,則默
  認更新為當前時間。
datetime timestamp

 

枚舉類型與集合類型

字段的值只能在給定范圍中選擇,如單選框,多選框
enum 單選 只能在給定的范圍內選一個值,如性別 sex 男male/女female
set 多選 在給定的范圍內可以選擇一個或一個以上的值(愛好1,愛好2,愛好3...)

解析:

枚舉類型(enum)
An ENUM column can have a maximum of 65,535 distinct elements. 
(The practical limit is less than 3000.)
示例:
    CREATE TABLE shirts (
        name VARCHAR(40),
        size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
    );
    INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), 
                                            ('t-shirt','medium'),
                                            ('polo shirt','small');

集合類型(set)
A SET column can have a maximum of 64 distinct members.
示例:
    CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));
    INSERT INTO myset (col) VALUES  ('a,d'),
                                    ('d,a'), 
                                    ('a,d,a'), 
                                    ('a,d,d'),
                                    ('d,a,d');
                                    
View Code

 


數據庫操作
 
-- 1.創建數據庫(在磁盤上創建一個對應的文件夾)
    create database [if not exists] db_name [character set xxx] 
    
-- 2.查看數據庫
    show databases;查看所有數據庫
    show create database db_name; 查看數據庫的創建方式

-- 3.修改數據庫
    alter database db_name [character set xxx] 

-- 4.刪除數據庫
    drop database [if exists] db_name;
    
-- 5.使用數據庫
    切換數據庫 use db_name; -- 注意:進入到某個數據庫后沒辦法再退回之前狀態,但可以通過use進行切換
    查看當前使用的數據庫 select database();
 
 

數據表操作

創建表

 
-- 語法
CREATE TABLE tab_name(
            field1 type[完整性約束條件],
            field2 type,
            ...
            fieldn type
        )[character set xxx];
復制代碼

示例:

 CREATE TABLE employee(
            id int primary key auto_increment ,
            name varchar(20),
            gender bit default 1,
            birthday date,
            department varchar(20),
            salary double(8,2) unsigned,
            resume text
          );

查看表信息

    desc tab_name              查看表結構
    show columns from tab_name      查看表結構
    show tables             查看當前數據庫中的所有的表
    show create table tab_name      查看當前數據庫表建表語句 

修改表結構

復制代碼
   -- (1)增加列(字段)
      alter table tab_name add [column] 列名 類型[完整性約束條件][first|after 字段名];
      
      #添加多個字段
      alter table users2 
            add addr varchar(20),
            add age  int first,
            add birth varchar(20) after name;

   -- (2)修改一列類型
      alter table tab_name modify 列名 類型 [完整性約束條件][first|after 字段名];
      -- (3)修改列名
      alter table tab_name change [column] 列名 新列名 類型 [完整性約束條件][first|after 字段名];
     -- (4)刪除一列
      alter table tab_name drop [column] 列名;-- (5)修改表名
      rename table 表名 to 新表名;

   -- (6)修該表所用的字符集    
      alter table student character set utf8;
復制代碼

刪除表

drop table tab_name;
 

表記錄操作

增加表記錄

/* 
<1>插入一條記錄:

  insert [into] tab_name (field1,filed2,.......) values (value1,value2,.......);
    

<2>插入多條記錄:
  insert [into] tab_name (field1,filed2,.......) values (value1,value2,.......),
                                        (value1,value2,.......), 
                             ...                               ;

<3>set插入:
  insert [into] tab_name set 字段名=值 

*/
 
 
INSERT employee (name,gender,birthday,salary,department) VALUES
                      ("grace",1,"1985-12-12",8000,"保潔部"),
                      ("egon",1,"1987-08-08",5000,"保安部"),
                      ("yuan",1,"1990-06-06",20000,"教學部");


INSERT employee VALUES (8,"女神",0,"1992-02-12","教學部",7000,"");

INSERT employee SET name="wusir",birthday="1990-11-11";

 

修改表記錄

1
update  tab_name  set  field1=value1,field2=value2,......[ where  語句]

 示例:

update employee_new set birthday="1989-10-24" WHERE id=1;

--- 將yuan的薪水在原有基礎上增加1000元。
update employee_new set salary=salary+4000 where name='yuan';

 

刪除表記錄

復制代碼
方式1:
delete from tab_name [where ....]

方式2:
truncate table emp_new;

            /*    
            如果不跟where語句則刪除整張表中的數據
            delete只能用來刪除一行記錄
            delete語句只能刪除表中的內容,不能刪除表本身,想要刪除表,用drop
            TRUNCATE TABLE也可以刪除表中的所有數據,詞語句首先摧毀表,再新建表。此種方式刪除的數據不能在
            事務中恢復。
            */

示例:

-- 刪除表中名稱為’alex’的記錄。
   delete from employee_new where name='grace';
-- 刪除表中所有記錄。
   delete from employee_new;

-- 注意auto_increment沒有被重置:alter table employee auto_increment=1;
查詢表記錄(select)
 
-- 查詢語法:

   SELECT *|field1,filed2 ...   FROM tab_name
                  WHERE 條件
                  GROUP BY field
                  HAVING 篩選
                  ORDER BY field
                  LIMIT 限制條數


-- Mysql在執行sql語句時的執行順序:
                -- from  where  group by  having select order by

准備表和數據

CREATE TABLE emp(
    id       INT PRIMARY KEY AUTO_INCREMENT,
    name     VARCHAR(20),
    gender   ENUM("male","female","other"),
    age      TINYINT,
    dep      VARCHAR(20),
    city     VARCHAR(20),
   salary    DOUBLE(7,2)
);


INSERT INTO emp (name,gender,age,dep,city,salary) VALUES
                ("yuan","male",24,"教學部","河北省",8000),
                ("egon","male",34,"保安部","山東省",8000),
                ("alex","male",28,"保潔部","山東省",10000),
                ("景麗陽","female",22,"教學部","北京",9000),
                ("張三", "male",24,"教學部","河北省",6000),
                ("李四", "male",32,"保安部","北京",12000),
                ("王五", "male",38,"教學部","河北省",7000),
                ("趙六", "male",19,"保安部","河北省",9000),
                ("豬七", "female",24,"保潔部","北京",9000);

SELECT  * FROM emp;
View Code
mysql> SELECT  * FROM emp;
+----+-----------+--------+------+-----------+-----------+----------+
| id | name      | gender | age  | dep       | city      | salary   |
+----+-----------+--------+------+-----------+-----------+----------+
|  1 | yuan      | male   |   24 | 教學部    | 河北省    |  8000.00 |
|  2 | egon      | male   |   34 | 保安部    | 山東省    |  8000.00 |
|  3 | grace      | male   |   28 | 保潔部    | 山東省    | 10000.00 |
|  4 | 景麗陽    | female |   22 | 教學部    | 北京      |  9000.00 |
|  5 | 張三      | male   |   24 | 教學部    | 河北省    |  6000.00 |
|  6 | 李四      | male   |   32 | 保安部    | 北京      | 12000.00 |
|  7 | 王五      | male   |   38 | 教學部    | 河北省    |  7000.00 |
|  8 | 趙六      | male   |   19 | 保安部    | 河北省    |  9000.00 |
|  9 | 豬七      | female |   24 | 保潔部    | 北京      |  9000.00 |
+----+-----------+--------+------+-----------+-----------+----------+
9 rows in set (0.00 sec)

where子句: 過濾查詢

復制代碼
-- where字句中可以使用:

         -- 比較運算符:
                        > < >= <=  !=  <>
                        between 80 and 100 值在10到20之間
                        in(80,90,100) 值是80或90或100
                        like 'yuan%'
                        /*
                        pattern可以是%或者_,
                        如果是%則表示任意多字符,此例如唐僧,唐國強
                        如果是_則表示一個字符唐_,只有唐僧符合。兩個_則表示兩個字符:__
                        */

         -- 邏輯運算符
                        在多個條件直接可以使用邏輯運算符 and or not
復制代碼

示例:

-- 查詢年紀大於24的員工
SELECT * FROM emp WHERE age>24;

-- 查詢教學部的男老師信息
SELECT * FROM emp WHERE dep="教學部" AND gender="male";

order:排序

按指定的列進行,排序的列即可是表中的列名,也可以是select語句后指定的別名。

-- 語法:

select *|field1,field2... from tab_name order by field [Asc|Desc]

         -- Asc 升序、Desc 降序,其中asc為默認值 ORDER BY 子句應位於SELECT語句的結尾。

示例:

-- 按年齡從高到低進行排序
SELECT * FROM emp ORDER BY age DESC ;

-- 按工資從低到高進行排序
SELECT * FROM emp ORDER BY salary;

group by:分組查詢(*****)

GROUP BY 語句根據某個列對結果集進行分組。在分組的列上我們可以使用 COUNT, SUM, AVG等函數進行相關查詢。

-- 語法:
  SELECT column_name, function(column_name)
        FROM table_name
        WHERE column_name operator value
        GROUP BY column_name;

 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
-- 查詢男女員工各有多少人
 
SELECT  gender 性別, count (*) 人數  FROM  emp5  GROUP  BY  gender;
 
-- 查詢各個部門的人數
 
SELECT  dep 部門, count (*) 人數  FROM  emp5  GROUP  BY  dep;
 
-- 查詢每個部門最大的年齡
 
SELECT  dep 部門, max (age) 最大年紀  FROM  emp5  GROUP  BY  dep;
 
-- 查詢每個部門年齡最大的員工姓名
 
SELECT  FROM  emp5  WHERE  age  in  ( SELECT  max (age)  FROM  emp5  GROUP  BY  dep);
 
-- 查詢每個部門的平均工資
 
SELECT  dep 部門, avg (salary) 最大年紀  FROM  emp  GROUP  BY  dep;
 
--  查詢教學部的員工最高工資:
 
SELECT  dep, max (salary)  FROM  emp11  GROUP  BY  dep  HAVING  dep= "教學部" ;
 
-- 查詢平均薪水超過8000的部門
 
SELECT  dep, AVG (salary)  FROM   emp  GROUP  BY  dep  HAVING  avg (salary)>8000;
 
--  查詢每個組的員工姓名
SELECT  dep,group_concat( name FROM  emp  GROUP  BY  dep;
 
-- 查詢公司一共有多少員工(可以將所有記錄看成一個組)
 
SELECT  COUNT (*) 員工總人數  FROM  emp;
 
                   -- KEY: 查詢條件中的每個后的詞就是分組的字段

limit記錄條數限制

SELECT * from ExamResult limit 1;
SELECT * from ExamResult limit 2,5;        --  跳過前兩條顯示接下來的五條紀錄
SELECT * from ExamResult limit 2,2;

正則表達式

SELECT * FROM employee WHERE emp_name REGEXP '^yu';

SELECT * FROM employee WHERE emp_name REGEXP 'yun$';

SELECT * FROM employee WHERE emp_name REGEXP 'm{2}';
 

多表查詢

創建表

CREATE TABLE emp(
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20),
    salary DOUBLE(7,2),
    dep_id INT
);

INSERT INTO emp (name,salary,dep_id) VALUES ("張三",8000,2),
                                            ("李四",12000,1),
                                            ("王五",5000,2),
                                            ("趙六",8000,3),
                                            ("豬七",9000,1),
                                            ("周八",7000,4),
                                            ("蔡九",7000,2);

CREATE TABLE dep(
      id INT PRIMARY KEY AUTO_INCREMENT,
      name VARCHAR(20)
);


INSERT INTO dep (name) VALUES ("教學部"),
                              ("銷售部"),
                              ("人事部");
View Code
 
mysql> select * from emp;
+----+--------+----------+--------+
| id | name   | salary   | dep_id |
+----+--------+----------+--------+
|  1 | 張三   |  8000.00 |      2 |
|  2 | 李四   | 12000.00 |      1 |
|  3 | 王五   |  5000.00 |      2 |
|  4 | 趙六   |  8000.00 |      3 |
|  5 | 豬七   |  9000.00 |      1 |
|  6 | 周八   |  7000.00 |      4 |
|  7 | 蔡九   |  7000.00 |      2 |
+----+--------+----------+--------+
7 rows in set (0.00 sec)

mysql> select * from dep;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | 教學部    |
|  2 | 銷售部    |
|  3 | 人事部    |
+----+-----------+
3 rows in set (0.00 sec)

1.笛卡爾積查詢

1
select  from  emp,dep;
復制代碼
mysql> select * from emp,dep;
+----+--------+----------+--------+----+-----------+
| id | name   | salary   | dep_id | id | name      |
+----+--------+----------+--------+----+-----------+
|  1 | 張三   |  8000.00 |      2 |  1 | 教學部    |
|  1 | 張三   |  8000.00 |      2 |  2 | 銷售部    |
|  1 | 張三   |  8000.00 |      2 |  3 | 人事部    |
|  2 | 李四   | 12000.00 |      1 |  1 | 教學部    |
|  2 | 李四   | 12000.00 |      1 |  2 | 銷售部    |
|  2 | 李四   | 12000.00 |      1 |  3 | 人事部    |
|  3 | 王五   |  5000.00 |      2 |  1 | 教學部    |
|  3 | 王五   |  5000.00 |      2 |  2 | 銷售部    |
|  3 | 王五   |  5000.00 |      2 |  3 | 人事部    |
|  4 | 趙六   |  8000.00 |      3 |  1 | 教學部    |
|  4 | 趙六   |  8000.00 |      3 |  2 | 銷售部    |
|  4 | 趙六   |  8000.00 |      3 |  3 | 人事部    |
|  5 | 豬七   |  9000.00 |      1 |  1 | 教學部    |
|  5 | 豬七   |  9000.00 |      1 |  2 | 銷售部    |
|  5 | 豬七   |  9000.00 |      1 |  3 | 人事部    |
|  6 | 周八   |  7000.00 |      4 |  1 | 教學部    |
|  6 | 周八   |  7000.00 |      4 |  2 | 銷售部    |
|  6 | 周八   |  7000.00 |      4 |  3 | 人事部    |
|  7 | 蔡九   |  7000.00 |      2 |  1 | 教學部    |
|  7 | 蔡九   |  7000.00 |      2 |  2 | 銷售部    |
|  7 | 蔡九   |  7000.00 |      2 |  3 | 人事部    |
+----+--------+----------+--------+----+-----------+
21 rows in set (0.00 sec)
復制代碼

2、內連接

查詢兩張表中都有的關聯數據,相當於利用條件從笛卡爾積結果中篩選出了正確的結果。

1
SELECT  FROM  emp,dep  WHERE  emp.dep_id=dep.id;

OR

1
SELECT  FROM  emp  INNER  JOIN  dep  ON  emp.dep_id=dep.id;

 查詢結果:

 
+----+--------+----------+--------+----+-----------+
| id | name   | salary   | dep_id | id | name      |
+----+--------+----------+--------+----+-----------+
|  1 | 張三   |  8000.00 |      2 |  2 | 銷售部     |
|  2 | 李四   | 12000.00 |      1 |  1 | 教學部     |
|  3 | 王五   |  5000.00 |      2 |  2 | 銷售部     |
|  4 | 趙六   |  8000.00 |      3 |  3 | 人事部     |
|  5 | 豬七   |  9000.00 |      1 |  1 | 教學部     |
|  7 | 蔡九   |  7000.00 |      2 |  2 | 銷售部     |
+----+--------+----------+--------+----+-----------+
6 rows in set (0.00 sec)

這時,我們就可以利用兩張表中所有的字段進行查詢了

示例:

 
-- 查詢李四所在的部門名稱

SELECT emp.name,dep.name FROM  emp INNER JOIN dep ON emp.dep_id=dep.id WHERE emp.name="李四";

-- 查詢銷售部所有員工姓名以及部門名稱

-- SELECT name FROM  emp WHERE dep_id in (SELECT id FROM dep WHERE name="銷售部");

SELECT emp.name,dep.name FROM  emp INNER JOIN dep ON emp.dep_id=dep.id WHERE dep.name="銷售部";
 

 3、外連接

1
2
3
--(1)左外連接:在內連接的基礎上增加左邊有右邊沒有的結果
 
  SELECT  FROM  emp  LEFT  JOIN  dep  ON  dep.id=emp.dep_id;
+----+--------+----------+--------+------+-----------+
| id | name   | salary   | dep_id | id   | name      |
+----+--------+----------+--------+------+-----------+
|  2 | 李四   | 12000.00 |      1 |    1 | 教學部    |
|  5 | 豬七   |  9000.00 |      1 |    1 | 教學部    |
|  1 | 張三   |  8000.00 |      2 |    2 | 銷售部    |
|  3 | 王五   |  5000.00 |      2 |    2 | 銷售部    |
|  7 | 蔡九   |  7000.00 |      2 |    2 | 銷售部    |
|  4 | 趙六   |  8000.00 |      3 |    3 | 人事部    |
|  6 | 周八   |  7000.00 |      4 | NULL | NULL      |
+----+--------+----------+--------+------+-----------+
7 rows in set (0.00 sec)
 
1
2
3
--(1)外右連接:在內連接的基礎上增加右邊有左邊沒有的結果
 
  SELECT  FROM  emp  RIGHT  JOIN  dep  ON  dep.id=emp.dep_id;
mysql> SELECT * FROM emp RIGHT JOIN dep ON dep.id=emp.dep_id;
+------+--------+----------+--------+----+-----------+
| id   | name   | salary   | dep_id | id | name      |
+------+--------+----------+--------+----+-----------+
|    1 | 張三   |  8000.00 |      2 |  2 | 銷售部    |
|    2 | 李四   | 12000.00 |      1 |  1 | 教學部    |
|    3 | 王五   |  5000.00 |      2 |  2 | 銷售部    |
|    4 | 趙六   |  8000.00 |      3 |  3 | 人事部    |
|    5 | 豬七   |  9000.00 |      1 |  1 | 教學部    |
|    7 | 蔡九   |  7000.00 |      2 |  2 | 銷售部    |
+------+--------+----------+--------+----+-----------+
6 rows in set (0.00 sec)
 
 

完整性約束

完整性約束是對字段進行限制,從而符合該字段達到我們期望的效果比如字段含有默認值,不能是NULL等 。直觀點說:如果插入的數據不滿足限制要求,數據庫管理系統就拒絕執行操作

唯一約束

唯一約束可以有多個但索引列的值必須唯一,索引列的值允許有空值。

如果能確定某個數據列將只包含彼此各不相同的值,在為這個數據列創建索引的時候就應該使用關鍵字UNIQUE。

CREATE TABLE t5(
  id   INT AUTO_INCREMENT,
  name VARCHAR(20) DEFAULT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY UK_t5_name (name)
);
-- 建表后添加約束:

alter table t5 add constraint UK_t5_name unique (name);

-- 如果不需要唯一約束,則可以這樣刪除

ALTER TABLE t5 DROP INDEX UK_t5_name;

添加約束和刪除約束

1
2
3
4
5
6
7
8
9
10
-- 創建唯一約束:
create  unique  index  UK_t5_name  on  t5 ( name );
 
-- 建表后添加約束:
 
alter  table  t5  add  constraint  UK_t5_name  unique  ( name );
 
-- 如果不需要唯一約束,則可以這樣刪除
 
ALTER  TABLE  t5  DROP  INDEX  UK_t5_name;

自增約束

MySQL 每張表只能有1個自動增長字段,這個自動增長字段通常作為主鍵,也可以用作非主鍵使用,但是請注意將自動增長字段當做非主鍵使用時必須必須為其添加唯一索引,否則系統將會報錯。

mysql> CREATE TABLE t4(
    ->   id INT NOT NULL,
    ->   name VARCHAR(20),
    ->   age INT AUTO_INCREMENT
    -> );

ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a ke

可以改為

mysql> CREATE TABLE t4(
    ->   id INT NOT NULL,
    ->   name VARCHAR(20),
    ->   age INT UNIQUE AUTO_INCREMENT
    -> );
Query OK, 0 rows affected (0.13 sec)

主鍵約束

主鍵是用於唯一標識一條記錄的約束,如同身份證。

主鍵有兩個約束:非空且唯一!

創建主鍵

-- 方式1

CREATE TABLE t1(
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(20)
);

-- 方式2

CREATE TABLE t2(
  id INT NOT NULL,
  name VARCHAR(20)
);

注意:

1、一張表中最多只能有一個主鍵

2、表中如果沒有設置主鍵,默認設置NOT NULL的字段為主鍵;此外,表中如果有多個NOT NULL的字段,則按順序將第一個設置NOT NULL的字段設為主鍵。

結論:主鍵一定是非空且唯一,但非空且唯一的字段不一定是主鍵。

3、主鍵類型不一定必須是整型

添加主鍵和刪除主鍵

1
2
-- 添加主鍵<br>alter table tab_name add primary key(字段名稱,...) <br>
-- 刪除主鍵<br>alter table users drop primary key;

 注意,如果主鍵是AUTO_INCREMENT,需要先取消AUTO_INCREMENT,因為AUTO_INCREMENT只能加在KEY上。

1
2
3
4
CREATE  TABLE  test(num  INT  PRIMARY  KEY  AUTO_INCREMENT);<br>
  -- 思考,如何刪除主鍵?
     ALTER  TABLE  test  modify  id  int ;    -- auto_increment沒了,但這樣寫主鍵依然存在,所以還要加上下面這句
     ALTER  TABLE  test  drop  primary  key ; -- 僅僅用這句也無法直接刪除主鍵

復合主鍵

所謂的復合主鍵 就是指你表的主鍵含有一個以上的字段。

如果一列不能唯一區分一個表里的記錄時,可以考慮多個列組合起來達到區分表記錄的唯一性,形式 

①創建時:

1
2
3
4
5
6
create  table  sc (
     studentid  int ,
     courseid  int ,
     score  int ,
primary  key  (studentno,courseid)
);        

②修改時:

1
alter  table  tb_name  add  primary  key  (字段1,字段2,字段3);

外鍵約束

外鍵語法

1
2
3
4
5
外鍵的定義語法:
[ CONSTRAINT  symbol]  FOREIGN  KEY  [id] (index_col_name, ...)
                     REFERENCES  tbl_name (index_col_name, ...)
     [ ON  DELETE  { RESTRICT  CASCADE  SET  NULL  NO  ACTION  SET  DEFAULT }]
     [ ON  UPDATE  { RESTRICT  CASCADE  SET  NULL  NO  ACTION  SET  DEFAULT }]

 該語法 可以在 CREATE TABLE 和 ALTER TABLE 時使用,如果不指定CONSTRAINT symbol,MYSQL會自動生成一個名字。

准備表和數據

-- 子表
CREATE TABLE emp(
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(20),
  dep_id INT
-- CONSTRAINT emp_fk_emp FOREIGN KEY (dep_id) REFERENCES dep(id) -- 注意外鍵字段的數據類型必須與關聯字段一致 ); -- 主表 CREATE TABLE dep( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20) ); INSERT emp (name,dep_id) VALUES ("grace",1), ("egon",2), ("alvi",2), ("莎莎",1), ("wusir",2), ("女神",2), ("冰冰",3), ("姍姍",3); INSERT dep (name) VALUES ("市場部"), ("教學部"), ("銷售部");

添加外鍵

現在,刪除市場部:

1
2
mysql>  DELETE  FROM  dep  WHERE  name = "市場部" ;
Query OK, 1 row affected (0.01 sec)

居然刪除成功了,不可思議,現在問題來了: alex和莎莎兩個人怎么辦?

所以,為了避免類似操作,我們需要給兩張表建立約束,這種約束稱為外鍵約束。外鍵的好處:可以使得兩張表關聯,保證數據的一致性和實現一些級聯操作

1
2
3
4
5
6
INSERT  dep (id, name VALUES  (1, "市場部" );   -- 思考為什么加這一句?
 
ALTER  TABLE  emp  ADD  CONSTRAINT  dep_fk_emp
                     FOREIGN  KEY  (dep_id)
                     REFERENCES   dep(id);
<br><br>mysql>  DELETE  FROM  dep  WHERE  name = "市場部" ;<br><br>ERROR 1451 (23000): Cannot  delete  or  update  a parent row: a  foreign  key  constraint  fail

INNODB支持的ON語句

外鍵約束對子表的含義: 如果在主表中(比如dep)找不到候選鍵,則不允許在子表(比如emp)上進行insert/update

外鍵約束對父表的含義: 在主表上進行update/delete以更新或刪除在子表中有一條或多條應匹配行的候選鍵時,父表的行為取決於:在定義子表的外鍵時指定的 -- on update/on delete子句

-- ------------------------innodb支持的四種方式---------------------------------

cascade方式 在父表上update/delete記錄時,同步update/delete掉子表的匹配記錄外鍵的級聯刪除:如果父表中的記錄被刪除,則子表中對應的記錄自動被刪除

     FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
                              ON DELETE CASCADE;


set null方式 在父表上update/delete記錄時,將子表上匹配記錄的列設為null ; 要注意子表的外鍵列不能為not null

     FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
                              ON DELETE SET NULL;


Restrict方式 :拒絕對父表進行刪除更新操作(了解)

No action方式 在mysql中同Restrict,如果子表中有匹配的記錄,則不允許對父表對應候選鍵 ;
進行update/delete操作(了解)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM