第 2 章 MySQL简介
在你能执行任意数据库操作前,需要选择一个数据库。为此,可使用USE关键字。
数据库、表、列、用户、权限等的信息被存储在数据库和表中(MySQL使用MySQL来存储这些信息)。不过,内部的表一般不直接访问。可用MySQL的SHOW命令来显示这些信息(MySQL从内部表中提取这些信息)
为了获得一个数据库内的表的列表,使用SHOW TABLES;
SHOW COLUMNS 要求给出一个表名(这个例子中的 FROM_customers),它对每个字段返回一行,行中包含字段名、数据类型、是否允许NULL、键信息、默认值以及其他信息(如字段cust_id的auto_increment)。
DESCRIBE customers;是SHOW COLUMNS FROM customers;的一种快捷方式。
第 4 章 检索数据
最经常使用的SQL语句就是SELECT语句了。它的用途是从一个或多个表中检索信息。
SELECT last_name FROM actor
SQL语句不区分大小写,因此SELECT与select是相同的。
多条SQL语句必须以分号(;)分隔。
要想从一个表中检索多个列,使用相同的SELECT语句。唯一的不同是必须在SELECT关键字后给出多个列名,列名之间必须以逗号分隔。SELECT last_name , first_name FROM actor
除了指定所需的列外(如上所述,一个或多个列),SELECT语句还可以检索所有的列而不必逐个列出它们。这可以通过在实际列名的位置使用星号(*)通配符来达到。
使用DISTINCT关键字,顾名思义,此关键字指示MySQL只返回不同的值。
SELECT DISTINCT last_name , first_name FROM actor
为了返回第一行或前几行,可使用LIMIT子句。LIMIT 5指示MySQL返回不多于5行。LIMIT 5, 5指示MySQL返回从行5开始的5行。SELECT DISTINCT last_name FROM actor LIMIT 5,5;
检索出来的第一行为行0而不是行1。因此,LIMIT 1, 1将检索出第二行而不是第一行。
第5章 排序检索数据
为了明确地排序用SELECT语句检索出的数据,可使用ORDER BY子句。ORDER BY子句取一个或多个列的名字,据此对输出进行排序。
SELECT DISTINCT last_name , first_name FROM actor ORDER BY first_name
经常需要按不止一个列进行数据排序。例如,如果要显示雇员清单,可能希望按姓和名排序(首先按姓排序,然后在每个姓中再按名排序)为了按多个列排序,只要指定列名,列名之间用逗号分开即可(就像选择多个列时所做的那样)
数据排序不限于升序排序(从A到Z)。这只是默认的排序顺序,还可以使用ORDER BY子句以降序(从Z到A)顺序排序。为了进行降序排序,必须指定DESC关键字。DESC关键字只应用到直接位于其前面的列名。SELECT DISTINCT last_name , first_name FROM actor ORDER BY first_name DESC
与DESC相反的关键字是ASC(ASCENDING)
在给出ORDER BY子句时,应该保证它位于FROM子句之后。如果使用LIMIT,它必须位于ORDER BY 之后。使用子句的次序不对将产生错误消息。
第6章 过滤数据
在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。WHERE子句在表名(FROM子句)之后给出。在同时使用ORDER BY和WHERE子句时,应该让ORDER BY位于WHERE之后。
SELECT customer_id,amount FROM payment WHERE amount = 11.99 ORDER BY customer_id DESC
在使用BETWEEN时,必须指定两个值——所需范围的低端值和高端值。这两个值必须用AND关键字 分隔。BETWEEN匹配范围中所有的值,包括指定的开始值和结束值。
SELECT customer_id,amount FROM payment WHERE amount BETWEEN 5 AND 10 ORDER BY customer_id DESC
SELECT语句有一个特殊的WHERE子句,可用来检查具有NULL值的列。这个WHERE子句就是IS NULL子句。
SELECT customer_id,amount FROM payment WHERE amount IS NULL
第 7 章 数据过滤
为了进行更强的过滤控制,MySQL允许给出多个WHERE子句。这些子句可以两种方式使用:以AND子句的方式或OR子句的方式使用。为了通过不止一个列进行过滤,可使用AND操作符给WHERE子句附加条件。
SELECT customer_id,amount FROM payment WHERE amount =0.99 AND customer_id = 1
OR操作符与AND操作符不同,它指示MySQL检索匹配任一条件的行。
SELECT customer_id,amount FROM payment WHERE amount =0.99 OR customer_id = 1
SQL(像多数语言一样)在处理OR操作符前,优先处理AND操作符。此问题的解决方法是使用圆括号明确地分组相应的操作符。
IN操作符用来指定条件范围,范围中的每个条件都可以进行匹配。
SELECT customer_id,amount FROM payment WHERE customer_id IN (1,2,3)
WHERE子句中的NOT操作符有且只有一个功能,那就是否定它之后所跟的任何条件。
SELECT customer_id,amount FROM payment WHERE customer_id NOT IN (1,2,3)
第 8 章 用通配符进行过滤
最常使用的通配符是百分号(%)。在搜索串中,%表示任何字符出现任意次数。
SELECT customer_id,amount FROM payment WHERE customer_id LIKE '2%’
搜索模式'%anvil%'表示匹配任何位置包含文本anvil的值,而不论它之前或之后出现什么字符。
SELECT customer_id,amount FROM payment WHERE customer_id LIKE '%2%’
另一个有用的通配符是下划线(_)。下划线的用途与%一样,但下划线只匹配单个字符而不是多个字符。与%能匹配0个字符不一样,_总是匹配一个字符,不能多也不能少。
第9章 用正则表达式进行搜索
正则表达式是用来匹配文本的特殊的串(字符集合)。如果你想从一个文本文件中提取电话号码,可 以使用正则表达式。如果你需要查找名字中间有数字的所有文件,可以使用一个正则表达式。
LIKE匹配整个列。如果被匹配的文本在列值中出现,LIKE将不会找到它,相应的行也不被返回(除非使用通配符)。而REGEXP在列值内进行匹配,如果被匹配的文本在列值中出现,REGEXP将会找到它,相应的行将被返回。这是一个非常重要的差别。
为搜索两个串之一(或者为这个串,或者为另一个串),使用|:
SELECT customer_id,amount FROM payment WHERE customer_id REGEXP '2|3’
匹配任何单一字符。但是,如果你只想匹配特定的字符,怎么办?可通过指定一组用[和]括起来的字符来完成
这里,使用了正则表达式[123] Ton。[123]定义一组字符,它的意思是匹配1或2或3,因此,1 ton和2 ton都匹配且返回(没有3 ton)。
SELECT customer_id,amount FROM payment WHERE customer_id REGEXP '[12]3’
字符集合也可以被否定,即,它们将匹配除指定字符外的任何东西。为否定一个字符集,在集合的开始处放置一个^即可。尽管[123]匹配字符1、2或3,但[^123]却匹配除这些字符外的任何东西。
为了匹配特殊字符,必须用\为前导。\-表示查找-,\.表示查找.。
第 10 章 创建计算字段
计算字段并不实际存在于数据库表中。计算字段是运行时在SELECT语句内创建的。
把两个列拼接起来。在MySQL的SELECT语句中,可使用Concat()函数来拼接两个列。
SQL支持列别名。别名(alias)是一个字段或值的替换名。别名用AS关键字赋予。
第 11 章 使用数据处理函数
使用Upper()函数 SELECT UPPER(last_name) FROM actor
无论你什么时候指定一个日期,不管是插入或更新表值还是用WHERE子句进行过滤,日期必须为格式yyyy-mm-dd。
SELECT customer_id,amount,payment_date FROM payment WHERE payment_date LIKE '2005-06-16%’
SELECT customer_id,amount,payment_date FROM payment WHERE Date(payment_date)='2005-06-16’
第 12 章 汇总数据
我们经常需要汇总数据而不用把它们实际检索出来,为此MySQL提供了专门的函数。使用这些函数,MySQL查询可用于检索数据,以便分析和报表生成。
确定表中行数(或者满足某个条件或包含某个特定值的行数)。 获得表中行组的和。 找出表列(或所有行或某些特定的行)的最大值、最小值和平均值
聚集函数(aggregate function) 运行在行组上,计算和返回单个值的函数
**AVG()**通过对表中行数计数并计算特定列值之和,求得该列的平均值。AVG()可用来返回所有列的平均值,也可以用来返回特定列或行的平均值。
SELECT AVG(amount) AS avg_amount FROM payment WHERE DATE(payment_date)='2005-06-16’
**COUNT()**函数进行计数。可利用COUNT()确定表中行的数目或符合特定条件的行的数目
SELECT COUNT(*) AS count_amount FROM payment WHERE DATE(payment_date)='2005-06-16’
**MAX()**返回指定列中的最大值。MAX()要求指定列名
SELECT MAX(amount) AS max_amount FROM payment WHERE DATE(payment_date)='2005-06-16’
**MIN()**的功能正好与MAX()功能相反,它返回指定列的最小值。与MAX()一样,MIN()要求指定列名
**SUM()**用来返回指定列值的和(总计)。
第 13 章 分组数据
分组数据,以便能汇总表内容的子集。涉及两个新SELECT语句子句,分别是GROUP BY子句和HAVING子句
SELECT SUM(amount),DATE(payment_date) AS sum_amount FROM payment GROUP BY DATE(payment_date)
GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前
唯一的差别是WHERE过滤行,而HAVING过滤分组 HAVING支持所有WHERE操作符
WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。
一般在使用GROUP BY子句时,应该也给出ORDER BY子句。
第 14 章 使用子查询
SQL还允许创建子查询(subquery),即嵌套在其他查询中的查询。
子查询最常见的使用是在WHERE子句的IN操作符中,以及用来填充计算列。
第 15 章 联结表
关键是,相同数据出现多次决不是一件好事,此因素是关系数据库设计的基础。关系表的设计就是要保证把信息分解成多个表,一类数据一个表。各表通过某些常用的值(即关系设计中的关系(relational))互相关联。在这个例子中,可建立两个表,一个存储供应商信息,另一个存储产品信息。vendors表包含所有供应商信息,每个供应商占一行,每个供应商具有唯一的标识。此标识称为主键(primary key)(在第1章中首次提到),可以是供应商ID或任何其他唯一值。products表只存储产品信息,它除了存储供应商ID(vendors表的主键)外不存储其他供应商信息。vendors表的主键又叫作products的外键,它将vendors表与products表关联,利用供应商ID能从vendors表中找出相应供应商的详细信息。
外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系。
这样做的好处如下: 供应商信息不重复,从而不浪费时间和空间; 如果供应商信息变动,可以只更新vendors表中的单个记录,相 关表中的数据不用改动; 由于数据无重复,显然数据是一致的,这使得处理数据更简单。 总之,关系数据可以有效地存储和方便地处理。因此,关系数据库的可伸缩性远比非关系数据库要好。
SELECT amount,payment_date,rental_date FROM payment,rental WHERE payment.customer_id
= rental.customer_id
目前为止所用的联结称为等值联结(equijoin),它基于两个表之间的相等测试。这种联结也称为内部联结。
此语句中的SELECT与前面的SELECT语句相同,但FROM子句不同。这里,两个表之间的关系是FROM子句的组成部分,以INNER JOIN指定。在使用这种语法时,联结条件用特定的ON子句而不是WHERE子句给出。传递给ON的实际条件与传递给WHERE的相同。
SELECT amount,payment_date,rental_date FROM payment INNER JOIN rental ON payment.customer_id = rental.customer_id
规范首选INNER JOIN语法
第 16 章 创建高级联结
表别名只用于WHERE子句。但是,表别名不仅能用于WHERE子句,它还可以用于SELECT的列表、ORDER BY子句以及语句的其他部分。
SELECT amount,payment_date,rental_date FROM payment AS P INNER JOIN rental AS R ON P.customer_id = R.customer_id
迄今为止,我们使用的只是称为内部联结或等值联结(equijoin)的简单联结。现在来看3种其他联结,它们分别是自联结、自然联结和外部联结。
自然联结是这样一种联结,其中你只能选择那些唯一的列。这一般是通过对表使用通配符(SELECT *),对所有其他表的列使用明确的子集来完成的。自然联结排除多次出现,使每个列只返回一次。
联结包含了那些在相关表中没有关联行的行。这种类型的联结称为外部联结。
在使用OUTER JOIN语法时,必须使用RIGHT或LEFT关键字指定包括其所有行的表(RIGHT指出的是OUTER JOIN右边的表,而LEFT指出的是OUTER JOIN左边的表)
SELECT amount,payment_date,rental_date FROM payment AS P LEFT OUTER JOIN rental AS R ON P.customer_id = R.customer_id
第 17 章 组合查询
多数SQL查询都只包含从一个或多个表中返回数据的单条SELECT语句。MySQL也允许执行多个查询(多条SELECT语句),并将结果作为单个查询结果集返回。这些组合查询通常称为并(union)或复合查询(compound query)。
SELECT amount,customer_id FROM payment WHERE amount > 2 UNION SELECT payment_id,customer_id FROM payment WHERE customer_id > 10
UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分隔(因此,如果组合4条SELECT语句,将要使用3个UNION关键字)。
UNION中的每个查询必须包含相同的列、表达式或聚集函数(不过各个列不需要以相同的次序列出)
列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含地转换的类型(例如,不同的数值类型或不同的日期类型)。
在使用UNION时,重复的行被自动取消。这是UNION的默认行为,但是如果需要,可以改变它。事实上,如果想返回所有匹配行,可使用UNION ALL而不是UNION。
在用UNION组合查询时,只能使用一条ORDER BY子句,它必须出现在最后一条SELECT语句之后。
利用UNION,可把多条查询的结果作为一条组合查询返回,不管它们的结果中包含还是不包含重复。
第 18 章 全文本搜索
两个最常使用的引擎为MyISAM和InnoDB,前者支持全文本搜索,而后者不支持。
第 19 章 插入数据
INSERT是用来插入(或添加)行到数据库表的。插入可以用几种方式使用: 插入完整的行; 插入行的一部分; 插入多行; 插入某些查询的结果。
存储到每个表列中的数据在VALUES子句中给出,对每个列必须提供一个值。如果某个列没有值,应该使用NULL值(假定表允许对该列指定空值)
INSERT INTO actor VALUES(201,'SUN','BIUBIU',NULL)
第一列cust_id也为NULL。这是因为每次插入一个新行时,该列由MySQL自动增量。
此例子完成与前一个INSERT语句完全相同的工作,但在表名后的括号里明确地给出了列名。在插入行时,MySQL将用VALUES列表中的相应值填入列表中的对应项。
因为提供了列名,VALUES必须以其指定的次序匹配指定的列名,不一定按各个列出现在实际表中的次序。其优点是,即使表的结构改变,此INSERT语句仍然能正确工作。
INSERT INTO actor (actor_id,first_name,last_name,last_update) VALUES(null,'SUN','BIUBIU',NULL)
如果数据检索是最重要的(通常是这样),则你可以通过在INSERT和INTO之间添加关键字LOW_PRIORITY,指示MySQL降低INSERT语句的优先级
可以使用多条INSERT语句,甚至一次提交它们,其中单条INSERT语句有多组值,每组值用一对圆括号括起来,用逗号分隔。
INSERT INTO actor (actor_id,first_name,last_name,last_update) VALUES(null,'SUN','BIUBIU3',NULL),(null,'SUN','BIUBIU4',NULL)
第 20 章 更新和删除数据
为了更新(修改)表中的数据,可使用UPDATE语句。可采用两种方式使用UPDATE:
更新表中特定行; 更新表中所有行。
在使用UPDATE时一定要注意细心。因为稍不注意,就会更新表中所有行。
UPDATE语句总是以要更新的表的名字开始。SET命令用来将新值赋给被更新的列。UPDATE语句以WHERE子句结束,它告诉MySQL更新哪一行。没有WHERE子句,MySQL将会用这个电子邮件地址更新表中所有行,这不是我们所希望的。
UPDATE actor SET first_name = 'swh' WHERE actor_id=202
在更新多个列时,只需要使用单个SET命令,每个“列=值”对之间用逗号分隔(最后一列之后不用逗号)
UPDATE actor SET first_name = 'swh',last_name = 'BiuB' WHERE actor_id=202
为了删除某个列的值,可设置它为NULL(假如表定义允许NULL值)。
为了从一个表中删除(去掉)数据,使用DELETE语句。可以两种方式使用DELETE:
从表中删除特定的行; 从表中删除所有行。
在使用DELETE时一定要注意细心。因为稍不注意,就会错误地删除表中所有行。
DELETE FROM要求指定从中删除数据的表名。WHERE子句过滤要删除的行。在这个例子中,只删除客户10006。如果省略WHERE子句,它将删除表中每个客户。 DELETE不需要列名或通配符。DELETE删除整行而不是删除列。为了删除指定的列,请使用UPDATE语句。
DELETE FROM actor WHERE actor_id = 204
DELETE语句从表中删除行,甚至是删除表中所有行。但是,DELETE不删除表本身。
如果想从表中删除所有行,不要使用DELETE。可使用TRUNCATE TABLE语句,它完成相同的工作,但速度更快(TRUNCATE实际是删除原来的表并重新创建一个表,而不是逐行删除表中的数据)。
第 21 章 创建和操纵表
为了用程序创建表,可使用SQL的CREATE TABLE语句。
为利用CREATE TABLE创建表,必须给出下列信息: 新表的名字,在关键字CREATE TABLE之后给出; 表列的名字和定义,用逗号分隔。
CREATE TABLE Sun
(
id int NOT NULL AUTO_INCREMENT,
name char(50) NOT NULL,
university char(50),
PRIMARY KEY (id)
)ENGINE = InnoDB;
表名紧跟在CREATE TABLE关键字后面。实际的表定义(所有列)括在圆括号之中。各列之间用逗号分隔。这个表由9列组成。每列的定义以列名(它在表中必须是唯一的)开始,后跟列的数据类型(关于数据类型的解释,请参阅第1章。此外,附录D列出了MySQL支持的数据类型)。表的主键可以在创建表时用PRIMARY KEY关键字指定。这里,列cust_id指定作为主键列。整条语句由右圆括号后的分号结束。
如果你仅想在一个表不存在时创建它,应该在表名后给出IF NOT EXISTS。
如果在插入行时没有给出值,MySQL允许指定此时使用的默认值。默认值用CREATE TABLE语句的列定义中的DEFAULT关键字指定。
以下是几个需要知道的引擎: InnoDB是一个可靠的事务处理引擎(参见第26章),它不支持全文本搜索; MEMORY在功能等同于MyISAM,但由于数据存储在内存(不是磁盘)中,速度很快(特别适合于临时表);
MyISAM是一个性能极高的引擎,它支持全文本搜索(参见第18章),但不支持事务处理。
为更新表定义,可使用ALTER TABLE语句。但是,理想状态下,当表中存储数据以后,该表就不应该再被更新。
为了使用ALTER TABLE更改表结构,必须给出下面的信息: 在ALTER TABLE之后给出要更改的表名(该表必须存在,否则将出错);
所做更改的列表。
ALTER TABLE Sun2 ADD age INT
ALTER TABLE Sun2 DROP COLUMN age
ALTER TABLE的一种常见用途是定义外键。
删除表(删除整个表而不是其内容)非常简单,使用DROP TABLE语句即可
使用RENAME TABLE语句可以重命名一个表:
RENAME TABLE Sun2 TO Sun3
删除表(删除整个表而不是其内容)非常简单,使用DROP TABLE语句即可:
DROP TABLE Sun3
第 22 章 使用视图
视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。它不包含表中应该有的任何列或数据,它包含的是一个SQL查询
下面是关于视图创建和使用的一些最常见的规则和限制。 与表一样,视图必须唯一命名(不能给视图取与别的视图或表相同的名字)。 对于可以创建的视图数目没有限制。 为了创建视图,必须具有足够的访问权限。这些限制通常由数据库管理人员授予。 视图可以嵌套,即可以利用从其他视图中检索数据的查询来构造一个视图。 ORDER BY可以用在视图中,但如果从该视图检索数据SELECT中也含有ORDER BY,那么该视图中的ORDER BY将被覆盖。 视图不能索引,也不能有关联的触发器或默认值。 视图可以和表一起使用。例如,编写一条联结表和视图的SELECT语句。
在理解什么是视图(以及管理它们的规则及约束)后,我们来看一下视图的创建。 视图用CREATE VIEW语句来创建。 使用SHOW CREATE VIEW viewname;来查看创建视图的语句。 用DROP删除视图,其语法为DROP VIEW viewname;。
更新视图时,可以先用DROP再用CREATE,也可以直接用CREATE ORREPLACE VIEW。如果要更新的视图不存在,则第2条更新语句会创建一个视图;如果要更新的视图存在,则第2条更新语句会替换原有视图。
视图极大地简化了复杂SQL语句的使用。利用视图,可一次性编写基础的SQL,然后根据需要多次使用。视图的另一常见用途是重新格式化检索出的数据。
通常,视图是可更新的(即,可以对它们使用INSERT、UPDATE和DELETE)。更新一个视图将更新其基表(可以回忆一下,视图本身没有数据)。如果你对视图增加或删除行,实际上是对其基表增加或删除行。
如果视图定义中有以下操作,则不能进行视图的更新:
分组(使用GROUP BY和HAVING); 联结; 子查询; 并; 聚集函数(Min()、Count()、Sum()等); DISTINCT; 导出(计算)列。
小结:视图为虚拟的表。它们包含的不是数据而是根据需要检索数据的查询。视图提供了一种MySQL的SELECT语句层次的封装,可用来简化数据处理以及重新格式化基础数据或保护基础数据。
第 23 章 使用存储过程
存储过程简单来说,就是为以后的使用而保存的一条或多条MySQL语句的集合。可将其视为批文件,虽然它们的作用不仅限于批处理。
MySQL执行存储过程的语句为CALL。CALL接受存储过程的名字以及需要传递给它的任意参数。
CREATE PROCEDURE avg_amount() BEGIN SELECT Avg(amount) AS avg_payment FROM payment; END;
第 24 章 使用游标
有时,需要在检索出来的行中前进或后退一行或多行。这就是使用游标的原因。游标(cursor)是一个存储在MySQL服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。
游标用OPEN CURSOR语句来打开:
在一个游标被打开后,可以使用FETCH语句分别访问它的每一行。FETCH指定检索什么数据(所需的列),检索出来的数据存储在什么地方。它还向前移动游标中的内部行指针,使下一条FETCH语句检索下一行(不重复读取同一行)。
第 25 章 使用触发器
触发器是MySQL响应以下任意语句而自动执行的一条MySQL语句(或位于BEGIN和END语句之间的一组语句):
DELETE; INSERT; UPDATE。
在创建触发器时,需要给出4条信息: 唯一的触发器名; 触发器关联的表; 触发器应该响应的活动(DELETE、INSERT或UPDATE); 触发器何时执行(处理之前或之后)。
触发器用CREATE TRIGGER语句创建。
*第 26 章 管理事务处理
事务处理(transaction processing)可以用来维护数据库的完整性,它保证成批的MySQL操作要么完全执行,要么完全不执行。
利用事务处理,可以保证一组操作不会中途停止,它们或者作为整体执行,或者完全不执行(除非明确指示)。如果没有错误发生,整组语句提交给(写到)数据库表。如果发生错误,则进行回退(撤销)以恢复数据库到某个已知且安全的状态。
事务(transaction)指一组SQL语句; 回退(rollback)指撤销指定SQL语句的过程; 提交(commit)指将未存储的SQL语句结果写入数据库表; 保留点(savepoint)指事务处理中设置的临时占位符(placeholder),你可以对它发布回退(与回退整个事务处理不同)。
INSERT INTO sun VALUES(NULL,'SUN','Nankai');
SELECT* FROM sun; START TRANSACTION; DELETE FROM sun; SELECT * FROM sun; ROLLBACK; SELECT * FROM sun;
你不能回退CREATE或DROP操作。
但是,在事务处理块中,提交不会隐含地进行。为进行明确的提交,使用COMMIT语句。
为了支持回退部分事务处理,必须能在事务处理块中合适的位置放置占位符。这样,如果需要回退,可以回退到某个占位符。
这些占位符称为保留点。为了创建占位符,可如下使用SAVEPOINT语句:
SELECT* FROM sun; START TRANSACTION; SAVEPOINT save1; DELETE FROM sun; SELECT * FROM sun; ROLLBACK TO save1; SELECT * FROM sun; COMMIT;
为了创建一个新用户账号,使用CREATE USER语句,用IDENTIFIED BY 'p@$$wOrd'给出了口令。
CREATE USER BIUBIU IDENTIFIED BY '111111'; USE mysql; SELECT USER FROM USER;