2 Star 0 Fork 2

jinzhengdong / mysql

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README.md 16.23 KB
一键复制 编辑 原始数据 按行查看 历史
jinzhengdong 提交于 2023-12-23 12:06 . .

开始

什么是数据库

  • 什么是数据库? 数据库是一个存储数据的集合,在这个集合中,数据以一定格式被存储以便数据能够被容易的访问。
  • 什么是数据库管理系统(DBMS)? 管理数据库的系统叫做数据库管理系统。

数据库分为:

  • 关系型数据库(Relational):以关系表的形式存储数据,并且以结构化查询语言来操纵数据(SQL, Structured Query Language),关系数据库管理系统(RDBMS)包括:MySQL,SQL Server,Oracle等。
  • 非关系型数据库(NoSQL)与关系型数据库非常的不同,需要单独的课程讲解,我们需要明白的仅是:NoSQL不理解SQL,他们有自己的查询语言。

安装MySQL

创建数据库

  • Windows下,完成MySQL安装后我们可以看到MySQL Workbench开发工具,启动并进入我们可以看到下面界面:
  • 上图,点击红框指示的按钮打开之前下载的数据库脚本,脚本打开后点击右侧面板的蓝框指示的执行按钮运行脚本完成数据库的创建
  • 完成数据库创建后,左侧面包将显示以下数据库设备:
    • sql_hr
    • sql_inventory
    • sql_invoicing
    • sql_store
  • 尝试使用并熟练该工具

学习内容介绍

我们首先要学习结构化查询语言最基本的四个子句,内容包括:

  • 查询数据(select)
  • 插入数据(insert)
  • 更新数据(update)
  • 删除数据(delete)

之后我们还要学习:

  • 汇总数据(summarizing data)
  • 编写复杂的查询
  • 学习内置函数(聚合函数)
  • 视图(Views)
  • 存储过程(Store Procedures)
  • 触发器(Triggers)
  • 事件(Events)
  • 事务(Transactions)
  • 并发(Concurrency)
  • 数据库设计
  • 索引及数据库性能
  • 数据库安全

单表查询

这一节讲述如何从单表查询数据,从MySQL Workbench来探查数据库,每个数据库都是一个容器,其中有很多数据对象:

  • 表(Tables)
    • 列(Columns),组成表的字段
    • 索引(Indexes),反映表中一列或多列的排序情况。
    • 外键(Foreign Keys),反映表间某种约定的关系。
    • 触发器(Triggers),在表中进行insert,update,delete前后可以调用相应的触发器进行数据处理。
  • 视图(Views),本质上就是查询
  • 存储过程(Stored Procedures)
  • 函数(Functions)

Select语句

--设置缺省数据库
use sql_store;

--查询语句形式一
select * from customers;

--查询语句形式二
select
  *
from
  customers
where
  customer_id = 1
order by
  first_name;

--select 常数
select 1, 2

select 子句

--查询指定表重的所有字段
select
  *
from
  customers;

--查询指定表重的指定字段
--查询的数学表达式支持及命名
select
  first_name,
  last_name,
  points,
  points + 10 as discount
from
  customers

-- distinct
select
  distinct state
from
  customers;

练习:

--返回products的所有行,其中字段列表包括:
--  name
--  unit_price
--  new_price => (unit_price * 1.1)

where 子句

select
  *
from
  customers
where
  points > 3000;

where子句支持以下比较操作符号:

  • ,大于

  • =,大于等于

  • <,小于
  • <=,小于等于
  • =,等于
  • !=,不等于
  • <>,不等于

再参看下面例子:

select
  *
from
  customers
where
  state = 'va';

select
  *
from
  customers
where
  birthdate > '1990-01-01';

练习:

--从orders表中返回2019年的数据

and or not 操作符

看下面例子:

select
  *
from
  customers
where
  birth_date > '1990-01-01' and points > 1000;

select
  *
from
  customers
where
  birth_date > '1990-01-01' or points > 1000;

select
  *
from
  customers
where
  birth_date > '1990-01-01' or 
  (points > 1000 and state = 'va');

select
  *
from
  customers
where not
  (birth_date <=> '1990-01-01' and points <=> 1000);

练习:

  • 从order_items获取订单号为6的,并且总价大于30的订单条目

in 操作符

select
  *
from
  customer
where state in ('va', 'fl', 'ga');

select
  *
from
  customer
where state not in ('va', 'fl', 'ga');

练习:

  • 从products中查询库存为49, 38, 72

between 操作符

select
  *
from
  customers
where
  pointss between 1000 and 3000;

练习:

  • 从customers中获取生日在1990-01-01和2000-01-01之间的顾客

like 操作符

查询中的通配符包括:

  • % 表示任何数字或字符
  • _ 表示单个字符
select
  *
from
  customers
where
  last_name like 'b%';

select
  *
from
  customers
where
  last_name like 'brush%';

select
  *
from
  customers
where
  last_name like '%b%';

select
  *
from
  customers
where
  last_name like '_____y';

select
  *
from
  customers
where
  last_name like 'b____y';

练习:

  • 从customers表中获取地址包含 trail 或 avenue;电话号码以9结束的顾客。

regexp 正则表达式操作符

--查询结果包含'field'
select
  *
from
  customers
where
  last_name regexp 'field';

--查询结果开始于'field'
select
  *
from
  customers
where
  last_name regexp '^field';

--查询结果以'field'结尾
select
  *
from
  customers
where
  last_name regexp 'field$';

--查询结果包含'field'或'mac'...
select
  *
from
  customers
where
  last_name regexp 'field$|mac|^rose';

--查询结果包含‘ge’,'ie', 'me'
select
  *
from
  customers
where
  last_name regexp '[gim]e';

select
  *
from
  customers
where
  last_name regexp '[a-h]e'

在正则表达式中:

  • ^表示开始
  • $表示结束
  • |表示逻辑或
  • [abcd]表示包含列表中的各字母
  • [a-f]表示包含按字母序a到f的各字母

练习:

  • customers表中查询
    • first_name包含elkaambur
    • last_nameeyon结尾
    • last_namemy开始或包含se
    • last_name包含b之后跟随字母ru

IsNull 操作符

本节演示如何查询字段值是null的情况,看下面例子:

--查询电话号码为空值的记录
select
  *
from
  customers
where
  phone is null;

--查询电话号码不为空值的记录
select
  *
from
  customers
where
  phone is not null;

练习:

  • orders表中获取那些没有被递送的记录

Order By 子句

本节演示order by排序子句,请看下面例子:

--first_name 正序排
select
  *
from
  customers
order by first_name;

--first_name正序排
select
  *
from
  customers
order by first_name asc;

--first_name倒序排
select
  *
from
  customers
order by first_name desc;

select
  *
from
  customers
order by state desc, first_name desc;

--1 => firstname, 2 => last_name
select
  first_name,
  last_name
from
  customers
order by 1, 2

练习:

  • 挑选一张表练习相关的排序操作

Limit 子句

查看下面的例子:

--查询头部的3条数据
select
  *
from
  customers
limit 3;

--查询结果按3条分一页进行分页,并显示第六页的数据
select
  *
from
  customers
limit 6, 3

练习:

  • 获取头三名忠诚的客户

多表查询

Inner Join

参看下面例子:

use sql_store;

select
	  o.order_id,
    o.customer_id,
    c.first_name,
    c.last_name
from
    orders o
    left outer join customers c on o.customer_id = c.customer_id
order by
    o.order_id;

跨数据库的Join

设置了缺省库时跨库的Join连接可用下面方式:

use sql_store;

select
    *
from
    order_items oi
    left outer join sql_inventory.products p on oi.product_id = p.product_id;

或者使用下面的查询语句则不需要指定缺省的数据库设备:

select
    *
from
    sql_store.order_items oi
    left outer join sql_inventory.products p on oi.product_id = p.product_id;

自引用 Self Join

查看employees表结构,我们发现reports_to字段指向表中的employee_id,那位3720雇员就是组织机构的管理员:

use sql_hr;
select
    e.employee_id,
    e.first_name,
    m.first_name as manager
from
    employees e
left outer join employees m on e.reports_to = m.employee_id

多表Join

看下面的例子:

use sql_store;

select
    o.order_id,
    o.order_date,
    c.first_name,
    c.last_name,
    os.name as status
from
    orders o
left outer join customers c using(customer_id)
left outer join order_statuses os on o.status = os.order_status_id

再看另一例子:

use sql_invoicing;

select
    p.date,
    p.invoice_id,
    p.amount,
    c.name as client,
    pm.name as payment_method
from
    payments p
left outer join clients c using(client_id)
left outer join payment_methods pm on p.payment_method = pm.payment_method_id

组合Join

use sql_store;
select
    *
from
    order_items oi
join order_item_notes oin 
    on oi.order_Id = oin.order_Id and oi.product_id = oin.product_id;

非直言join

use sql_store;
select
    *
from
    orders o, customers c
where
    o.customer_id = c.customer_id

Outer Join

缺省情况,所有的join都是inner join,我没看下面的例子:

Inner Join:

use sql_store;
select
    c.customer_id,
    c.first_name,
    o.order_id
from
    customers c
join
    orders o using(customer_id)
order by
    c.customer_id;

Outer Join:

use sql_store;
select
    c.customer_id,
    c.first_name,
    o.order_id
from
    customers c
left outer join
    orders o using(customer_id)
order by
    c.customer_id
  • 以上两个Join查询,left join将显示所有来自customers表中的记录
  • 如果使用right outer join则所有来自orders表中记录将被显示

多表间的 outer join

下面的查询显示inner join的查结果:

select
    c.customer_id,
    c.first_name,
    o.order_id
from
    customers c
join orders o using(customer_id)
order by
    c.customer_id

下面则是left outer join的查询结果:

select
    c.customer_id,
    c.first_name,
    o.order_id
from
    customers c
left outer join orders o using(customer_id)
order by
    c.customer_id

下面的例子shippers是inner join:

select
    c.customer_id,
    c.first_name,
    o.order_id
from
    customers c
left outer join orders o using(customer_id)
join shippers sh using(shipper_id)
order by
    c.customer_id

下面例子,如果全采用left outer join则如下:

select
    c.customer_id,
    c.first_name,
    o.order_id,
    sh.name as shipper
from
    customers c
left outer join orders o using(customer_id)
left outer join shippers sh using(shipper_id)
order by
    c.customer_id

练习:

  • 看下面的inner join例子:
select
    o.order_id,
    o.order_date,
    c.first_name as customer,
    sh.name as shipper
from
    orders o
join customers c using(customer_id)
join shippers sh using(shipper_id)

看下面outer join 的例子:

select
    o.order_id,
    o.order_date,
    c.first_name as customer,
    sh.name as shipper,
    os.name as status
from
    orders o
join customers c using(customer_id)
left join shippers sh using(shipper_id)
join order_statuses os on o.status = os.order_status_id

Self Outer Joins

看下面例子使用inner join:

use sql_hr;

select
    e.employee_id,
    e.first_name,
    m.first_name as manager
from
    employees e
join
    employees m on e.reports_to = m.employee_id

下面的例子使用left outer join

use sql_hr;

select
    e.employee_id,
    e.first_name,
    m.first_name as manager
from
    employees e
left outer join
    employees m on e.reports_to = m.employee_id

上面例子拿掉outer后仍然是left outer join:

use sql_hr;

select
    e.employee_id,
    e.first_name,
    m.first_name as manager
from
    employees e
left join
    employees m on e.reports_to = m.employee_id

注意:

  • MySQL查询中join通常指left inner join;而left join通常指left outer join

Using子句

  • 请考察下面的例子, join连接时两张表的关联字段完全一样:
use sql_store;

select
    o.order_id,
    c.first_name
from
    orders o
join customers c
    on o.customer_id = c.customer_id
  • 如果关联表的关联字段完全一样则可以使用using子句来描述关联字段,如下:
use sql_store;

select
    o.order_id,
    c.first_name
from
    orders o
join customers c
    using (customer_id)
  • 同样的方式我们可以关联其他表如下:
use sql_store;

select
    o.order_id,
    c.first_name,
    sh.name as shipper
from
    orders o
join customers c
    using (customer_id)
join shippers sh
    using (shipper_id)
  • 如果我们使用left outer join连接shippers如下:
use sql_store;

select
    o.order_id,
    c.first_name,
    sh.name as shipper
from
    orders o
join customers c
    using (customer_id)
left join shippers sh
    using (shipper_id)
  • 最后,请考察下面复合关联的例子:
use sql_store;

select
    *
from
    order_items oi
join
    order_item_notes oin
        on oi.order_id = oin.order_id and
            oi.product_id = oin.product_id
  • 对于上面的例子,我们可以按下面方式使用using进行简化:
use sql_store;

select
    *
from
    order_items oi
join
    order_item_notes oin
        using (order_id, product_id)

练习下面查询:

use sql_invoicing;

select
    p.date,
    c.name as client,
    p.amount,
    pm.name as payment_method
from
    payments p
join clients c using (client_id)
join payment_methods pm
    on p.payment_method = pm.payment_method_id

natural join

参看下面的例子,我们使用natural join后并未指定连接的关联字段:

use sql_store;

select
    o.order_id,
    c.first_name
from
    orders o
natural join customers c

注意:

在使用natural join后查询会使用两表中共同的字段customer_id进行关联,这种方式并不常用。

交叉关联 Cross Joins

查看下面例子,执行交叉连接是,第一张表的记录会逐条与第二张表的记录进行迭代,因此,不需要指定关联条件:

use sql_store;

select
    c.first_name as customer,
    p.name as product
from
    customers c
cross join products p
order by c.first_name

交叉关联也可用下面的语句表示:

use sql_store;

select
    c.first_name as customer,
    p.name as product
from
    customers c,
    products p
order by c.first_name

联合 Unions

查看下面联合查询的例子:

use sql_store;

select
    order_id,
    order_date,
    'Active' as status
from
    orders
where
    order_date >= '2019-01-01'
    
union

select
    order_id,
    order_date,
    'Archived' as status
from
    orders
where
    order_date < '2019-01-01'

插入、更新及删除数据

列属性(字段属性)

我们考察一张表,一张表由多个字段组成,而每个字段又包含以下属性:

  • 字段名(column name),例如:customer_id, first_name
  • 字段的数据类型(Datatype),例如:int, varchar
  • 约束条件及索引:
    • PK, Primary Key
    • NN, Not Null
    • UQ, Unique
    • BIN, Binary
    • UN, Unsigned Data Type
    • ZF, for numeric column, it will be filled with zero
    • AI, Auto Incremental
    • G, Generated Column
    • Default/Expression, default value or expression

插入行

如果没有指定插入的字段列表,则请按表的字段顺序填写相关的插入值,如下:

insert into customers
values (
	  200,
    'Jerry',
    'Smith',
    '1968-08-20',
    '13888000000',
    '470# Bailong RD, Kunming, Yunnan, China',
    'KM',
    'YN',
    1000
);

我们也可以提供插入的字段列表如下:

insert into customers (
	  customer_id,
    first_name,
    last_name,
    birth_date,
    phone,
    address,
    city,
    state,
    points
)
values (
	  200,
    'Jerry',
    'Smith',
    '1968-08-20',
    '13888000000',
    '470# Bailong RD, Kunming, Yunnan, China',
    'KM',
    'YN',
    1000
);
SQL
1
https://gitee.com/jinzhengdong/mysql.git
git@gitee.com:jinzhengdong/mysql.git
jinzhengdong
mysql
mysql
master

搜索帮助