Mysql

Posted 四十不惑的编程之路

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql相关的知识,希望对你有一定的参考价值。

 

linux下安装
--yum -y install mariadb mariadb-server

OR

--yum -y install mysql mysql-server

 

启动

--service mysqld start #开启 --chkconfig mysqld on #设置开机自启 OR --systemctl start mariadb --systemctl enable mariadb

cmd模式下

设置密码

-- mysqladmin -uroot password \'123\' #设置初始密码,初始密码为空因此-p选项没有用 -- mysqladmin -u root -p123 password \'1234\' #修改root用户密码

登陆 mysql -uroot -p123456

   mysql -uroot -p123456 -h 192.168.31.95   (远程登陆)

退出 mysql>quit;

 

常用命令

select now(); 打印当前时间
单行注释  --
多行注释  /* */

创建数据库

create database db_name;

create database if not exists db_name character set utf8;

查看数据库

show databases;

show create database db_name;  查看数据库的创建信息

删除数据库

drop database db_name;

更改数据库信息

alter database db_name character set utf8;

使用数据库

use  db_name;

select database();  查看当前使用的数据库

MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。

Decimal(n,m)表示数值中共有n位数,其中整数n-m位,小数m位。例:decimal(10,6),数值中共有10位数,其中整数占4位,小数占6位。

每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。

 

CHAR和VARCHAR类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。

BINARY和VARBINARY类类似于CHAR和VARCHAR,不同的是它们包含二进制字符串而不要非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。

BLOB是一个二进制大对象,可以容纳可变数量的数据。有4种BLOB类型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。它们只是可容纳值的最大长度不同。

有4种TEXT类型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。这些对应4种BLOB类型,有相同的最大长度和存储需求。

 

创建一个表

CREATE TABLE employee(

  id INT [完整性约束条件],  [PRIMARY KEY auto_increment] -> 主键,自增

  name VARCHAR(32) not null unique,  非空,唯一  

  gender BOOLEAN,  -> 系统会自动转换为tinyint(1)

  age TINYINT,

  department VARCHAR(20),

  salary DOUBLE(7,2)  最后一个不加,号

)[ character set utf8][ENGINE=INNODB];

 

创建时也可以指定数据库 create table db_name.tab_name(.....);

查看当前数据库中的所有表

show tables;

查看某表结构

desc tab_name;

show columns from tab_name

查看表的创建语句

show create table tab_name;

 

修改表结构

 -- (1)增加列(字段) add
      alter table tab_name add [column] 列名 类型[完整性约束条件][first|after 字段名];
      alter table user add addr varchar(20) not null unique first/after username;
      #添加多个字段
      alter table users2 
            add addr varchar(20),
            add age  int first,
            add birth varchar(20) after name;

   -- (2)修改一列类型 modify
      alter table tab_name modify 列名 类型 [完整性约束条件][first|after 字段名];
      alter table users2 modify age tinyint default 20;
      alter table users2 modify age int  after id;
   
   -- (3)修改列名  change
      alter table tab_name change [column] 列名 新列名 类型 [完整性约束条件][first|after 字段名];
      alter table users2 change age Age int default 28 first;

   -- (4)删除一列  drop
      alter table tab_name drop [column] 列名;
      -- 删除多列
   alter table tab_name drop 列名1,drop 列名2;

加一个并删一个 alter table users2 add salary float(6,2) unsigned not null after name, drop addr; -- (5)修改表名 rename rename table 表名 to 新表名; -- (6)修改表所用的字符集 alter table student character set utf8; -- 4.删除表 drop table tab_name; ---5 添加主键,删除主键
alert table tab_name add constraint primary key(字段名称,...) alter table tab_name add primary key(字段名称,...) alter table users drop primary key; eg: mysql> create table test5(num int auto_increment); ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key create table test(num int primary key auto_increment); -- 思考,如何删除主键? alter table test modify id int; -- auto_increment没了,但这样写主键依然存在,所以还要加上下面这句 alter table test drop primary key;-- 仅仅用这句也无法直接删除主键

插入记录
insert into emp set name="张三",age=18;
insert into emp (id,age,name,gender,salary,depart,is_married)

          values(1,38,\'alex\',0,1700,\'技术部\',1);
insert into emp (name,salary,depart) values(\'少年\',30000,\'保安部\'); 需要插入哪些字段就写哪些字段

插入多条记录
  insert into emp (name,salary,depart) values(\'少年\',30000,\'保安部\'),(\'冰冰\',5000,\'销售部\');

注意

insert into values (10,\'崔京浩\',1,6000,\'技术部\',0);  这种方法没有写字段名,则必须将所有字段对应的值写全

修改记录
update tab_name set field1=value1,field2=value2,......[where语句]; 不加where会对所有记录操作

删除记录
delete from tab_name [where条件];  一条一条删除
truncate table tab_name; 将表销毁掉,然后重新创建

查询记录(单表)
select distinct 字段
from tab_name;
select salary+10 from tab_name;
select js+django+flask as 总成绩 from tab_name;
select name js from tab_name; -> select name as js from tab_name;
使用where子句,进行过滤查询。

-- 查询姓名为XXX的学生成绩
select * from ExamResult where name=\'yuan\';
-- 查询英语成绩大于90分的同学
select id,name,JS from ExamResult where JS>90;
-- 查询总分大于200分的所有同学
select name,JS+Django+OpenStack as 总成绩 from
                        ExamResult where JS+Django+OpenStack>200 ;
-- where字句中可以使用:
-- 比较运算符:
 > < >= <= <> !=
between 80 and 100 值在10到20之间
 in(80,90,100) 值是10或20或30
like \'yuan%\'
 /*
pattern可以是%或者_,
如果是%则表示任意多字符,此例如唐僧,唐国强
如果是_则表示一个字符唐_,只有唐僧符合。两个_则表示两个字符:__
*/

-- 逻辑运算符
在多个条件直接可以使用逻辑运算符 and or not
-- 练习
      -- 查询JS分数在 70-100之间的同学。
      select name ,JS from ExamResult where JS between 80 and 100;
      -- 查询Django分数为75,76,77的同学。
      select name ,Django from ExamResult where Django in (75,76,77);
      -- 查询所有姓王的学生成绩。
      select * from ExamResult where name like \'王%\';
      -- 查询JS分>90,Django分>90的同学。
      select id,name from ExamResult where JS>90 and Django >90;
      -- 查找缺考数学的学生的姓名
      select name from ExamResult where Database is null;

(4)Order by 指定排序的列,排序的列即可是表中的列名,也可以是select 语句后指定的别名。

 -- select *|field1,field2... from tab_name order by field1[Asc|Desc],field2[Asc|Desc]...
-- Asc 升序、Desc 降序,其中asc为默认值 ORDER BY 子句应位于SELECT语句的结尾。
-- 练习: -- 对JS成绩排序后输出。 select * from ExamResult order by JS;
-- 对总分排序按从高到低的顺序输出 select name ,(ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0)) 总成绩 from ExamResult order by 总成绩 desc;
-- 对姓李的学生成绩排序输出 select name ,(ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0)) 总成绩 from ExamResult where name like \'李%\' order by 总成绩 desc;

-- (5)group by 分组查询:
CREATE TABLE order_menu(
id INT PRIMARY KEY auto_increment,
product_name VARCHAR (20),
price FLOAT(6,2),
born_date DATE,
class VARCHAR (20)
);


INSERT INTO order_menu (product_name,price,born_date,class) VALUES
("苹果",20,20170612,"水果"),
("香蕉",80,20170602,"水果"),
("水壶",120,20170612,"电器"),
("被罩",70,20170612,"床上用品"),
("音响",420,20170612,"电器"),
("床单",55,20170612,"床上用品"),
("草莓",34,20170612,"水果");


-- 注意,按分组条件分组后每一组只会显示第一条记录

-- group by字句,其后可以接多个列名,也可以跟having子句,对group by 的结果进行筛选。


-- 按位置字段筛选
select * from order_menu group by 5;    按第五个字段进行分组(此例为class

-- 练习:对购物表按类名分组后显示每一组商品的价格总和
select class,SUM(price)from order_menu group by class;

-- 练习:对购物表按类名分组后显示每一组商品价格总和超过150的商品
select class,SUM(price)from order_menu group by class
HAVING SUM(price)>150;  having 指对分组后的记录进行过滤,而where是对分组前的记录进行过滤

 

/*
having 和 where两者都可以对查询结果进行进一步的过滤,差别有:
<1>where语句只能用在分组之前的筛选,having可以用在分组之后的筛选;
<2>使用where语句的地方都可以用having进行替换
<3>having中可以用聚合函数,where中就不行。
*/


-- GROUP_CONCAT() 函数  将group by产生的同一个分组中的值连接起来,返回一个字符串结果。

 

-- (6)聚合函数。
-- (一般和分组查询配合使用)

--<1> 统计表中所有记录

-- COUNT(列名):统计行的个数
-- 统计一个班级共有多少学生?先查出所有的学生,再用count包上
select count(*) from ExamResult;
-- 统计JS成绩大于70的学生有多少个?
select count(JS) from ExamResult where JS>70;
-- 统计总分大于280的人数有多少?
select count(name) from ExamResult
where (ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0))>280;
-- 注意:count(*)统计所有行; count(字段)不统计null值.

-- SUM(列名):统计满足条件的行的内容和
-- 统计一个班级JS总成绩?先查出所有的JS成绩,再用sum包上
select JS as JS总成绩 from ExamResult;
select sum(JS) as JS总成绩 from ExamResult;
-- 统计一个班级各科分别的总成绩
select sum(JS) as JS总成绩,
sum(Django) as Django总成绩,
sum(OpenStack) as OpenStack from ExamResult;

-- 统计一个班级各科的成绩总和
select sum(ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0))
as 总成绩 from ExamResult;
-- 统计一个班级JS成绩平均分
select sum(JS)/count(*) from ExamResult ;
-- 注意:sum仅对数值起作用,否则会报错。

-- AVG(列名):
-- 求一个班级JS平均分?先查出所有的JS分,然后用avg包上。
select avg(ifnull(JS,0)) from ExamResult;
-- 求一个班级总分平均分
select avg((ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0)))
from ExamResult ;
-- Max、Min
-- 求班级最高分和最低分(数值范围在统计中特别有用)
select Max((ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0)))
最高分 from ExamResult;
select Min((ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0)))
最低分 from ExamResult;
-- 求购物表中单价最高的商品名称及价格
---SELECT id, MAX(price) FROM order_menu;--id和最高价商品是一个商品吗?

SELECT MAX(price) FROM order_menu;

-- 注意:null 和所有的数计算都是null,所以需要用ifnull将null转换为0!
-- -----ifnull(JS,0)


-- with rollup的使用

--<2> 统计分组后的组记录


-- (7) 重点:书写顺序 Select    from    where    group by    having    order by   limit
-- Mysql在执行sql语句时的执行顺序:
-- from     where  group by    having    select    order by    limit
-- 分析:
select JS as JS成绩 from ExamResult where JS成绩 >70; ---- 不成功
select JS as JS成绩 from ExamResult having JS成绩 >90; --- 成功

-- (8) limit : 从哪一行开始,显示几条,下标从0开始
SELECT * from ExamResult limit 1;   从下标0开始,显示一条
SELECT * from ExamResult limit 2,5;--跳过前两条显示接下来的五条纪录
SELECT * from ExamResult limit 2,2;


--- (9) 使用正则表达式查询
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}\';

 

 

函数:可以用在select语句及其子句也可以用在update,delete语句当中

函数分类:字符串函数、数值函数、日期和时间函数、流程函数、其它函数

一、    字符串函数

Concat(s1,s2…sn) 拼接字符串(任何字符串与null相连后结果都是null)

Insert(str,x,y,instr) 将字符串str从x位置开始,y个字符长的子串替换为指定字符instr

Lower(str) upper(str) str转为小写/大写

Left(str,x) right(str,x) 返回字符串最左边/右边x个字符,如x为null则不返回任何字符

Lpad(str,n,pad) rpad(str,n,pad) 在str左边/右边填充字符串pad,直到结果为n个字符的长度

Ltrim(str) rtrim(str) Trim(str) 去左/右/左右空格

Repeat(str,x) 重复str x次

Replace(str,a,b)在str中用b替换a

Substring(str,x,y) 返回str中第x位置起y个长度的字符

二、    数值函数

Abs(x) 求x的绝对值

Ceil(x) 小数不为零部分上取整

Floor(x) 小数不为零部分下取整

Mod(x,y) 求x%y 模

Rand() 随机0-1的小数。 Select floor(rand() *10)    返回1-10的随机数

三、日期和时间函数

四、流程函数

五、其它函数

 

 

 

 

 

数据完整性:保证用户输入到数据库中的内容是正确的

(1)实体(一行记录代表一个实体)完整性:标识每一行数据不重复,行级约束

主键约束 primary key   数据唯一,不能为null

唯一约束 unique    指定列的数据不能重复,可以为null

自动增长列 auto_increment

联合主键 create table student(id bigint,snum int, name varchar(50), primary key(id, snum));

将id和snum合为一个主键,称为联合主键,这两个段数据同时相同时才违反联合主键约束

 (2)域完整性(域代表一个单元格)

数据类型:数值类型、日期类型、字符串类型

非空约束 not null

缺省值约束 default = xxx

(3)参照完整性(表与表之间的约束)

注意:两个表必须得是innoDB引擎

外键 FOREIGN KEY

 

 外键

create table student(

  id int primary key auto_increment,

  name varchar(20),

  charger_id tinyint,

  FOREIGN KEY (charger_id) REFERENCES classcharger(id)  charger_id 与 classcharger表中的id 必须数据类型一致 

  或者 CONSTRAINT 外键名 FOREIGN  KEY (charger_id) REFERENCES classcharger(id)     

)

 

给某个字段增加外键

ALTER TABLE student ADD  CONSTRAINT 外键名 FOREIGN  KEY (charger_id) REFERENCES classcharger(id)

删除外键

ALTER TABLE student DROP FOREIGN KEY KEY 外键名


--外键约束对子表的含义:   如果在父表中找不到候选键,则不允许在子表上进行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操作(了解)

多表查询

合并结果集:就是把两个select语句查询的结果合并在一起

注意:被合并的两个结果,列数,列类型必须相同

union 去重, union all不会去重

 

准备表

复制代码
-- 准备两张表
-- company.employee
-- company.department

      create table employee(
      emp_id int auto_increment primary key not null,
      emp_name varchar(50),
      age int,
      dept_id int
      );

      insert into employee(emp_name,age,dept_id) values
        (\'A\',19,200),
        (\'B\',26,201),
        (\'C\',30,201),
        (\'D\',24,202),
        (\'E\',20,200),
        (\'F\',38,204);


    create table department(
       dept_id int,
       dept_name varchar(100)
      );

    insert into department values
      (200,\'人事部\'),
      (201,\'技术部\'),
      (202,\'销售部\'),
      (203,\'财政部\');

mysql> select * from employee;
+--------+----------+------+---------+
| emp_id | emp_name | age  | dept_id |
+--------+----------+------+---------+
|      1 | A        |   19 |     200 |
|      2 | B        |   26 |     201 |
|      3 | C        |   30 |     201 |
|      4 | D        |   24 |     202 |
|      5 | E        |   20 |     200 |
|      6 | F        |   38 |     204 |
+--------+----------+------+---------+
6 rows in set (0.00 sec)

mysql> select * from department;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|     200 | 人事部    |
|     201 | 技术部    |
|     202 | 销售部    |
|     203 | 财政部    |
+---------+-----------+
4 rows in set (0.01 sec)
复制代码

多表查询之连接查询

1.笛卡尔积查询

复制代码
mysql> SELECT * FROM employee,department;

--        select employee.emp_id,employee.emp_name,employee.age,
--        department.dept_name from employee,department;

+--------+----------+------+---------+---------+-----------+
| emp_id | emp_name | age  | dept_id | dept_id | dept_name |
+--------+----------+------+---------+---------+-----------+
|      1 | A        |   19 |     200 |     200 | 人事部    |
|      1 | A        |   19 |     200 |     201 | 技术部    |
|      1 | A        |   19 |     200 |     202 | 销售部    |
|      1 | A        |   19 |     200 |     203 | 财政部    |
|      2 | B        |   26 |     201 |     200 | 人事部    |
|      2 | B        |   26 |     201 |     201 | 技术部    |
|      2 | B        |   26 |     201 |     202 | 销售部    |
|      2 | B        |   26 |     201 |     203 | 财政部    |
|      3 | C        |   30 |     201 |     200 | 人事部    |
|      3 | C        |   30 |     201 |     201 | 技术部    |
|      3 | C        |   30 |     201 |     202 | 销售部    |
|      3 | C        |   30 |     201 |     203 | 财政部    |
|      4 | D        |   24 |     202 |     200 | 人事部    |
|      4 | D        |   24 |     202 |     201 | 技术部    |
|      4 | D        |   24 |     202 |     202 | 销售部    |
|      4 | D        |   24 |     202 |     203 | 财政部    |
|      5 | E        |   20 |     200 |     200 | 人事部    |
|      5 | E        |   20 |     200 |     201 | 技术部    |
|      5 | E        |   20 |     200 |     202 | 销售部    |
|      5 | E        |   20 |     200 |     203 | 财政部    |
|      6 | F        |   38 |     204 |     200 | 人事部    |
|      6 | F        |   38 |     204 |     201 | 技术部    |
|      6 | F        |   38 |     204 |     202 | 销售部    |
|      6 | F        |   38 |     204 |     203 | 财政部    |
+--------+----------+------+---------+---------+-----------+
复制代码

2.内连接

  select * from employee,department where employee.dept_id = department.dept_id;  隐式连接(99写法)
--select * from employee inner join department on employee.dept_id = department.dept_id;    inner可以省略不写

      +--------+----------+------+---------+---------+-----------+
      | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
      +--------+----------+------+---------+---------+-----------+
      |      1 | A        |   19 |     200 |     200 | 人事部    |
      |      2 | B        |   26 |     201 |     201 | 技术部    |
      |      3 | C        |   30 |     201 |     201 | 技术部    |
      |      4 | D        |   24 |     202 |     202 | 销售部    |
      |      5 | E        |   20 |     200 |     200 | 人事部    |
      +--------+----------+------+---------+---------+-----------+

等值连接:两个表同时出现id号(值)才显示
     on后面只写主外键
     如果还有条件就在后面写where select * from employee inner join department on employee.dept_id = department.dept_id where xxx;
      多表联查后面还有就条就直接写and   select * from employee inner join department on employee.dept_id = department.dept_id where xxx and xxx;


多表连接


Select * from stu st,score sc,course c where st.id=sc.sid and sc.cid = c.cid; (99查询写法)

Select * from stu st

join score sc on st.id =sc.sid    先join第一个表,并确定条件

join course c on sc.cid =c.cid;      再join第二个表,并确定条件     (内连接写法 inner可以省略不写)

 

非等值连接

查询所有员工的姓名,工资,所在部门的名称以及工资的等级

Select e.ename,e.salary,d.dname,g.grade from emp e, dept d, salarade g

Where e.deptno = d.deptno

And e.salary >= g.lowsalary and e.salary <= g.highsalary; (99查询写法)

 

Select e.ename,e.salary,d.dname,g.grade from emp e, dept d, salarade g

Where e.deptno = d.deptno

And e.salary between g.lowsalary and  g.highsalary; (99查询写法)

 

Select e.ename,e.salary,d.dname from emp e

Join dept d on e.deptno = d.deptno

Join salgrade g on e.salary between g.lowsalary and g.highsalary (内连接写法)

 


复制代码

3.外连接

复制代码
--(1)左外连接:在内连接的基础上增加左边有右边没有的结果 (左边的表数据全查出来,右边的表满足条件的才查出来)

 select * from employee left join department on employee.dept_id = department.dept_id;

     +--------+----------+------+---------+---------+-----------+
    | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
    +--------+----------+------+---------+---------+-----------+
    |      1 | A        |   19 |     200 |     200 | 人事部    |
    |      5 | E        |   20 |     200 |     200 | 人事部    |
    |      2 | B        |   26 |     201 |     201 | 技术部    |
    |      3 | C        |   30 |     201 |     201 | 技术部    |
    |      4 | D        |   24 |     202 |     202 | 销售部    |
    |      6 | F        |   38 |     204 |    NULL | NULL      |
    +--------+----------+------+---------+---------+-----------+

 --(2)右外连接:在内连接的基础上增加右边有左边没有的结果 (右边表的数据全查出来,左边表满足条件的才查出来)

 select * from employee RIGHT JOIN department on employee.dept_id = department.dept_id;

        +--------+----------+------+---------+---------+-----------+
        | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
        +--------+----------+------+---------+---------+-----------+
        |      1 | A        |   19 |     200 |     200 | 人事部    |
        |      2 | B        |   26 |     201 |     201 | 技术部    |
        |      3 | C        |   30 |     201 |     201 | 技术部    |
        |      4 | D        |   24 |     202 |     202 | 销售部    |
        |      5 | E        |   20 |     200 |     200 | 人事部    |
        |   NULL | NULL     | NULL |    NULL |     203 | 财政部    |
        +--------+----------+------+---------+---------+-----------+

 --(3)全外连接:在内连接的基础上增加左边有右边没有的和右边有左边没有的结果

    -- mysql不支持全外连接 full JOIN
    -- mysql可以使用此种方式间接实现全外连接
    
   select * from employee RIGHT JOIN department on employee.dept_id = department.dept_id
   UNION
   select * from employee LEFT JOIN department on employee.dept_id = department.dept_id;

        

        +--------+----------+------+---------+---------+-----------+
        | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
        +--------+----------+------+---------+---------+-----------+
        |      1 | A        |   19 |     200 |     200 | 人事部    |
        |      2 | B        |   26 |     201 |     201 | 技术部    |
        |      3 | C        |   30 |     201 |     201 | 技术部    |
        |      4 | D        |   24 |     202 |     202 | 销售部    |
        |      5 | E        |   20 |     200 |     200 | 人事部    |
        |   NULL | NULL     | NULL |    NULL |     203 | 财政部    |
        |      6 | F        |   38 |     204 |    NULL | NULL      |
        +--------+----------+------+---------+---------+-----------+

      -- 注意 union与union all的区别:union会去掉相同的纪录
复制代码

4.自然连接 (不常用)

去除内联接的笛卡尔集,无需给出主外键等式,它会自动找到这一等式

要示:两张连接的表中列名称和类型完全一致做为条件(如学生表sid,成绩表也对应学生的sid) 注意两张表如有两个列以上名称及类型一致则必须两个列都一致了才会查询出来

Select * from stu natural join score;

 

多表查询之复合条件连接查询

复制代码
-- 查询员工年龄大于等于25岁的部门

    SELECT DISTINCT department.dept_name
    FROM employee,department
    WHERE employee.dept_id = department.dept_id
    AND age>25;


--以内连接的方式查询employee和department表,并且以age字段的升序方式显示

    select employee.emp_id,employee.emp_name,employee.age,department.dept_name
    from employee,department
    where employee.dept_id = department.dept_id
    order by age asc;
复制代码

多表查询之子查询

复制代码
-- 子查询是将一个查询语句嵌套在另一个查询语句中。
-- 内层查询语句的查询结果,可以为外层查询语句提供查询条件。
-- 子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
-- 还可以包含比较运算符:= 、 !=、> 、<等


-- 1. 带IN关键字的子查询

   ---查询employee表,但dept_id必须在department表中出现过

   select * from employee
            where dept_id IN
            (select dept_id from department);


+--------+----------+------+---------+
| emp_id | emp_name | age  | dept_id |
+--------+----------+------+---------+
|      1 | A        |   19 |     200 |
|      2 | B        |   26 |     201 |
|      3 | C        |   30 |     201 |
|      4 | D        |   24 |     202 |
|      5 | E        |   20 |     200 |
+--------+----------+------+---------+
5 rows in set (0.01 sec)



-- 2. 带比较运算符的子查询
      --      =、!=、>、>=、<、<=、<>

     -- 查询员工年龄大于等于25岁的部门
     select dept_id,dept_name from department
           where dept_id IN
          (select DISTINCT dept_id from employee where age>=25);

-- 3. 带EXISTS关键字的子查询

-- EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。
-- 而是返回一个真假值。Ture或False
-- 当返回Ture时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询

     select * from employee
              WHERE EXISTS
              (SELECT dept_name from department where dept_id=203);

      --department表中存在dept_id=203,Ture


     select * from employee
                WHERE EXISTS
              (SELECT dept_name from department where dept_id=205);

     -- Empty set (0.00 sec)


将t2表中的数据完全复制到新建的t1表中(会自己根据t2的表结构创建t1的表结构,但是没有主键、约束等信息)
create table t1(select * from t2);



子查询:一个seclect语句中包含另一个完整的select语句或两个以上select那么就是子查询语句了。

子查询出现的位置:where后,把select查询出的结果当做另一个select的条件值

From后,把查询出的结果当作一个新表

查询与项羽同一个部门员工(where 之后)

Select ename,deptno from emp where deptno = (Select deptno from emp where ename=’项羽’)

查询30号部门里薪水大于2000的

Select ename from

(Select ename,salary,deptno from emp where deptno =30)

Where salary > 2000;

查询工资高于程咬金的员工

Select ename,salary from emp where salary>

(Select salary from emp where ename =’程咬金);

查询工资高于30号部门最高人的员工信息

Select eanme,salary from emp where salary>

(Select max(salary) from emp where deptno =30)

查询工作和工资与妲己完全相同的员工信息

Select * from emp where (job,salary) in (select job,salary from emp where ename = ‘妲己’)

或者

Select * from emp e, (select job,salary from emp where ename=’妲己’) r

Where e.job =r.job and e.salary = r.salary;

有两个直接下属的员工信息

Select * from emp where empno in

(Select mgr,group_concat(mgr),count(mgr) from emp

Group by mgr having count(mgr) >=2);

查询编号为7788的员工名称、员工工资、部门名称、部门地址

Select e.ename,e.salary,d.dname,d.local from emp e ,dept d where e.deptno = d.deptno and e.empno =7788;

 

自连接(把自己当两张表,起别名)

求7369员工编号、姓名、经理编号和经理姓名

Select e1.empno,e1.ename,e2.empno,e2.ename from emp e1, emp e2

Where e1.mgr = e2.empno;

And e1.empno =7369;

 

事务:事务的操作只针对于DML (删除,修改,插入)

一、提交事务

Start transaction; (开始事务)

Update zs_account set money = money -2000; 

Update ls_account set money = money + 2000;

Commit;  (提交事务)

二、回滚事务

Start transaction; (开始事务)

Update zs_account set money = money -2000; 

Update ls_account set money = money + 2000;

roolback;  (回滚事务)

一、    事务的隔离级别

1、         read uncommitted 一个事务可以读取另一个未提交事务的数据

2、         read committe 一个事务要等另一个事务提交后才能读取数

3、         repeatable read (mysql 默认)

4、         serializable

查看事务隔离的级别

Select @@global.tx_isolation,@@tx_isolation;  (全局的,本地的)

修改事务隔离的级别

修改全局 set global transaction isolation level 隔离级别;

四、事务的并发处理

 

 

权限管理

创建用户 create user ‘用户名’@’localhost’ identified by ‘密码’;

删除用户 drop user ‘用户名’@’localhost’;

分配权限 grant 权限 (columns) on 数据库对象 to 用户 identified by “密码” with grant option

例:创建一个mkly用户为超级管理员,

Grant all privileges on *.* mylk@localhost identified by ‘1234’ whih grant option (*.*代表所有数据库中的所有表, grant option 指可以给其它用户分配权限)

例:创建对指定数据库的所有权限

Grant all privileges on 数据库名.* to 用户名@localhost identified by ‘1234’

查看权限 show grants;

查看指定用户的权限 show grants for root@localhost;

删除权限 revoke 权限 on 数据库对象 from 用户

 

视图

创建视图

Create view 视图名 as (select * from emp where salary >2000);

删除视图

Drop view 视图名

 

存储过程:一组可编程的函数,是为了完成特定功能的sql语句集

存储过程的参数有三种类型:in   out   inout 

In的示例

Out的示例

Inout的示例

自定义函数

通过存储过程构建一千万条数据

再执行:Call insert_emp10(1,10000000);

 

索引

Explain select * from emp where id=101;

 

索引的结构(btree索引:引擎为innodb  hash索引:引擎为memory)

以上是关于Mysql的主要内容,如果未能解决你的问题,请参考以下文章

从mysql的片段中加载ListView

连接MySQL出现错误:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)(代码片段

使用 json rereiver php mysql 在片段中填充列表视图

关于mysql驱动版本报错解决,Cause: com.mysql.jdbc.exceptions.jdbc4Unknown system variable ‘query_cache_size(代码片段

修改MySQL密码报错“ERROR 1819 (HY000): Your password does not satisfy the current policy requirements“(代码片段

mysql查看版本的四种方法