知识预览

  • sql语句规范
  • 数据类型
  • 数据库操作
  • 数据表操作
  • 表记录操作
  • 查询表记录(select)
  • 多表查询
  • 完整性约束
回到顶部

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
+------+

View Code

显示长度和存储字节

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: 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)

字符串类型

存储字符串:

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%。因此,用户在设计数据库时应当综合考虑各方面的因素,以求达到最佳的平衡texttext数据类型用于保存变长的大字符串,可以组多到65535 (2**16 − 1)个字符。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

注意:

在查询的时候,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 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);

View Code

查看表信息

    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("alex",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";

View Code

修改表记录

?
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';

View Code

删除表记录

方式1:
delete from tab_name [where ....]方式2:
truncate table emp_new;/*    如果不跟where语句则删除整张表中的数据delete只能用来删除一行记录delete语句只能删除表中的内容,不能删除表本身,想要删除表,用dropTRUNCATE TABLE也可以删除表中的所有数据,词语句首先摧毁表,再新建表。此种方式删除的数据不能在事务中恢复。*/

示例:

-- 删除表中名称为’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 限制条数
-- Mysql在执行sql语句时的执行顺序:-- from  where  select  group by  having 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 | alex      | 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) 值是10或20或30like '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_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(*) 人数 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 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)

主键约束

主键是用于唯一标识一条记录的约束,如同身份证。

主键有两个约束:非空且唯一!

创建主键

-- 方式1CREATE TABLE t1(id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(20)
);-- 方式2CREATE 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 ("alex",1),("egon",2),("alvin",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 nullFOREIGN KEY (charger_id) REFERENCES ClassCharger(id)ON DELETE SET NULL;Restrict方式 :拒绝对父表进行删除更新操作(了解)No action方式 在mysql中同Restrict,如果子表中有匹配的记录,则不允许对父表对应候选键 ; 进行update/delete操作(了解)

转载于:https://www.cnblogs.com/xiaotaiyanghhh/p/8510067.html

Mysql--重点1相关推荐

  1. JAVA-MySQL四{MySQL重点DQL查询数据}JAVA从基础开始 --7

    JAVA-MySQL四{MySQL重点DQL查询数据}JAVA从基础开始 --7 DQL查询语句 DQL - Data Query Language:数据查询语言 指定查询字段 1.全查 2.指定字段 ...

  2. linux和mysql重点哪个_重要的MySQL 文档存储知识点扫盲

    MySQL 文档存储 可以跳过底层数据结构创建.数据规范化和其它使用传统数据库时需要做的工作,直接存储数据. MySQL 可以提供 NoSQL JSON 文档存储Document Store 了,这样 ...

  3. 企业面试中关于MYSQL重点的28道面试题解答

    问题1:char.varchar的区别是什么? varchar是变长而char的长度是固定的.如果你的内容是固定大小的,你会得到更好的性能. 问题2: TRUNCATE和DELETE的区别是什么? D ...

  4. mysql text转varchar_关于企业面试中:“ Mysql重点 ”的28道面试题解析!

    问题1:char.varchar的区别是什么? varchar是变长而char的长度是固定的.如果你的内容是固定大小的,你会得到更好的性能. 问题2: TRUNCATE和DELETE的区别是什么? D ...

  5. 《逆袭进大厂》第十二弹之MySQL重点篇27问27答

    大家好,我是阿秀. 我来更新了,本期是 MySQL 第二期,至此 MySQL 部分就全部更新完毕了,下一弹就是 Redis 篇了. 上一篇文章中,小伙伴建议将资料按照更细粒度去整理一番,我觉得是非常不 ...

  6. 无法安装mysql server 2008_Windows Server2008安装mysql5.6出现程序无法正常启动(0xc000007b)...

    下载 到官网下载mysql5.6版本,msi安装包只有32位无64位 移动到指定文件夹下,解压文件 添加环境变量 变量名:MYSQL_HOME 变量值:C:\Program Files\mysql 即 ...

  7. window 自动安装MySQL数据库_windows安装MySQL数据库

    windows安装MySQL数据库 最终效果展示 具体步骤 打开MySQL官网,找到downloads 选择MySQL社区版 选择MySQL Community Server社区器 选择windows ...

  8. mysql dba高级教程_MySQL DBA高级视频教程 博瑞森一线DBA大神亲授

    下载服务器:五号服务器---VIP资料下载八区\数据库专区 游客,如果您要查看本帖隐藏内容请回复 MySQL DBA高级视频教程 这个是我参与培训的,分享给大家学习,真正一线DBA大神亲授 全程高清, ...

  9. 数据库性能测试-mysql篇

    一.数据库主从同步的工作原理 主从复制原理: 上边这张交互图就清楚的标记出了Master节点如何同步到Slave节点 1.首先Master上的修改.删除.新增操作都会被记录到一个叫做binlog的文件 ...

  10. python入门与提高实践 老男孩_跟老男孩学Linux运维:MySQL入门与提高实践

    第10章 MySQL数据库日志知识与企业应用实践 10.1 MySQL常用日志文件知识 10.2 错误日志的介绍与配置 10.3 普通查询日志的介绍与配置 10.4 二进制日志的介绍与配置 10.5  ...

最新文章

  1. Zabbix,Nagios,OneAPM Servers 安装部署
  2. centos7 harbor 单机搭建
  3. 2015.12.23 OC中的字符串(NSStringNSMutableString) 数组(NSArrayNSMutableArray)
  4. python 字符串 编码 解码_Python 字符串编解码研究
  5. 【每日SQL打卡】​​​​​​​​​​​​​​​DAY 8丨平面上的最近距离【难度中等】
  6. 主机路由在计算机中的应用
  7. 微信 账户升级服务器地址,微信支付商户平台账户升级后有哪些新功能呢?
  8. 网页模板素材|解救不会编程的UI设计师网页设计者!
  9. linux源码包与RPM包的区别
  10. 个人设计web前端大作业 基于html5制作美食菜谱网页设计作业代码
  11. re2020 bt2020_2020年最好的4个在线学习平台
  12. 蓝桥杯 Java B组省赛真题【2017】
  13. 自己动手 DIY 一个读写200MB/s 的高速 U 盘
  14. 全文检索同时高亮多个字段
  15. c语言之奇偶数分开排序
  16. 写给Android开发的Android简史
  17. JVM_06 内存模型(JMM)篇
  18. 【Python】list写入txt文件
  19. 2000-2020上市公司全要素生产率OLS和固定效应方法含原始数据和Stata代码
  20. python自动群发_python---自动群发邮件

热门文章

  1. Gvim 字体大小设置和FencView插件安装
  2. [Bash]kill指定的进程名
  3. 前端学习(3020):vue+element今日头条管理--创建路由和配置路由
  4. 前端学习(2994):vue+element今日头条管理--初始化目录结构
  5. [html] 如何禁止web端的页面缩放?
  6. [html] const nums1 = [1, 2, 2, 1], nums2 = [2] 交集是什么?
  7. [css] 浏览器是怎样判断元素是否和某个CSS选择器匹配?
  8. [css] 请用css写一个扫码的加载动画图
  9. [css] 如何使用css实现鼠标跟随?
  10. 前端学习(2730):重读vue电商网站40之使用vue-table-with-tree-grid