当前位置:网站首页>MySql必知必会学习

MySql必知必会学习

2022-07-06 11:35:00 瀛台夜雪

MySql必知必会学习

配置MySql

安装mysql服务

sudo apt update
sudo apt install mysql-server

查看MySQL是否安装成功

sudo systemctl status mysql

设置MySQL的登录密码

sudo mysql

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password by 'mynewpassword';

exit;

sudo mysql_secure_installation

加载《MySQL必知必会》的例程

加载进入mysql

mysql -uroot -p

创建数据库

create database myMysql;

导入例程

use myMysql;
source +create.sql的地址
source +populate.sql 的地址

安装mysql-workbench

在官网中选择对应的版本的mysql-workbeach,安装包下载地址如下:https://dev.mysql.com/downloads/workbench/

sudo dpkg -i mysql-workbench-community_8.0.29-1ubuntu20.04_amd64.deb

若出现报错,则执行

sudo apt -f install

执行完毕后再执行第一条指令

PART4检索数据

———SELECT语句进行检索一个或多个数据列

SELECT语句必须包含

  • 想要选择的列名
  • 从那张表中进行选择

检索单个列

SELECT prod_name FROM products;

注意事项:

多条SQL语句必须以分号;分割

SQL虽然不区分大小写,但是在日常使用过程中需要多所有SQL关键字使用大写,而对所有列和表明使用小写。

SQL会自动忽略空格,SQL命令可以在一行中给出也可以在多行中给出

检索多个列

SELECT prod_id,prod_name,prod_price FROM products;

检索所有列

SELECT * FROM products;

检索不同行(无重复的值)

DISTINCT关键字:指示MySQL只返回不同的值

SELECT DISTINCT vend_id FROM myMysql.products;

当使用DISTINCT关键字的时候其应用于选定的表的所有列而不是前置它的列

限制检索的结果

SELECT prod_name FROM products LIMIT 3,4;
SELECT prod_name FROM products LIMIT 5;

使用关键字LIMIT对输出的行数进行限制

当两个参数的时候第一个起始位置,默认从0开始计数,第二个参数为要获取的行数

只有一个参数的时候则默认从0开始到第j行

PART5排序检索数据

仅使用SQL语句返回数据库表中的单个列。若不制定排序的顺序,则数据一般以它在底层表中出现的顺序显示。该顺序可以为数据最初被添加到表中的顺序,或者收到MySQL重用回收存储空间的影响。

为了对SELECT语句检索出的数据进行明确的排序,可以使用ORDER BY子句。

ORDER BY子句取一个或多个列的名字,据此对输出进行排序

子句==一个关键字+所提供的数据组成

使用ORDER BY子句默认是用升序排列

排序数据

SELECT prod_name FROM products ORDER BY prod_name;
SELECT prod_name FROM products ORDER BY prod_price;

所选择的列可以使用显示所选择的列,也可以使用未检索的列排序数据

按多个列排序

为了按多个列排序,只需要指定列名,列名之间用逗号分开即可。

mysql> SELECT
    -> prod_id,prod_price,prod_name
    -> FROM products
    -> ORDER BY
    -> prod_price,prod_name;

指定排序方向

使用ORDER BY进行数据排序,是以 升序排序作为默认排序顺序。以DESC 指定降序操作

mysql> SELECT
    -> prod_id,prod_price,prod_name
    -> FROM products
    -> ORDER BY
    -> prod_price DESC;

对多个列进行排序

SELECT prod_id,prod_price,prod_name FROM myMysql.products order by prod_price desc,prod_name desc;

如果要在多个列上进行降序操作,必须对每个列指定DESC关键字

利用ORDER BY 和LIMIT的组合,能够找出一个列中最高或最低的值,但需要注意LIMIT必须在ORDER BY的后面

select prod_id,prod_price,prod_name from myMysql.products order by prod_price desc limit 1;

PART6过滤数据

搜索条件(过滤条件):只检索所需数据需要指定搜索条件

SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。WHERE子句在表名(FROM子句)之后给出

select prod_name ,prod_price
from myMysql.products
where prod_price=2.50;

WHERE 子句和ORDER BY子句同时使用时,应该让ORDER BY位于WHERE之后

MySQL在执行匹配时默认不区分大小写

IS NULL子句可用来默认检查具有NULL值的列

select cust_id 
from myMysql.customers
where cust_email is null;

PART7数据过滤

MySQL允许给出多个WHERE子句。这些子句以两种方式使用,以AND子句的方式或OR子句的方式

操作符(逻辑操作符):用以联结或改变WHERE子句中的子句的关键字。

select prod_id,prod_price,prod_name
from myMysql.products
where vend_id=1003 and prod_price<10;

AND:用在WHERE子句中 的关键字,用来指示检索满足所有给定条件的行

OR: 指示MySQL检索匹配任一条件

由于SQL在处理OR操作符前,会有限处理AND字符。因此要使用圆括号明确地分组相应的操作符

IN: 用来指定条件范围,范围中的每个条件都可以进行匹配。IN取合法值的由逗号分隔的清单,全部括在圆括号中

select prod_id,prod_price,prod_name
from myMysql.products
where vend_id in (1002,1003) 
order by prod_name;

IN WHERE子句中用来指定要匹配值的清单的关键字,功能与OR相当

NOT :否定它之后所跟的任何条件

select prod_id,prod_price,prod_name
from myMysql.products
where vend_id not in (1002,1003) 
order by prod_name;

PART8用通配符进行过滤

之前的操作符都是针对已知值进行过滤。但这种方法并不是任何的时候都是好用的。利用通配符可以创建比较特定数据的搜索模式。

通配符:用来匹配值的一部分的特殊字符

搜索模式:由字面值、通配符或两者组合构成的搜索条件。

在使用通配符时,必须使用LIKE操作符。LIKE指示MySQL,后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较。LIKE是谓词。

百分号%通配符

%表示任何字符出现任意次数

select prod_id,prod_name
from myMysql.products
where prod_name like 'jet%';

通配符可在搜索模式中任意位置使用,并且可以使用多个通配符

select prod_id,prod_name
from myMysql.products
where prod_name like '%anvil%';

通配符也可以出现搜索模式的中间

select prod_id,prod_name
from myMysql.products
where prod_name like 'j%k%';

使用通配符时尾空格可能会干扰通配符匹配,因此可以在搜索模式最后附加一个%,或者使用函数

通配符无法匹配NULL

下划线_通配符

下划线通配符只匹配单个字符而不是多个字符

select prod_id,prod_name
from myMysql.products
where prod_name like '_ ton anvil';

PART9用正则表达式进行搜索

正则表达式是用来匹配文本的特定的串(字符集合)

MySQL用WHERE子句对正则表达式提供了初步支持,允许你指定正则表达式,过滤SELECT检索出的数据。

基本正则表达式

REGEXP后所跟的东西作为正则表达式处理

select prod_id,prod_name
from myMysql.products
where prod_name regexp '1000'
order by prod_name;

.表示匹配任意一个字符

与LIKE进行比较

LIKE匹配整个列。如果被匹配的文本在列值中出现,LIKE将不会找到它,相应的行也不被返回(除非使用通配符)

REGEXP在列值内进行匹配,如果被匹配的文本在列值中出现,REGEXP将找到它,相应的行将被返回

select prod_id,prod_name
from myMysql.products
where prod_name like '1000'
order by prod_name;


select prod_id,prod_name
from myMysql.products
where prod_name regexp '1000'
order by prod_name;

进行OR匹配

多个OR条件可以合并入一个正则表达式

select prod_id,prod_name
from myMysql.products
where prod_name regexp '1000|2000'
order by prod_name;

匹配几个字符之一

可以使用一组用[和]括起来的字符来完成, []是另一种形式的OR语句

select prod_id,prod_name
from myMysql.products
where prod_name regexp '[123] Ton'
order by prod_name;

字符集合可以被否定,他们将匹配除指定字符外的任何东西。为否定一个字符集,在集合的开始处放置一个^即可

匹配范围

可以使用-定义一个范围

select prod_id,prod_name
from myMysql.products
where prod_name regexp '[1-4] Ton'
order by prod_name;

匹配特殊字符

为了匹配特殊字符,必须用\ \ 为前导。 \ \ -表示查找-,\ \ .表示查找.

select prod_id,prod_name
from myMysql.products
where prod_name regexp '\\.'
order by prod_name;

在字符串匹配的过程中,可以使用预定义的字符串,称为字符串类

匹配多个实例

select prod_id,prod_name
from myMysql.products
where prod_name regexp '\\([0-9] sticks?\\)'
order by prod_name;
select prod_id,prod_name
from myMysql.products
where prod_name regexp '[[:digit:]]{4}'
order by prod_name;

定位符

匹配特定位置的文本,使用定位符

select prod_id,prod_name
from myMysql.products
where prod_name regexp '^[0-9\\.]'
order by prod_name;

^有两种用法,在集合中,用它来否定该集合,否则,用来指串的开始处。

PART10创建计算字段

计算字段并不实际存在于数据库中。计算字段是运行时在SELECT语句内创建的

字段:意思与列相同,在数据库列一般称为列,而术语字段通常用在计算字段的连接上

只有数据库知道SELECT语句中那些列是实际的表列,那些列是计算字段。从客户机(应用程序)的角度来看,计算字段的数据是以与其他列的数据相同的方式返回的

拼接字段

拼接:将值联结在一起构成单个值

MySQL的SELECT语句中,可使用Concat()函数来拼接两个列

Concat():把多个串连接起来形成一个较长的串

Concat()需要一个或多个指定的串,各个串之间用逗号分割

select concat(vend_name,'(',vend_country,')')
from myMysql.vendors
order by vend_name;

使用RTrim()函数可以删除数据右侧多余的空格来整理数据

select concat(rtrim(vend_name),'(',rtrim(vend_country),')')
from myMysql.vendors
order by vend_name;

LTrim()去掉串左边的空格

Trim()去掉串左右两边的空格

使用别名

别名:是一个字段或值的替换名。别名用AS关键字赋予

select concat(rtrim(vend_name),'(',rtrim(vend_country),')') as vender_title
from myMysql.vendors
order by vend_name;

执行算术计算

可以对检索出的数据进行简单的算术计算

select prod_id,quantity,item_price,
	quantity*item_price as expanded_price
from myMysql.orderitems
where order_num=20005;

PART11使用数据处理函数

函数一般在数据上执行,其给数据的转换和处理提供了方便

根据函数的功能可以分为

  • 文本处理函数
  • 日期处理函数
  • 数值处理函数
select vend_name,upper(vend_name)as vend_name_upper
from myMysql.vendors
order by vend_name;
select cust_name,cust_contact
from myMysql.customers
where soundex(cust_contact)=soundex('y. lie');
select cust_id,order_num
from myMysql.orders
where date(order_date)='2005-09-01';
select cust_id,order_num,order_date
from myMysql.orders
where date(order_date) between '2005-09-01' and '2005-09-30';

select cust_id,order_num,order_date
from myMysql.orders
where year(order_date)=2005 and month(order_date)=9;
select cust_id,order_num,order_date,mod(order_num,3)as modValue
from myMysql.orders
where year(order_date)=2005 and month(order_date)=9;

PART12汇总数据

聚焦函数:运行在行组上,计算和返回单个值的函数

AVG函数

AVG()通过对表中行数计数并计算特定列值纸盒,求得该列的平均值。AVG()可用来返回所有列的平均值,也可以返回指定列或行的平均值

  • AVG()只能用来确定特定数值列的平均值,而且列名必须作为函数参数给出
  • 为了获得多个列的平均值,必须使用多个AVG()函数
  • AVG()函数忽略列值为NULL的行
select avg(prod_price) as avg_price
from myMysql.products;
select avg(prod_price) as avg_price
from myMysql.products
where vend_id=1003;

COUNT函数

coun()确定表中行的数目或符合特定条件的行的数目

  • count(*)对表中行的数目进行计数,不管表列中包含的是控制(NULL)还是非空值
  • 使用count(column)对特定列中具有值的行进行计数,忽略NULL值
select count(*) as count_num
from myMysql.products;
select count(vend_id) as count_num
from myMysql.products;

MAX函数

  • max()返回指定列中的最大值
  • 应用在文本数据时,如果数据按相应的列排序,则MAX()返回最后一行
  • MAX()函数忽略列值为NULL的行
select max(vend_id) as max_num
from myMysql.products;

MIN函数

  • 返回指定列的最小值
  • 应用在文本数据时,如果数据按相应的列排序,则MIN()返回最前面的行
  • 忽略列值为NULL的行
select min(prod_name) as max_num
from myMysql.products;

SUM函数

  • 用来返回指定列值的和
  • 也可以用来合计计算值
  • 忽略列值为NULL的行
select sum(quantity) as items_ordered
from myMysql.orderitems
where order_num=20005;
select sum(quantity*item_price) as total_price
from myMysql.orderitems
where order_num=20005;

聚类不同值

  • 对所有的行执行计算,指定ALL参数或者不给参数(因为ALL是默认行为)
  • 只包含不同的值,指定DISTINCT参数
select avg(distinct prod_price) as avg_price
from myMysql.products
where vend_id=1003;

如果指定列名,则distinct只能用于count()。distinct不能用于count(*)

组合聚类函数

SELECT语句可以根据需要包含多个聚焦函数

select avg(distinct prod_price) as avg_price,
		count(*) as num_items,
        min(prod_price)as price_min,
        max(prod_price)as price_max,
        avg(prod_price)as price_avg,
        sum(prod_price)as price_sum
        
from myMysql.products;

PART13分组数据

分组:允许把数据分为多个逻辑组,以便能对每个组进行聚类计算

分组是在SELECT语句的GROUP BY子句建立的

select vend_id,count(*)as num_prods
from myMysql.products
group by vend_id;

使用GROUP By, 就不必指定要计算和估值的每个组了。系统会自动完成。GROUP BY子句指示MySQL分组数据,然后对每个组而不是整个结果集进行聚集。

过滤分组

MySQL允许过滤分组,规定包括那些分组,排除那些分组。其必须基于完整的分组而不是个别的行进行过滤。

HAVING子句,可以用来替代WHERE子句,唯一的区别在于,WHERE过滤行,HAVING过滤分组

select vend_id,count(*)as num_prods
from myMysql.products
group by vend_id
having count(*)>2;

过滤是基于分组聚集值而不是特定行值的

WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。WHERE排除的行不包括在分组中,这可能会改变计算值,从而影响HAVING子句中基于这些值过滤掉的分组

WHERE和HAVING子句的结合使用

select vend_id,count(*)as num_prods
from myMysql.products
where prod_price>=10
group by vend_id
having count(*)>=2;

先执行where子句过滤掉所有的prod_price至少为10的行,然后再执行分组和过滤

在使用GROUP BY子句时,也应该给出ORDER BY子句,这是保证数据正确排序的唯一方法。

select order_num,sum(quantity*item_price)as ordertoal
from myMysql.orderitems
group by order_num
having sum(quantity*item_price)>=50;
select order_num,sum(quantity*item_price)as ordertoal
from myMysql.orderitems
group by order_num
having sum(quantity*item_price)>=50
order by ordertoal;

PART14使用子查询

查询,任何SQL语句都是查询操作。

子查询,嵌套在其他查询中的查询

子查询可以将多个查询组合成一条语句。其具有两种方式

  1. 利用子查询进行过滤
  2. 将子查询作为计算字段来使用
select order_num
from myMysql.orderitems
where prod_id='TNT2';


select cust_id
from myMysql.orders
where order_num in (20005,20007);

select cust_name,cust_contact
from myMysql.customers
where cust_id in (10001,10004);


#使用子查询进行的操作
select cust_name,cust_contact
from myMysql.customers
where cust_id in(
	select cust_id
	from myMysql.orders
	where order_num in (
		select order_num
		from myMysql.orderitems
		where prod_id='TNT2'
	)
);

在实际使用过程中,由于计算机本身性能的限制,因此不能嵌套太多的子查询

select cust_name,cust_state,
(select count(*)
from myMysql.orders
where orders.cust_id=customers.cust_id)as orders
from myMysql.customers
order by cust_name;

相关子查询:涉及外部查询的子查询

任何时候当列名可能存在有多义性,就必须使用这种语法(表名和列名由一个句点分隔)

PART15联结表

SQL最强大的功能之一就是能够在数据检索查询的执行中使用联结表

关系表的设计就是要保证把信息分解成多个表,一类数据一个表。各表通过某些常用的值(即关系设计中的关系)互相关联

外键:外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系

  • 信息不会重复,从而并不会浪费空间和时间
  • 当数据出现变动时,只需要更改单个记录就可以
  • 数据处理变得更加简单

可伸缩性,能够适应不断增加的工作量而不失败。设计良好的数据库或应用程序称之为可伸缩性好

关系数据可以有效存储和方便地处理,因此关系数据库的可伸缩性比非关系数据库要好

当数据存储在多个表中,怎样用单条SELECT语句检索出数据?

->使用联结。联结是一种机制,用来在一条SELECT语句中关联表,因此称之为联结。使用特殊的语法,可以联结多个表返回一组输出,联结在运行时关联表中正确的行

联结,不是物理实体,其在实际的数据库表中并不存在,联结由MySQL根据需要建立,它存在于查询的执行当中

select vend_name,prod_name,prod_price
from myMysql.vendors,myMysql.products
where vendors.vend_id=products.vend_id
order by vend_name,prod_name;

引用的列可能出现二义性,必须使用完全限定列名(用一个点分隔的表名和列名)

在一条SELECT语句中联结几个表时,相应的关系是在运行中构造的。在数据库表的定义中不存在能指示MySQL如何对表进行联结的东西

笛卡尔积(叉联结):由没有联结条件的表关系返回的结果为笛卡尔积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数

使用内部联结的方式

select vend_name,prod_name,prod_price
from vendors inner join products
on vendors.vend_id=products.vend_id
order by vend_name,prod_name;

联结多个表

select vend_name,prod_name,prod_price,quantity
from myMysql.vendors,myMysql.products,myMysql.orderitems
where products.vend_id=vendors.vend_id
	and orderitems.prod_id=products.prod_id
    and orderitems.order_num=20005
order by vend_name,prod_name;
select cust_name,cust_contact
from myMysql.customers
where cust_id in(
	select cust_id
	from myMysql.orders
	where order_num in (
		select order_num
		from myMysql.orderitems
		where prod_id='TNT2'
	)
);


select cust_name,cust_contact
from customers,orders,orderitems
where customers.cust_id=orders.cust_id
	and orders.order_num=orderitems.order_num
    and prod_id='TNT2';

PART16 创建高级联结

别名除了用于列名和计算字段外,SQL还允许给表名起别名,其可以

  • 缩短SQL语句
  • 允许在单条SELECT语句中多次使用相同的表
select cust_name,cust_contact
from customers as c,orders as o,orderitems as oi
where c.cust_id=o.cust_id
	and o.order_num=oi.order_num
    and oi.prod_id='TNT2';

表别名不仅能用于where子句,还可以用于select的列车,order by子句以及语句的其他部分。

表别名只在查询执行中使用。与列别名不一样,表别名不返回到客户机

自联结

select cust_name,cust_contact
from customers,orders,orderitems
where customers.cust_id=orders.cust_id
	and orders.order_num=orderitems.order_num
    and prod_id='TNT2';

select cust_name,cust_contact
from customers as c,orders as o,orderitems as oi
where c.cust_id=o.cust_id
	and o.order_num=oi.order_num
    and oi.prod_id='TNT2';

自联结通常作为外部语句用来替代从相同表中检索数据时使用的子查询语句。虽然最终的结果是相同的,但有时处理联结远比处理子查询快得多

自然联结

自然联结排除多次出现,使每个列只返回一次。通过对表使用通配符(SELECT *),对所有其他表的列使用明确的子集完成

select c.*,o.order_num,o.order_date,oi.prod_id,oi.quantity,oi.item_price
from customers as c,orders as o,orderitems as oi
where c.cust_id=o.cust_id
	and oi.order_num=o.order_num
    and prod_id='FB';

外部联结

联结包含了那些在相关表中没有关联行的行,这种类型的联结称为外部联结

select customers.cust_id,orders.order_num
from customers inner join orders
on customers.cust_id=orders.cust_id;

select customers.cust_id,orders.order_num
from customers left outer join orders
on customers.cust_id=orders.cust_id;

select customers.cust_id,orders.order_num
from customers right outer join orders
on orders.cust_id=customers.cust_id;

在使用outer join语法时,必须使用right或者left关键字指定包括其所有行的表,right指出outer join 右边的表,而left指出的是outer join 左边的表

左外部联结与右外部联结,他们之间的唯一区别是所关联的表的顺序不同。左外部联结可通过颠倒from或where子句中表的顺序转换为右外部联结。因此两种类型的外部联结可以互相使用

使用带聚集函数的联结

select customers.cust_name,customers.cust_id,
	count(orders.order_num)as num_ord
from customers inner join orders
on customers.cust_id=orders.cust_id
group by customers.cust_id;

select customers.cust_name,customers.cust_id,
	count(orders.order_num)as num_ord
from customers left outer  join orders
on customers.cust_id=orders.cust_id
group by customers.cust_id;

联结的注意事项

  • 注意所提供的联结类型,一般使用内部联结,但使用外部联结也需要是有效的
  • 保证使用正确的联结条件,否则将返回不正确的数据
  • 应该总是提供联结条件,否则会得出笛卡尔积
  • 在一个联结中可以包含多个表,甚至对于每个联结可以采用不同的联结类型。

PART17组合查询

MySQL允许执行多个查询(多条SELECT语句),并将结果作为单个查询结果集进行返回。这些查询通常被称为并或复合查询操作

  • 在单个查询中从不同的表返回类似结构的数据
  • 对单个表执行多个查询,按单个查询返回数据

多数情况下,组合相同表的两个查询完成的工作与具有对个where子句条件的单条查询完成的工作相同。即,任何具有多个where子句的SELECT语句都可以作为一个组合查询给出

可以使用UNION操作符来组合数条SQL查询。利用UNION,可给出多条SELECT语句,将他们的结果组合成单个结果集

select vend_id,prod_id,prod_price
from products
where prod_price<=5
union
select vend_id,prod_id,prod_price
from products
where vend_id in(1001,1002);
  • union必须由两条或两条以上的select语句组成,语句之间用关联词union分隔
  • union中的每个查询必须包含相同的列、表达式或聚集函数
  • 列数据必须兼容

union从查询结果集中自动去除了重复的行,这是union的默认行为,如果想返回所有匹配的行,可使用union all

select vend_id,prod_id,prod_price
from products
where prod_price<=5
union all
select vend_id,prod_id,prod_price
from products
where vend_id in(1001,1002);

union all为union的一种形式,它完成where子句完成不了的工作。如果确实需要每条记录的匹配行全部出现(包括 重复行),则必须使用union all,而不能用where

在使用union组合查询时,只能使用一条order by子句,其必须出现在最后一条select语句之后,不允许使用多条 order by 子句

select vend_id,prod_id,prod_price
from products
where prod_price<=5
union all
select vend_id,prod_id,prod_price
from products
where vend_id in(1001,1002)
order by vend_id,prod_price;

PART18 全文本搜索

在使用全文本搜索时,MySQL不需要分别查看每个行,不需要分别分析和处理每个词。MySQL创建指定列中各词的一个索引,搜索可以针对这些词进行。这样MySQL可以快速有效地决定哪些词匹配,哪些词不匹配,他们的匹配的频率

使用全文本搜索,必须索引被搜索的列,而且要随着数据的改变不断地重新索引。在对表进行适当设计后,MySQL会自动进行所有的索引和重新索引。在索引之后,SELECT可与Match()和Against()一起使用以实际执行搜索

启用全文本搜索支持

一般在创建表时启用全文本搜索。CREATE TABLE语句接受FULLTEXT子句,它给出被索引值的一个逗号分隔的列表

create table  mydata
(	
	note_id int not null auto_increment,
    prod_id char(10) not null,
    noe_data datetime not null,
    note_text text null,
    primary key(note_id),
    fulltext(note_text)
)engine=MyISAM;

为了进行全文本搜索,MySQL根据子句FULLTEXT(note_text)的指示对它进行索引。FULLTEXT索引单个列,如果需要也可以指定多个列

在定义之后,MySQL自动维护该索引。在增加、更新或删除行是,索引随之自动更新。

可以在创建表时指定FULLTEXT,或者在稍后指定
如果正在调入数据到一个新表,应该首先导入所有数据,然后再修改表,定义FULLTEXT,这样有助于更快地导入数据。

进行全文本搜索

Match()指定被搜索的列,Against()指定要使用的搜索表达式。

select note_text
from productnotes
where match(note_text) against('rabbit');
  • 传递给Match()的值必须与FULLTEXT()定义中的相同。如果指定多个列,则必须列出他们
  • 搜索不区分大小写

用like语句可完成类似的操作

select note_text
from productnotes
where note_text like '%rabbit%';

使用like以不特别有用的顺序返回数据,使用全文本搜索返回以文本匹配的良好程度排序的数据

全文本搜索的一个重要部分就是对结果排序。具有较高登记的行先返回。

select note_text,match(note_text) against('rabbit') as ranks 
from productnotes;

排序的等级是mySQL根据行中词的数目、唯一词的数目、整个索引中词的总数以及包含该词的行的数目计算出来

当指定多个搜索项时,包含多数匹配词的那些行将具有比包含较少词(或仅有一个匹配)的那些行高的等级值

使用查询扩展

查询扩展用来设法放宽所返回的全文本搜索结果的范围。在使用查询扩展时,MySQL对数据和索引进行两遍扫描来完成搜索

  • 首先,进行一个基本的全文本搜索,找出与搜索条件匹配的所有行
  • 其次,MySQL检查这些匹配行并选择所有有用的词
  • 再其次,MySQL再次进行全文本搜索,此次不仅使用原来的条年间,而且还使用所有有用的词

利用查询扩展,能找出可能相关的结果,即使他们并不精确包含所查找的词。

select note_text
from productnotes
where match(note_text) against('anvils' with query expansion);

查询扩展极大地增加了返回的行数,但这样也增加了实际上不需要的行的数目。表中的行越多,代表使用查询扩展返回的结果越好。

使用布尔搜索

布尔方式可提供

  • 要匹配的词
  • 要排斥的词
  • 排列提示
  • 表达式分组
  • 另外一些内容

布尔方式即使没有定义FULLTEXT索引,也可以使用它。

select note_text
from productnotes
where match(note_text) against('heavy' in boolean mode);
select note_text
from productnotes
where match(note_text) against('heavy -rope*' in boolean mode);

-排除一个词,*截断操作(可想象为用于词尾的一个通配符)

select note_text
from productnotes
where match(note_text) against('+rabbit +bait' in boolean mode);

+包含,词必须存在

select note_text
from productnotes
where match(note_text) against('rabbit bait' in boolean mode);

未指定操作符,则只要存在一个便可以了

select note_text
from productnotes
where match(note_text) against('"rabbit bait"' in boolean mode);

匹配双引号内的短语,而非词

select note_text
from productnotes
where match(note_text) against('>rabbit <carrot' in boolean mode);

增加前者的等级,降低后者的等级

select note_text
from productnotes
where match(note_text) against('+safe +(<combination)' in boolean mode);
  • 在索引全文本数据时,短词被忽略且从索引中排除。短词定义为那些具有3个或3个一下字符的词

  • MySQL带有一个内建的非用词列表,这些词在索引全文本数据时总是被忽略。如果需要,可以覆盖这个列表

  • 当许多词出现的频率很高,搜索他们没有用处。MySQL规定了一条50%规则,如果一个词出现在50%以上的行中,则将它看成一个非常用词忽略。50%规则不用于in boolearn

  • 如果表中的行数少于3行,则全文本搜索不返回结果

  • 忽略词中的单引号

  • 不具有词分隔符的语言不能恰当地返回全文本搜索结果

PART19插入数据

insert用来插入(或添加)行到数据库表的。插入可以的形式有:

  • 插入完整的行
  • 插入行的一部分
  • 插入多行
  • 插入某些查询的结果

插入完整的行

使用基本的insert语法,其要求指定表名和被插入到新行中的值

insert into customers
values (
	null,
    'pep E.LaPew',
    '100 Main Street',
    'Los Angeles',
    'CA',
    '90046',
    'USA',
    null,
    null
    );
    
    select *
	from customers;

上面的SQL语句高度依赖于表中列的定义次序,并且还依赖于其次序容易获得的信息。即使可得到这种次序信息,也不能保证下一次表结构变动后各个列保持完全相同的 次序,为此可以按一下编辑

insert into customers(
	cust_name,
    cust_address,
    cust_city,
    cust_state,
    cust_zip,
    cust_country,
    cust_contact,
    cust_email
)


values (
    'E.LaPew',
    '100 Main Street',
    'Los Angeles',
    'CA',
    '90046',
    'USA',
    null,
    null
    );
    
    select *
	from customers;

因为提供了列名,VALUES必须以 其指定的次序匹配指定的列名,不一定按各个列出现在实际表中的次序。其优点是,即使表的结构发生了改变,此时insert语句仍然能正确工作。

insert into customers(
    cust_country,
    cust_contact,
    cust_email,
	cust_name,
    cust_address,
    cust_city,
    cust_state,
    cust_zip
)


values (
	   'CHINA',
		null,
		null,
    'E.LaPew',
    '100 Main Street',
    'Los Angeles',
    'CA',
    '90046'
    );
    
    select *
	from customers;
-- -- 

一般不要使用没有明确给出列的列表得到INSERT语句。使用列的列表能使SQL代码继续发挥作用,即使表结构发生了变化。

不管采用那种INSERT语法,都必须给出VALUES的正确数目

如果表的定义允许,可以在INSERT操作中省略某些列。省略的列必须满足于以下某个条件

  • 该列定义为允许NULL值(无值或空值)
  • 在表定义中给出默认值,这表示如果不给出值,将使用双默认值

插入多个行

可以使用多条INSERT语句,甚至一次提交他们,每条语句用一个分号结束

insert into customers(
	cust_name,
    cust_address,
    cust_city,
    cust_state,
    cust_zip,
    cust_country
)


values (
    'KE.LaPew',
    '100 Main Street',
    'Los Angeles',
    'CA',
    '90046',
    'CHINA'
    );
insert into customers(
	cust_name,
    cust_address,
    cust_city,
    cust_state,
    cust_zip,
    cust_country
)


values (
    'GE.LaPew',
    '100 Main Street',
    'Los Angeles',
    'CA',
    '90046',
    'CHINA'
    );
    
    select *
	from customers;
-- 
    

或者可以使用组合语句

insert into customers(
	cust_name,
    cust_address,
    cust_city,
    cust_state,
    cust_zip,
    cust_country
)


values (
    'KE.LaPew',
    '100 Main Street',
    'Los Angeles',
    'CA',
    '90046',
    'CHINA'
    ),
    (
    'GE.LaPew',
    '100 Main Street',
    'Los Angeles',
    'CA',
    '90046',
    'CHINA'
    );
    
    select *
	from customers;
-- -- 
    

插入检索出的数据

可以将一条SELECT语句的结果插入表中,即INSERT SELERT

insert into customers(
	cust_id,
	cust_name,
    cust_address,
    cust_city,
    cust_state,
    cust_zip,
    cust_country
)
select 
	cust_id,
	cust_name,
    cust_address,
    cust_city,
    cust_state,
    cust_zip,
    cust_country
from custnew;
-- -- 
   

insert select中select语句可包含WHERE子句可以过滤插入的数据

PART20更新和删除数据

更新数据

为了更新(修改)表中的数据,可以使用update语句,可以采用两种方式使用update

  • 更新表中特定的行
  • 更新表中所有行

基本的update语句由以下3部分组成

  • 要更新的表
  • 列名和它们的新值
  • 确定要更新行的过滤条件
update customers
set cust_email='[email protected]'
where cust_id=10011;

set 命令用来将心智赋给被更新的列,如果没有where子句,MySQL将会用该值更新表中对应的所有行

更新所有行

update customers
set cust_email='[email protected]',cust_name='sxyc'
where cust_id=10011;

update语句中可以使用子查询,使得能用SELECT语句检索出的数据更新列数据

如果采用update语句更新多行,并且在更新这些行中的一行或多行时出现一个错误,则整个update 操作将被取消。但是即使发生错误,也可以继续进行更新,可使用ignore关键字

update ignore customers

当为了删除某个列的值,可以将它设置为NULL,假如表定义允许为NULL值

update customers
set cust_email=null
where cust_id=10011;

删除数据

为了从一个表中删除去掉数据,使用delete语句,可以使用两种方式使用delete

  • 从表中删除特定的行
  • 从表中删除所有行
delete from customers
where cust_id=10011;

delete删除整行而不是删除列。为了删除指定的列,可使用update语句

delete语句从表中删除行,甚至是删除表中所有行,但是delete不能删除表本身

如果想从表中删除所有的行,可使用 truncate table,其速度更快,实际上是删除原来的表并重新创建一个表,而不是逐行删除表中的数据

如果省略了where子句,则update或delete将被应用到表中所有的行

PART21创建和操作表

MySQL不仅用于表数据操纵,而且还可以用来执行数据库和表的素有操作,包括表本身的创建和处理

  • 使用具有交互式创建和管理表的工具
  • 表也可以直接用MySQL语句操纵

程序创建表,使用SQL的create table 语句,

表创建基础

使用create table 创建表,必须给出以下信息

  • 新表的名字,在关键字create table 之后给出
  • 表列的名字和定义,用逗号分割

create table语句也可能会包括其他关键字或选项,但至少要包括表的名字和列的细节

每列的定义以列名(他在表中是唯一的)开始,后跟列的数据类型。表的主键可以在创建表时用primary key关键字指定。

在创建新表时,指定的表名必须不存在,否则将出错。如果要放置意外覆盖已有的表,SQL要求首先删除该表,然后再重建它。当若想设置一个表在不存在时创建它,应该在表后给出 if not exists.

null 值就是没有值或缺值。允许NULL值的列也允许在插入行时不给出该列的值。不允许NULL值的列不接受该列没有值的行,换句话说,在插入或更新行时,该列必须得有值

NULL是没有值,但不是空串。空串是一个有效的值,它并不是无值

主键必须是唯一的,表中的每个行必须具有唯一的主键值。如果主键使用单个列,则它的值必须唯一。如果使用多个列,则这些列的组合值必须唯一

为了创建由多个列组成的主键,应该以逗号分隔的列表给出各列名

主键为其唯一标识表中每个行的列。主键中只能使用不允许NULL值的列。允许NULL值的列不能作为唯一标识

auto-increment 告诉MySQL,本列每当早呢更加一行时自动增量。每次执行一个INSERT操作时,MySQL自动对该列增量,给该值赋予下一个可用的值。这样给每个行分配一个唯一的cust_id,从而可以用作主键值

每个表只允许一个auto-increment列,而且它必须被索引

覆盖 auto-increment: 可以简单在insert语句中指定一个值,只要它是唯一的即可,该值将被用来替代自动生成的值

确定auto-increment值,MySQL自动生成组件的确定是无法知道值的具体,可使用 select last_insert_id() 返回最后一个auto-increment值,然后将它用于后续的MySQL语句

MySQL允许指定此事使用的默认值,默认值用CREATE TABLE语句的列定义中的DEFAULT关键字指定

MySQL不允许使用函数作为默认值,其只支持常量

MySQL具有多种引擎。它打包多个引擎,这些引擎隐藏在MySQL服务器内。不同的引擎具有各自不同的功能和特性,为不同的任务选择正确的引擎能获得良好的功能和灵活性。

如果省略ENGING=语句,则可以使用默认引擎,大概率是MyISAM

  • InnoDB,是可靠的事务处理引擎,但不支持全文本搜索
  • MEMORY在功能上等同于MyISAM,但由于数据存储在内存(不是磁盘)中,速度很快(特别适合于临时表)
  • MyISAM是一个性能极高的引擎,其支持全文本搜索,但不支持事务处理

外键不能跨引擎,即使用一个引擎的表不能引用具有使用不同引擎的表的外键

更新表

可以使用ALTER TABLE语句,对表进行跟心

  • 在ALTER TABLE 之后给出要更改的表名
  • 所做更改的列表
alter table vendors
add vnd_phone char(20);
alter table orderitems
add constraint fk_orderitems_orders
foreign key (order_num)
references orders(order_num);

ALTER TABLE的常见用途是定义外键

  • 用新的列布局创建一个新的表
  • 使用insert select 语句从旧表复制数据到新表 。如果有必要,可使用转换函数和计算字符
  • 检验包含所需数据的新表
  • 重命名旧表
  • 用旧表原来的名字重命名新表
  • 根据需要,重新创建触发器,存储过程,索引和外键

删除表

使用DROP TABLE语句就可实现

重命名表

使用 RENAME TABLE语句可以重命名一个表

PART22使用试图

视图 是虚拟的表,与包含数据的表不一样,视图只包含使用时动态检索数据的查询。

作为视图,其不包含表中应该有的任何列或数据,其包含的是一个SQL查询

视图的作用:

  • 可以重复SQL语句
  • 简化复杂的SQL操作
  • 使用表的组成部分而不是整个表
  • 保护操作
  • 更改数据格式和表示

视图创建之后,可以用与表基本相同的方式利用它们。可以对视图执行SELECT操作,过滤和排序数据,将视图联结到其他视图或表,甚至能添加和更改数据

驶入仅仅是用来查看存储在别处的数据的一种设施。视图本身不包含数据,因此其返回的数据是从其他表中检索出来的。在添加或更改这些表中的数据时,视图将返回改变过的数据

视图的规则和限制

  • 视图必须是唯一命名的
  • 对于可以创建的视图的数目是没有限制
  • 为了创建视图,必须具有足够的权限
  • 视图可以嵌套,可以使用从其他视图检索数据的查询来构造一个视图
  • order by 利用在视图中,但如果从视图检索数据的select语句中也含有order by,则该视图中的 order by 将被覆盖
  • 视图不能索引,也不能由关联的触发器或默认值
  • 视图可以和表一起使用
create view productcustomers as 
select cust_name,cust_contact,prod_id
from customers,orders,orderitems
where customers.cust_id=orders.cust_id
	and orderitems.order_num=orders.order_num;


select *
from productcustomers
where productcustomers.prod_if='TNT2';
select concat(rtrim(vend_name),'(',rtrim(vend_country),')')
from myMysql.vendors
order by vend_name;


create view vendorlocation as
select concat(rtrim(vend_name),'(',rtrim(vend_country),')')
from myMysql.vendors
order by vend_name;

select * 
from vendorlocation;
create view customeremaillist as 
select cust_id,cust_name,cust_email
from customers
where cust_email is not null;

select *
from customeremaillist;
select prod_id,quantity,item_price,
	quantity*item_price as expanded_price
from myMysql.orderitems
where order_num=20005;

create view orderitemsexpanded as
select order_num,prod_id,quantity,item_price,
	quantity*item_price as expanded_price
from myMysql.orderitems;

select *
from orderitemsexpanded
where order_num=20005

在MySQL处理此查询时,其将指定的where子句添加到视图查询中的已有where子句,以便正确过滤数据

利用视图,可以一次性编写基础的SQL,然后根据需要多次进行使用

从视图检索数据时使用了一条where子句,,则这两组子句将进行自动组合

视图非常容易被 创建,正确使用视图,可极大就极大简化复杂的数据处理

视图是可更新的,更新一个视图将更新其基表。如果对视图增加或删除行,实际上是对基表进行增加和删除行操作

并非所有视图都是可更新的,基本上,如果MySQL不能正确地确定被更新的基数据,则不允许更新。即当视图定义有以下操作则不能对视图进行更新

  • 分组
  • 联结
  • 子查询
  • 聚集函数
  • DISTINCT
  • 到处计算列

视图主要用于数据检索,而不是用于更新

PART23使用存储过程

存储过程简单来书哦,就是为之后的使用而保存的一条或多条MySQL语句的集合。可将其视为批文件,虽然他们的作用不仅限于批处理

为什么要使用存储过程

  • 通过把处理封装在容易使用的单元中,简化复杂的操作
  • 不要求反复建立一系列处理不走,保证了数据的完整性
  • 简化对变动的管理

通过存储过程限制对基础数据的访问减少了数据讹误的机会(无意识的或别的原因所导致的数据讹误)

存储过程有3个主要的好处,简单、安全、高效。

一般而言,存储过程的编写比基本SQL语句复杂,可能没有常见存储过程的权限

创建存储过程

mysql> delimiter //
mysql> create procedure productpricing()
    -> begin
    -> select avg(prod_price) as priceaverage
    -> from products;
    -> end //
Query OK, 0 rows affected (0.02 sec)

mysql> delimiter ;
mysql> call productpricing();

如果存储过程接受参数,将在()中列举出来,继续存储过程不接受参数,但后跟的()仍需要。begin和end语句用来限定存储过程体

delimter // 告诉命令行实用程序使用//作为新的语句结束分隔符

删除存储过程

drop procedure productpricing;

使用参数

存储过程并不显示结果,而是把结果返回给指定的变量。

变量,内存中一个特定的位置,用来临时存储数据



create procedure productpricing(
	out p1 decimal(8,2),
    out ph decimal(8,2),
    out pa decimal(8,2)
)
begin 
	select min(prod_price)
    into p1
    from products;
    
	select max(prod_price)
    into ph
    from products;
    
	select avg(prod_price)
    into pa
    from products;
    
end;

  • out 关键字指出 相应的参数用来从存储过程一个值(返回给调用者)
  • in 传递给存储过程
  • out 从存储过程传出
  • inout 对存储过程传入和传出

存储过程的代码位于begin 和 end 语句中

存储过程中的参数允许的数据类型与表中使用的数据类型相同,记录集不是允许的类型

call productpricing(
	@pricelow,
    @pricehigh,
    @priceaverage
    );
    
select @priceaverage;
select 	@pricelow,@pricehigh,@priceaverage;
create procedure ordertotal(
	in onnumber int,
    out ototal decimal(8,2)
)
begin 
	select sum(item_price*quantity)
    from orderitems
    where order_num=onnumber
    into ototal;
end;

call ordertotal(20005,@total);
select @total;
create procedure ordertotal(
	in onnumber int,
    in taxtable boolean,
    out ototal decimal(8,2)
)
comment 'Obtain order total, optionally adding tax'
begin 
	declare total decimal(8,2);
    declare taxrate int default 6;


	select sum(item_price*quantity)
    from orderitems
    where order_num=onnumber
    into total;
    
    if taxable then
		select total+(total/100*taxrate ) into total;
	end if;
    select total into ototal;
end;

call ordertotal(20005,0,@total);
select @total;

call ordertotal(20005,1,@total);
select @total;

使用 show create procedure 语句 创建存储过程的create 语句

show create procedure ordertotal

使用 show procedure statuas 获得包括何时,由谁创建等详细信息的存储过程列表

PART2使用游标

使用游标的原因:需要在检索出来的行中前进或后退一行或多行

游标:一个存储在MySQL服务器上的数据库查询,其不是一条SELECT语句,而是被该语句检索出来的结果集

在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据

游标主要应用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或做出更改,MySQL游标只能拥有存储过程(和函数)

使用游标

  • 在能够使用游标前,必须声明(定义)它
  • 一旦声明后,必须打开游标以供使用
  • 对于填有数据的游标,根据需要取出(检索)各行
  • 在结束游标使用时,必须关闭游标

在声明游标后,可根据需要频繁地打开和关闭游标。在游标打开后,可根据需要频繁地执行取操作

创建游标

DECLARE语句创建游标,并定义相应的SELECT语句,根据需要带WHERE和其他子句

打开游标

游标用OPEN CURSOR语句来打开,在处理OPEN语句时执行查询,存储检索出的数据以供浏览和滚动

关闭游标

CLOSE:释放游标使用的所有内部存储和资源,因此在每个游标不在需要时都应该关闭。

在一个游标关闭后,如果没有重新打开,则不能使用它。但是,使用说明过的游标不需要再次声明,使用OPEN语句便可以打开它。

如果不明确关闭游标,MySQL将在到达END语句时自动关闭它

create procedure processorders()
begin
	declare ordernumbers cursor for select order_num from orders;
    open ordernumbers;
    close ordernumbers;
end

使用游标数据

在一个游标被打开后,可以使用fetch语句分别访问它的每一行。fetch指定检索什么数据(所需的列),检索出来的数据存储在什么地方。

其还向前移动游标中的内部行指针,使下一条fetch语句检索下一行(不重复读取同一行)

从游标中检索单个行(第一行)

create procedure processorders()
begin
	declare o int;
	declare ordernumbers cursor for select order_num from orders;
    open ordernumbers;
    fetch ordernumbers into o;
    close ordernumbers;
end
create procedure processorders()
begin
	declare done boolean default 0;
	declare o int;
	declare ordernumbers cursor for select order_num from orders;
    declare continue handler for sqstate '02000' set done =1;
    open ordernumbers;
    repeat
		fetch ordernumbers into o;
	until done end repeat;
    close ordernumbers;
end
create procedure processorders()
begin
	declare done boolean default 0;
	declare o int;
    declare t decimal (8,2);
    
	declare ordernumbers cursor for select order_num from orders;
    declare continue handler for sqlstate '02000' set done =1;
    
    create table if not exists ordertotals(order_num int, total decimal(8,2));
    
    open ordernumbers;
    repeat
		fetch ordernumbers into o;
        call ordertotal(o,1,t);
        
        insert into ordertotals(order_num,total)
        values(o,t);
	until done end repeat;
    close ordernumbers;
end

PART25使用触发器

触发器:需要在某个表发生更改时自动处理。触发器,是MySQL响应以下任意语句而自动执行的一条MySQL语句(或位于BEGIN和END语句之间的一组语句)

  • delete
  • insert
  • update

创建触发器

创建触发器,需要给出以下信息

  • 唯一的触发器名
  • 触发器关联的表
  • 触发器应该响应的活动
  • 触发器何时执行

触发器名必须在每个表中唯一,但不是在每个数据库中唯一,这表明同一数据库中的两个表可具有相同名字的触发器

只有表才支持触发器,视图不支持

create trigger newproduct after insert on products
for each row select 'Product add';

触发器按每个表每个时间每次地定义,每个表每个时间每次只允许一个触发器。每个表最多支持6个触发器(每条INSERT、UPDATE和DELETE的之前和之后)。单一触发器不能与多个事件或多个表关联

删除触发器

drop trigger newproduct;

触发器不能更新或覆盖。为了修改一个触发器,必须先删除它,然后再重新创建

使用触发器

INSERT触发器

INSERT触发器在INSERT语句执行之前或之后执行

  • 在INSERT触发器代码内,可引用一个名为NEW的虚拟表,访问被插入的行
  • 在before insert触发器中,new中的值也可以被更新
  • 对于INSERT_increment列,new在insert执行之前包含0,在insert执行之后包含新的自动生成值
create trigger neworder after insert on orders
for each row select new.order_num;

insert into orders(order_date,cust_id)
values(now(),1001);

before用于数据验证和净化(目的是保证插入表中的数据确实是需要的数据)

DELETE触发器

  • delete 触发器代码中,可以引用一个名为OLD的虚拟表,访问被删除的行
  • OLD中的值全部是只读,不能更新
create trigger deleteorder before delete on orders
for each row
begin
	insert into archive_orders(order_num,order_date,cust_id)
    values(old.order_num,old.order_date,old.cust_id);
end;

update触发器

  • update触发器中,可以引用一个名为OLD的虚拟表访问以前 update 语句前的值,引用一个名为 new 的虚拟表访问新更新的值
  • 在before update 触发器中,new中的值可能也被更新,允许更改将要用于update 语句中的值
  • old 中的值全都是只读的,不能更新
create trigger updatevendor before update on vendors
for each row set new.vend_state=upper(new.vend_state);

PART26 管理事务处理

事务管理:可以用来维护数据库的完整性,其保证成批的MySQL操作要么完全执行,要么完全不执行

事务管理,是一种机制,用来管理必须成批执行的MySQL操作,以保证数据库不包含不完整的操作结果。利用事务处理,可以保证一组操作不会中途停止,它或者作为整体执行,或者完全不治之星。如果没有错位发生,整组语句提交给(写到)数据库表。如果发生错误,则进行回退,以回复数据库到某个已知且安全的状态

  • 事务:一组SQL语句
  • 回退,撤销指定SQL语句的过程
  • 提交,指将为存储的SQL语句结果写入数据库表
  • 保留点,指事务处理中设置的临时占位符,你可以对它发布回退(与回退整个事务处理不同)

控制事务处理

管理事务处理的关键在于将SQL语句组分解为逻辑块,并明确规定数据何时应该回退,何时不应该回退

start transaction

标识事务的开始

使用ROLLBACK用来回退(撤销)MySQL语句

select * from ordertotals;
start transaction;
delete from ordertotals;
select *from ordertotals;
rollback;
select *from ordertotals;

ROLLBACK只能在一个事务处理内使用

事务处理用来管理INSERT、UPDATE和DELETE 语句,不能回退SELECT 语句,不能回退CREATE或DROP操作

使用COMMIT

MySQL语句都是针对数据库表执行和编写的,即隐含式提交,即提交(写或保存)操作是自动进行的

但是,在事务处理中,提交不会隐含进行,为进行明确的提交,使用commit语句

select transaction;
delete from orderitems where order_num=20010;
delete from orders where order_num=20010;
commit;

当commit 或rollback 语句执行后,事务会自动关闭

使用保留点

简单的ROLLBACK和COMMIT语句就可以写入或撤销整个事务处理,但是,只是对简单的事务处理才能这样做,更复杂的事务处理可能需要部分提交或回退

为了支持回退部分事务处理,必须能在事务处理块中合适的位置放置占位符。这样,如果需要回退,可以回退到某个占位符

这些占位符被称为保留点,为了创建占位符,可是使用SAVEPOINT语句

SAVEPOINT delete1;

每个保留点都取标识它的唯一名字,以便在回退时,MySQL知道要回退到何处。

rollback to delete1

保留点越多越好

释放保留点:保留点在事务处理完成后自动释放,也可用release savepoin明确指出释放保留点

更改默认的提交行为

默认的MySQL是自动提交所有更改。可指定MySQL不自动提交更改

set autocommit =0 ;

设置autocommit为0(假)指示MySQL不自动提交更改

PART27全球化和本地化

数据集中常用的术语:

  • 字符集:字母和符号的集合
  • 编码,某个字符集成员的内部表示
  • 校对,规定字符如何比较的指令

show character set

显示所有可用的字符集以及每个字符集的描述和默认校对

show collattion

显示所有可用的校对,以及他们使用的字符集,字符集具有不止一种校对

系统管理在安装时会定义一个默认的字符集和校对。此外,也可在创建数据库时,指定默认的字符集和校对

show variables like 'character%';
show variables like 'collation%';

为了给表指定数据集和校对,可使用带子句的create table语句

create table mytable
(
	columnn1 int,
    columnn2   varchar(10)
)
default character set hebrew
collate hebrew_general_ci;
  • 如果指定character set 和collate 两者,则使用这些值
  • 如果只指定character set,则使用此字符集及其默认的校对
  • 如果既不指定character set,也不指定collate,则使用数据库默认

MySQL还允许对某个列设置

create table mytable
(
	columnn1 int,
    columnn2   varchar(10),
    columnn3 varchar(10) character set latin1 collate latin1_general_ci
)
default character set hebrew
collate hebrew_general_ci;

用与创建表是不同的校对顺序排序特定的select语句,可以在select语句自身中进行

select *from customers
order by lastname,firstname collate latin1_general_ci

PART28安全管理

MySQL服务器的安全基础是:用户应该对他们需要的数据具有适当的访问全,不能多也不能少

访问控制,需要给用户提供恰当的访问权,管理访问控制需要创建和管理用户账号

管理用户

mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select user from user;

创建用户账号

create user ben identified by '[email protected]$$w0rd';

重命名用户账号

rename user ben to bforta;

删除用户账号

drop user bforta;

设置访问权限

更改口令show grants for bforta

grant 语句们必须要求具有以下的信息

  • 被授予的权限
  • 被授予访问权限的数据库或表
  • 用户名
grant select on crashcourse.* to bforta

撤销特定的权限

revoke select on crashcourse.* from bforta

授予和撤销特定的访问权限可在几个层次上进行控制

  • 整个服务器,使用 grant all 和 revoke all
  • 整个数据库,使用 on database .*
  • 特定的表,使用 on database.table
  • 特定的列
  • 特定的存储过程

更改口令

set password for bforta =password('n3w [email protected]$$w0rd');

原网站

版权声明
本文为[瀛台夜雪]所创,转载请带上原文链接,感谢
https://blog.csdn.net/sxycylq/article/details/125635619