Mysql--重点1

回到顶部

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/414616.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6、jeecg 笔记之 自定义excel 模板导出(一)

6、jeecg 笔记之 自定义excel 模板导出&#xff08;一&#xff09; 1、前言 jeecg 中已经自带 excel 的导出导出功能&#xff0c;其所使用的是 easypoi&#xff0c;尽管所导出的 excel 能满足大部分需求&#xff0c; 但总是有需要用到自定义 excel 导出模板&#xff0c;下文所…

Android Lambda 表达式使用实例,-

1、Lambda表达式理解 Lambda 表达式&#xff0c;也可称为闭包&#xff0c;它是推动 Java 8 发布的最重要新特性。 Lambda 允许把函数作为一个方法的参数&#xff08;函数作为参数传递进方法中&#xff09;。 使用Lambda 表达式可以使代码变的更加简洁紧凑。 2、Lambda表达式…

前端学习(2740):重读vue电商网站50之Element-UI 组件按需加载

通过 CDN 优化 ElementUI 的打包 虽然在开发阶段&#xff0c;我们启用了 element-ui 组件的按需加载&#xff0c;尽可能的减少了打包的体积&#xff0c;但是那些被按需加载的组件&#xff0c;还是占用了较大的文件体积。此时&#xff0c;我们可以将 element-ui 中的组件&#…

8、jeecg 笔记之 自定义word 模板导出(一)

8、jeecg 笔记之 自定义word 模板导出&#xff08;一&#xff09; 1、前言 jeecg 中已经自带 word 的导出导出功能&#xff0c;其所使用的也是 easypoi&#xff0c;尽管所导出的 word 能满足大部分需求&#xff0c; 但总是有需要用到自定义 word导出模板&#xff0c;下文所用到…

Android 全屏抽屉fragment,NavigationView

1、首先是右→左进入动画 、slide_left.xml <?xml version"1.0" encoding"utf-8"?> <set xmlns:android"http://schemas.android.com/apk/res/android"><translateandroid:duration"800"android:fromXDelta"20…

Eclipse 创建第一个 springboot 应用

Eclipse 创建第一个 springboot 应用 1、前言 一直想把笔记整理出来&#xff0c;分享一下 springboot 的搭建&#xff1b; 因为私下 idea 用的比较多&#xff0c;使用比较方便&#xff0c;但恰逢小伙伴问起 eclipse 怎么搭建的问题&#xff0c; 顾整理以记之。 2、springboot …

Can't process attribute android:fillColor=@color/gray,添加vector属性报错解决方法

Android studio添加vector属性文件报错 vector属性文件 <vector xmlns:android"http://schemas.android.com/apk/res/android"android:width"24dp"android:height"24dp"android:viewportHeight"49.94"android:viewportWidth"4…

前端学习(2742):重读vue电商网站52之路由懒加载

当打包构建项目时&#xff0c;JavaScript 包会变得非常大&#xff0c;影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块&#xff0c;然后当路由被访问的时候才加载对应组件&#xff0c;这样就更加高效了。 具体需要 3 步&#xff1a; 安装 babel/plugin-synt…

Android Service与IntentService区别

相同点&#xff1a; 1、首先Service与IntentService都是Android的基本组件service 2、使用时都是一样需要创建&#xff0c;配置&#xff1b;和调用启动方式都是一样的 不同点&#xff1a; 1、IntentService是继承自Service的service 类&#xff0c;创建了自己的特有方法onH…

前端学习(2743):重读vue电商网站53之项目上线

通过 node 创建 web 服务器。开启 gzip 配置。配置 https 服务。使用 pm2 管理应用。 通过 node 创建 web 服务器 创建 node 项目&#xff0c;并安装 express&#xff0c;通过 express 快速创建 web 服务器&#xff0c;将 vue 打包生成的 dist 文件夹&#xff0c;托管为静态资…

记录请求的耗时(拦截器、过滤器、aspect)

记录请求的耗时&#xff08;拦截器、过滤器、aspect&#xff09; 文章前言 记录控制器请求的耗时处理通常有三种实现方式&#xff0c;分别是&#xff1a;过滤器、拦截器、aspect&#xff1b;下文将逐一实现。 1、Filter 过滤器 1.1、方法说明 需要实现 Filter 类&#xff0c;主…

7、Flutter banner_view 轮播图的使用

7、Flutter banner_view 轮播图的使用 1、前言 实现轮播图&#xff0c;效果如下&#xff1a; 2、实现 将采用 banner_view 实现&#xff1a;资源库地址 2.1、yaml 引入依赖 在 pubspec.yaml 声明需要引用的库&#xff0c;执行命令 flutter packages get 进行拉取即可使用。 ba…

Android 人脸实名验证demo——腾讯人脸核身·云智慧眼

可以说比较容易实现&#xff1a;只需要获取BizToken&#xff0c;再起调腾讯SDK即可 1、首先登录腾讯云平台&#xff0c;申请权限&#xff0c;创建应用 腾讯云&#xff1a; https://cloud.tencent.com/ 2、配置应用信息及实名验证流程设置&#xff0c;下载SDK 不过&#xff0c;…

[JSOI 2015] 子集选取

4475: [Jsoi2015]子集选取 Time Limit: 1 Sec Memory Limit: 512 MBSubmit: 363 Solved: 255[Submit][Status][Discuss]Description Input 输入包含一行两个整数N和K&#xff0c;1<N,K<10^9 Output 一行一个整数&#xff0c;表示不同方案数目模1,000,000,007的值。 Sam…

工作242:关于第二个git仓库提交代码

其实第二个仓库 建立的时候直接取进行 push操作就可以完成 原理一样 可以直接对代码地址进行提交

工作243:name报错

name报错就是name的数值报错

Android 图片压缩,Bitmap旋转,bitmap与byte[]之间相互转换,Bitmap与String互转

频繁setImageBitmap引起oom问题解决方法 Glide.with(gsewmimg).load(getCodeBitmap(response.data.skip, R.mipmap.zhifuicon)).into(gsewmimg);压缩前后。图片大小 2.22MB——>200KB 1、图片压缩方法&#xff1a; Bitmap bitmap; byte[] buff; buff Bitmap2Bytes(bitmap…

9、Flutter 实现 生成二维码

9、Flutter 实现 生成二维码 1、加入依赖 在 pubspec.yaml 中 dependencies 节点下添加&#xff1a; dependencies: qr_flutter: ^1.1.6 2、引入代码 在需要细线二维码的 dart 类中引入依赖代码包&#xff1a; import package:qr_flutter/qr_flutter.dart; 代码部分 import p…

Android 换肤demo,轻量快捷接入集成,判断是否夜间模式

true为黑夜模式 //检查当前系统是否已开启暗黑模式 public static boolean getDarkModeStatus(Context context) {int mode context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;return mode Configuration.UI_MODE_NIGHT_YES;} 实现…