Mysql--重点1
知識(shí)預(yù)覽
- sql語句規(guī)范
- 數(shù)據(jù)類型
- 數(shù)據(jù)庫(kù)操作
- 數(shù)據(jù)表操作
- 表記錄操作
- 查詢表記錄(select)
- 多表查詢
- 完整性約束
sql語句規(guī)范
sql是Structured Query Language(結(jié)構(gòu)化查詢語言)的縮寫。SQL是專為數(shù)據(jù)庫(kù)而建立的操作命令集,是一種功能齊全的數(shù)據(jù)庫(kù)語言。
在使用它時(shí),只需要發(fā)出“做什么”的命令,“怎么做”是不用使用者考慮的。SQL功能強(qiáng)大、簡(jiǎn)單易學(xué)、使用方便,已經(jīng)成為了數(shù)據(jù)庫(kù)操作的基礎(chǔ),并且現(xiàn)在幾乎所有的數(shù)據(jù)庫(kù)均支持sql。
<1> 在數(shù)據(jù)庫(kù)系統(tǒng)中,SQL語句不區(qū)分大小寫(建議用大寫) 。但字符串常量區(qū)分大小寫。建議命令大寫,表名庫(kù)名小寫;
<2> SQL語句可單行或多行書寫,以“;”結(jié)尾。關(guān)鍵詞不能跨多行或簡(jiǎn)寫。
<3> 用空格和縮進(jìn)來提高語句的可讀性。子句通常位于獨(dú)立行,便于編輯,提高可讀性。
?| 1 2 | SELECT * FROM tb_table ????????????WHERE NAME="YUAN"; |
<4> 注釋:單行注釋:--
?????????????? 多行注釋:/*......*/
<5>sql語句可以折行操作
回到頂部數(shù)據(jù)類型
數(shù)值類型
???
作用:存儲(chǔ)年齡,等級(jí),id,手機(jī)號(hào),身高,薪水等數(shù)字
無符號(hào)類型
=========有符號(hào)和無符號(hào)tinyint========== #tinyint默認(rèn)為有符號(hào) MariaDB [db1]> create table t1(x tinyint); #默認(rèn)為有符號(hào),即數(shù)字前有正負(fù)號(hào) MariaDB [db1]> desc t1; MariaDB [db1]> insert into t1 values-> (-129),-> (-128),-> (127),-> (128); MariaDB [db1]> select * from t1; +------+ | x | +------+ | -128 | #-129存成了-128 | -128 | #有符號(hào),最小值為-128 | 127 | #有符號(hào),最大值127 | 127 | #128存成了127 +------+ #設(shè)置無符號(hào)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 | #無符號(hào),最小值為0 | 255 | #無符號(hào),最大值為255 | 255 | #256存成了255 +------+ View Code顯示長(zhǎng)度和存儲(chǔ)字節(jié)
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)是默認(rèn)的顯示寬度,因?yàn)閕nt是用4個(gè)字節(jié)存儲(chǔ),所以能存儲(chǔ)的最大數(shù)就是4294967295,是一個(gè)十位數(shù)字,對(duì)于無符號(hào)類型,所以默認(rèn)顯示寬度就是11;同理:tinyint的默認(rèn)顯示寬度是4位。
decimal類型
float:浮點(diǎn)型,含字節(jié)數(shù)為4,32bit, 數(shù)值范圍為-3.4E38~3.4E38(7個(gè)有效位)double:雙精度實(shí)型,含字節(jié)數(shù)為8,64bit 數(shù)值范圍-1.7E308~1.7E308(15個(gè)有效位)decimal:數(shù)字型,128 數(shù)值范圍 ±1.0 × E28 to ±7.9 × E28(28個(gè)有效位)decimal的精度比double大,所能儲(chǔ)存的最大數(shù)卻比double要小 。decimal是存在精度損失的,只不過較小而已!
BIT
BIT(M)可以用來存放多位二進(jìn)制數(shù),M范圍從1~64,如果不寫默認(rèn)為1位。
注意:對(duì)于位字段需要使用函數(shù)讀取
bin()顯示為二進(jìn)制
hex()顯示為十六進(jìn)制
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: 0mysql> 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)
字符串類型
存儲(chǔ)字符串:
CHAR系列 :CHAR VARCHAR
TEXT系列 : TINYTEXT TEXT MEDIUMTEXT LONGTEXT
存儲(chǔ)二進(jìn)制數(shù)據(jù):
BINARY系列: BINARY VARBINARY
BLOB 系列 :? TINYBLOB BLOB MEDIUMBLOB LONGBLOB?
解析:
/*char (m)CHAR列的長(zhǎng)度固定為創(chuàng)建表時(shí)聲明的長(zhǎng)度: 0 ~ 255。其中m代表字符串的長(zhǎng)度。PS: 即使數(shù)據(jù)小于m長(zhǎng)度,也會(huì)占用m長(zhǎng)度varchar(m)VARCHAR列中的值為可變長(zhǎng)字符串,長(zhǎng)度: 0 ~ 65535。其中m代表該數(shù)據(jù)類型所允許保存的字符串的最大長(zhǎng)度,只要長(zhǎng)度小于該最大值的字符串都可以被保存在該數(shù)據(jù)類型中。注:雖然varchar使用起來較為靈活,但是從整個(gè)系統(tǒng)的性能角度來說,char數(shù)據(jù)類型的處理速度更快,有時(shí)甚至可以超出varchar處理速度的50%。因此,用戶在設(shè)計(jì)數(shù)據(jù)庫(kù)時(shí)應(yīng)當(dāng)綜合考慮各方面的因素,以求達(dá)到最佳的平衡texttext數(shù)據(jù)類型用于保存變長(zhǎng)的大字符串,可以組多到65535 (2**16 ? 1)個(gè)字符。mediumtextA TEXT column with a maximum length of 16,777,215 (2**24 ? 1) characters.longtextA TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 ? 1) characters.*/ View Code注意:
在查詢的時(shí)候,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 | +--------+-----------+----------+-----------+日期類型
表示時(shí)間值的日期和時(shí)間類型為DATETIME、DATE、TIMESTAMP、TIME和YEAR。
每個(gè)時(shí)間類型有一個(gè)有效值范圍和一個(gè)"零"值,當(dāng)指定不合法的MySQL不能表示的值時(shí)使用"零"值。
作用:存儲(chǔ)用戶注冊(cè)時(shí)間,文章發(fā)布時(shí)間,員工入職時(shí)間,出生時(shí)間,過期時(shí)間等
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)
create table t_mul(d date,t time,dt datetime);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) /* 在實(shí)際應(yīng)用的很多場(chǎng)景中,MySQL的這兩種日期類型都能夠滿足我們的需要,存儲(chǔ)精度都為秒,但在某些情況下,會(huì)展現(xiàn)出他們各自的優(yōu)劣。下面就來總結(jié)一下兩種日期類型的區(qū)別。1.DATETIME的日期范圍是1001——9999年,TIMESTAMP的時(shí)間范圍是1970——2038年。2.DATETIME存儲(chǔ)時(shí)間與時(shí)區(qū)無關(guān),TIMESTAMP存儲(chǔ)時(shí)間與時(shí)區(qū)有關(guān),顯示的值也依賴于時(shí)區(qū)。在mysql服務(wù)器,操作系統(tǒng)以及客戶端連接都有時(shí)區(qū)的設(shè)置。3.DATETIME使用8字節(jié)的存儲(chǔ)空間,TIMESTAMP的存儲(chǔ)空間為4字節(jié)。因此,TIMESTAMP比DATETIME的空間利用率更高。4.DATETIME的默認(rèn)值為null;TIMESTAMP的字段默認(rèn)不為空(not null),默認(rèn)值為當(dāng)前時(shí)間(CURRENT_TIMESTAMP),如果不做特殊處理,并且update語句中沒有指定該列的更新值,則默認(rèn)更新為當(dāng)前時(shí)間。*/ datetime與timestamp枚舉類型與集合類型
字段的值只能在給定范圍中選擇,如單選框,多選框
enum 單選 只能在給定的范圍內(nèi)選一個(gè)值,如性別 sex 男male/女female
set 多選 在給定的范圍內(nèi)可以選擇一個(gè)或一個(gè)以上的值(愛好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 回到頂部數(shù)據(jù)庫(kù)操作
-- 1.創(chuàng)建數(shù)據(jù)庫(kù)(在磁盤上創(chuàng)建一個(gè)對(duì)應(yīng)的文件夾)create database [if not exists] db_name [character set xxx] -- 2.查看數(shù)據(jù)庫(kù) show databases;查看所有數(shù)據(jù)庫(kù)show create database db_name; 查看數(shù)據(jù)庫(kù)的創(chuàng)建方式-- 3.修改數(shù)據(jù)庫(kù)alter database db_name [character set xxx] -- 4.刪除數(shù)據(jù)庫(kù)drop database [if exists] db_name;-- 5.使用數(shù)據(jù)庫(kù)切換數(shù)據(jù)庫(kù) use db_name; -- 注意:進(jìn)入到某個(gè)數(shù)據(jù)庫(kù)后沒辦法再退回之前狀態(tài),但可以通過use進(jìn)行切換查看當(dāng)前使用的數(shù)據(jù)庫(kù) select database(); 回到頂部數(shù)據(jù)表操作
創(chuàng)建表
-- 語法
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); View Code查看表信息
desc tab_name 查看表結(jié)構(gòu)show columns from tab_name 查看表結(jié)構(gòu)show tables 查看當(dāng)前數(shù)據(jù)庫(kù)中的所有的表show create table tab_name 查看當(dāng)前數(shù)據(jù)庫(kù)表建表語句修改表結(jié)構(gòu)
-- (1)增加列(字段)alter table tab_name add [column] 列名 類型[完整性約束條件][first|after 字段名];#添加多個(gè)字段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("alex",1,"1985-12-12",8000,"保潔部"),("egon",1,"1987-08-08",5000,"保安部"),("yuan",1,"1990-06-06",20000,"教學(xué)部");INSERT employee VALUES (8,"女神",0,"1992-02-12","教學(xué)部",7000,"");INSERT employee SET name="wusir",birthday="1990-11-11"; View Code修改表記錄
?| 1 | update tab_name set field1=value1,field2=value2,......[where 語句] |
?示例:
update employee_new set birthday="1989-10-24" WHERE id=1;--- 將yuan的薪水在原有基礎(chǔ)上增加1000元。 update employee_new set salary=salary+4000 where name='yuan'; View Code刪除表記錄
方式1: delete from tab_name [where ....]方式2: truncate table emp_new;/* 如果不跟where語句則刪除整張表中的數(shù)據(jù)delete只能用來刪除一行記錄delete語句只能刪除表中的內(nèi)容,不能刪除表本身,想要?jiǎng)h除表,用dropTRUNCATE TABLE也可以刪除表中的所有數(shù)據(jù),詞語句首先摧毀表,再新建表。此種方式刪除的數(shù)據(jù)不能在事務(wù)中恢復(fù)。*/示例:
-- 刪除表中名稱為’alex’的記錄。delete from employee_new where name='alex'; -- 刪除表中所有記錄。delete from employee_new;-- 注意auto_increment沒有被重置:alter table employee auto_increment=1; View Code 回到頂部查詢表記錄(select)
-- 查詢語法:SELECT *|field1,filed2 ... FROM tab_nameWHERE 條件GROUP BY fieldHAVING 篩選ORDER BY fieldLIMIT 限制條數(shù)-- Mysql在執(zhí)行sql語句時(shí)的執(zhí)行順序:-- from where select group by having order by ?
準(zhǔn)備表和數(shù)據(jù)
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,"教學(xué)部","河北省",8000),("egon","male",34,"保安部","山東省",8000),("alex","male",28,"保潔部","山東省",10000),("景麗陽","female",22,"教學(xué)部","北京",9000),("張三", "male",24,"教學(xué)部","河北省",6000),("李四", "male",32,"保安部","北京",12000),("王五", "male",38,"教學(xué)部","河北省",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 | 教學(xué)部 | 河北省 | 8000.00 | | 2 | egon | male | 34 | 保安部 | 山東省 | 8000.00 | | 3 | alex | male | 28 | 保潔部 | 山東省 | 10000.00 | | 4 | 景麗陽 | female | 22 | 教學(xué)部 | 北京 | 9000.00 | | 5 | 張三 | male | 24 | 教學(xué)部 | 河北省 | 6000.00 | | 6 | 李四 | male | 32 | 保安部 | 北京 | 12000.00 | | 7 | 王五 | male | 38 | 教學(xué)部 | 河北省 | 7000.00 | | 8 | 趙六 | male | 19 | 保安部 | 河北省 | 9000.00 | | 9 | 豬七 | female | 24 | 保潔部 | 北京 | 9000.00 | +----+-----------+--------+------+-----------+-----------+----------+ 9 rows in set (0.00 sec)where子句: 過濾查詢
-- where字句中可以使用:-- 比較運(yùn)算符:> < >= <= <> !=between 80 and 100 值在10到20之間in(80,90,100) 值是10或20或30like 'yuan%'/*pattern可以是%或者_(dá),如果是%則表示任意多字符,此例如唐僧,唐國(guó)強(qiáng)如果是_則表示一個(gè)字符唐_,只有唐僧符合。兩個(gè)_則表示兩個(gè)字符:__*/-- 邏輯運(yùn)算符在多個(gè)條件直接可以使用邏輯運(yùn)算符 and or not示例:
-- 查詢年紀(jì)大于24的員工 SELECT * FROM emp WHERE age>24;-- 查詢教學(xué)部的男老師信息 SELECT * FROM emp WHERE dep="教學(xué)部" AND gender="male";order:排序
按指定的列進(jìn)行,排序的列即可是表中的列名,也可以是select語句后指定的別名。
示例:
group by:分組查詢(*****)
GROUP BY 語句根據(jù)某個(gè)列對(duì)結(jié)果集進(jìn)行分組。在分組的列上我們可以使用 COUNT, SUM, AVG等函數(shù)進(jìn)行相關(guān)查詢。
-- 語法:SELECT column_name, function(column_name)FROM table_nameWHERE column_name operator valueGROUP 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(*) 人數(shù) FROM emp5 GROUP BY gender; -- 查詢各個(gè)部門的人數(shù) SELECT dep 部門,count(*) 人數(shù) FROM emp5 GROUP BY dep; -- 查詢每個(gè)部門最大的年齡 SELECT dep 部門,max(age) 最大年紀(jì) FROM emp5 GROUP BY dep; -- 查詢每個(gè)部門年齡最大的員工姓名 SELECT * FROM emp5 WHERE age in (SELECT max(age) FROM emp5 GROUP BY dep); -- 查詢每個(gè)部門的平均工資 SELECT dep 部門,avg(salary) 最大年紀(jì) FROM emp GROUP BY dep; --? 查詢教學(xué)部的員工最高工資: SELECT dep,max(salary) FROM emp11 GROUP BY dep HAVING dep="教學(xué)部"; -- 查詢平均薪水超過8000的部門 SELECT dep,AVG(salary) FROM? emp GROUP BY dep HAVING avg(salary)>8000; --? 查詢每個(gè)組的員工姓名 SELECT dep,group_concat(name) FROM emp GROUP BY dep; -- 查詢公司一共有多少員工(可以將所有記錄看成一個(gè)組) SELECT COUNT(*) 員工總?cè)藬?shù) FROM emp; ????? -- KEY: 查詢條件中的每個(gè)后的詞就是分組的字段 |
limit記錄條數(shù)限制
SELECT * from ExamResult limit 1; SELECT * from ExamResult limit 2,5; -- 跳過前兩條顯示接下來的五條紀(jì)錄 SELECT * from ExamResult limit 2,2;正則表達(dá)式
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}'; 回到頂部多表查詢
創(chuàng)建表
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 ("教學(xué)部"),("銷售部"),("人事部"); 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 | 教學(xué)部??? |
|? 2 | 銷售部??? |
|? 3 | 人事部??? |
+----+-----------+
3 rows in set (0.00 sec)
1.笛卡爾積查詢
?| 1 | select * from emp,dep; |
2、內(nèi)連接
查詢兩張表中都有的關(guān)聯(lián)數(shù)據(jù),相當(dāng)于利用條件從笛卡爾積結(jié)果中篩選出了正確的結(jié)果。
?| 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; |
?查詢結(jié)果:
+----+--------+----------+--------+----+-----------+ | id | name | salary | dep_id | id | name | +----+--------+----------+--------+----+-----------+ | 1 | 張三 | 8000.00 | 2 | 2 | 銷售部 | | 2 | 李四 | 12000.00 | 1 | 1 | 教學(xué)部 | | 3 | 王五 | 5000.00 | 2 | 2 | 銷售部 | | 4 | 趙六 | 8000.00 | 3 | 3 | 人事部 | | 5 | 豬七 | 9000.00 | 1 | 1 | 教學(xué)部 | | 7 | 蔡九 | 7000.00 | 2 | 2 | 銷售部 | +----+--------+----------+--------+----+-----------+ 6 rows in set (0.00 sec)這時(shí),我們就可以利用兩張表中所有的字段進(jìn)行查詢了
示例:
-- 查詢李四所在的部門名稱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)左外連接:在內(nèi)連接的基礎(chǔ)上增加左邊有右邊沒有的結(jié)果 ?SELECT * FROM emp LEFT JOIN dep ON dep.id=emp.dep_id; |
| 1 2 3 | --(1)外右連接:在內(nèi)連接的基礎(chǔ)上增加右邊有左邊沒有的結(jié)果 ?SELECT * FROM emp RIGHT JOIN dep ON dep.id=emp.dep_id; |
完整性約束
完整性約束是對(duì)字段進(jìn)行限制,從而符合該字段達(dá)到我們期望的效果比如字段含有默認(rèn)值,不能是NULL等 。直觀點(diǎn)說:如果插入的數(shù)據(jù)不滿足限制要求,數(shù)據(jù)庫(kù)管理系統(tǒng)就拒絕執(zhí)行操作
唯一約束
唯一約束可以有多個(gè)但索引列的值必須唯一,索引列的值允許有空值。
如果能確定某個(gè)數(shù)據(jù)列將只包含彼此各不相同的值,在為這個(gè)數(shù)據(jù)列創(chuàng)建索引的時(shí)候就應(yīng)該使用關(guān)鍵字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 | -- 創(chuàng)建唯一約束: 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個(gè)自動(dòng)增長(zhǎng)字段,這個(gè)自動(dòng)增長(zhǎng)字段通常作為主鍵,也可以用作非主鍵使用,但是請(qǐng)注意將自動(dòng)增長(zhǎng)字段當(dāng)做非主鍵使用時(shí)必須必須為其添加唯一索引,否則系統(tǒng)將會(huì)報(bào)錯(cuò)。
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 key
可以改為
mysql> CREATE TABLE t4(-> id INT NOT NULL,-> name VARCHAR(20),-> age INT UNIQUE AUTO_INCREMENT-> ); Query OK, 0 rows affected (0.13 sec)主鍵約束
主鍵是用于唯一標(biāo)識(shí)一條記錄的約束,如同身份證。
主鍵有兩個(gè)約束:非空且唯一!
創(chuàng)建主鍵
-- 方式1CREATE TABLE t1(id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(20) );-- 方式2CREATE TABLE t2(id INT NOT NULL,name VARCHAR(20) );注意:
1、一張表中最多只能有一個(gè)主鍵
2、表中如果沒有設(shè)置主鍵,默認(rèn)設(shè)置NOT NULL的字段為主鍵;此外,表中如果有多個(gè)NOT NULL的字段,則按順序?qū)⒌谝粋€(gè)設(shè)置NOT NULL的字段設(shè)為主鍵。
結(jié)論:主鍵一定是非空且唯一,但非空且唯一的字段不一定是主鍵。
3、主鍵類型不一定必須是整型
添加主鍵和刪除主鍵
?| 1 2 | -- 添加主鍵<br>alter table tab_name add primary key(字段名稱,...) <br> -- 刪除主鍵<br>alter table users drop primary key; |
?注意,如果主鍵是AUTO_INCREMENT,需要先取消AUTO_INCREMENT,因?yàn)?span style="color:#000000;">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;-- 僅僅用這句也無法直接刪除主鍵 |
復(fù)合主鍵
所謂的復(fù)合主鍵 就是指你表的主鍵含有一個(gè)以上的字段。
如果一列不能唯一區(qū)分一個(gè)表里的記錄時(shí),可以考慮多個(gè)列組合起來達(dá)到區(qū)分表記錄的唯一性,形式
①創(chuàng)建時(shí):
| 1 2 3 4 5 6 | create table sc ( ????studentid int, ????courseid int, ????score int, primary key (studentno,courseid) );???????? |
②修改時(shí):
?| 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 時(shí)使用,如果不指定CONSTRAINT symbol,MYSQL會(huì)自動(dòng)生成一個(gè)名字。
準(zhǔn)備表和數(shù)據(jù)
-- 子表 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) -- 注意外鍵字段的數(shù)據(jù)類型必須與關(guān)聯(lián)字段一致 );-- 主表 CREATE TABLE dep(id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(20) );INSERT emp (name,dep_id) VALUES ("alex",1),("egon",2),("alvin",2),("莎莎",1),("wusir",2),("女神",2),("冰冰",3),("姍姍",3);INSERT dep (name) VALUES ("市場(chǎng)部"),("教學(xué)部"),("銷售部");
添加外鍵
現(xiàn)在,刪除市場(chǎng)部:
?| 1 2 | mysql> DELETE FROM dep WHERE name="市場(chǎng)部"; Query OK, 1 row affected (0.01 sec) |
居然刪除成功了,不可思議,現(xiàn)在問題來了: alex和莎莎兩個(gè)人怎么辦?
所以,為了避免類似操作,我們需要給兩張表建立約束,這種約束稱為外鍵約束。外鍵的好處:可以使得兩張表關(guān)聯(lián),保證數(shù)據(jù)的一致性和實(shí)現(xiàn)一些級(jí)聯(lián)操作
?| 1 2 3 4 5 6 | INSERT dep (id,name) VALUES (1,"市場(chǎng)部");? -- 思考為什么加這一句? ALTER TABLE emp ADD CONSTRAINT dep_fk_emp ????????????????????FOREIGN KEY (dep_id) ????????????????????REFERENCES? dep(id); <br><br>mysql> DELETE FROM dep WHERE name="市場(chǎng)部";<br><br>ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fail |
INNODB支持的ON語句
外鍵約束對(duì)子表的含義: 如果在主表中(比如dep)找不到候選鍵,則不允許在子表(比如emp)上進(jìn)行insert/update
外鍵約束對(duì)父表的含義: 在主表上進(jìn)行update/delete以更新或刪除在子表中有一條或多條應(yīng)匹配行的候選鍵時(shí),父表的行為取決于:在定義子表的外鍵時(shí)指定的 -- on update/on delete子句
-- ------------------------innodb支持的四種方式---------------------------------cascade方式 在父表上update/delete記錄時(shí),同步update/delete掉子表的匹配記錄外鍵的級(jí)聯(lián)刪除:如果父表中的記錄被刪除,則子表中對(duì)應(yīng)的記錄自動(dòng)被刪除FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)ON DELETE CASCADE;set null方式 在父表上update/delete記錄時(shí),將子表上匹配記錄的列設(shè)為null ; 要注意子表的外鍵列不能為not nullFOREIGN KEY (charger_id) REFERENCES ClassCharger(id)ON DELETE SET NULL;Restrict方式 :拒絕對(duì)父表進(jìn)行刪除更新操作(了解)No action方式 在mysql中同Restrict,如果子表中有匹配的記錄,則不允許對(duì)父表對(duì)應(yīng)候選鍵 ; 進(jìn)行update/delete操作(了解)轉(zhuǎn)載于:https://www.cnblogs.com/xiaotaiyanghhh/p/8510067.html
總結(jié)
以上是生活随笔為你收集整理的Mysql--重点1的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java完全自学手册(java完全自学手
- 下一篇: 配置mysql环境变量