目前属于Oracle,分红社区版和企业版
,关系型数据库
。mysql
配置文件:my.ini
git
在win cmd中使用net start/stop mysql
来启动和中止mysql服务github
mysql -uuer_name -ppassword -Pport -hhost
复制代码
能够只使用mysql -uuser_name -ppasswrod
来开启,后面的可使用默认的值。-P
是指端口号,默认3306。-h
是指地址,默认127.0.0.1。正则表达式
在MySQL命令窗口输入:exit
, quit
和\q
之中任意一个便可。算法
在登入时,经过-prompt
来指定提示符,或者在处于命令行时使用prompt
来指定。sql
在指定提示符的时候可使用\D
, \d
, \h
和\u
来指示提示符显示当前的日期、数据库、服务器和用户。数据库
使用SELECT VERSION()
, SELECT NOW()
, SELECT USER()
, SELECT DATABASE()
能够分别用来显示当前的数据库版本、时间、操做用户和数据库。设计模式
--
/**/
数据库操做指令大写;数据库相关的名称小写,且单词之间用下划线分开。安全
查看mysql中当前编码服务器
show variables like 'char%
复制代码
查看数据表的编码格式
mysql> show create table <表名>;
复制代码
建立数据库时指定数据库的字符集
mysql>create database <数据库名> character set utf8;
复制代码
建立数据表时指定数据表的编码格式
create table tb_books (
name varchar(45) not null,
price double not null,
bookCount int not null,
author varchar(45) not null ) default charset = utf8;
复制代码
修改数据库的编码格式
mysql>alter database <数据库名> character set utf8;
复制代码
修改数据表格编码格式
mysql>alter table <表名> character set utf8;
复制代码
修改字段编码格式
mysql>alter table <表名> change <字段名> <字段名> <类型> character set utf8;
复制代码
window命令行中中文乱码问题,链接以后使用
set names gbk;
复制代码
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
[DEFAULT] CHARACTER SET [=] character_name
复制代码
my.ini
中的default-character-set
中指定。CHARACTER SET [=] character_name
用来指定数据库的字符编码方式。IF NOT EXISTS
当指定数据库已经存在的时候,就不会报错了,不然会报错,可是报的错仍是能够查找到的。创建表的时候使用备注:
CREATE TABLE test_table (
test_grade int DEFAULT 1 COMMENT '等级'
) COMMENT = '测试表';
复制代码
SHOW CREATE DATABASE db_name;
复制代码
相似的,还有显示表的建立的SQL语句:SHOW CREATE TABLE tbl_name;
修改数据库的字符编码方式的语句:
ALTER {DATABASE|SCHEMA} [DEFAULT] CHARACTER SET [=] charset_name;
复制代码
DROP {DATABASE|SCHEMA} [IF EXISTS] db_name
复制代码
SHOW DATABASES;
复制代码
相似的,有SHOW TABLES [FROM db_name]
用于显示当前数据库(或指定数据库)下面的全部表。
整数分为有符号和无符号的,经过UNSIGNED
指定。(取值范围和C语言中的类型范围同样)
浮点数也分为有符号的和无符号的。以下所示,前面的m指定了总的位数,后面的n指定了小数的位数,因此整数位数为m-n. 和C语言中的float和double范围同样。
或者使用时间戳,用BIGINT保存指定时间的毫秒值。
CREATE TABLE [IF NOT EXISTS] table_name (
column_name data_type,
...
);
复制代码
查看指定数据库的全部的表
SHOW TABLES [FROM db_name][LIKE 'pattern'|WHERE expr];
复制代码
显示指定表的各个列的定义:
SHOW COLUMNS FROM tbl_name;
复制代码
在建立表的时候,在定义列的后面加上NOT NULL
来指定指定的列不可为空。这样的列在插入记录的时候必须对其进行赋值。
自动编号,必须与主键组合使用。经过在建立表的时候在列定义后加入AUTO_INCREMENT
来实现。此外,能够经过ALTER TABLE users AUTO_INCREMENT = 10000;
来指定自增的开始值。
必须保证惟一性,一个表只能有一个,非NULL。建立表的时候使用PRIMARY KEY
来指定列是主键。
必须保证惟一性,一个表能够有多个,能够是NULL的。建立表的时候使用UNIQUE KEY
来指定列是惟一的。
当指定的列没有指定值的时候就使用默认的值,在建立表的时候,经过使用DEFAULT
关键字来指定列的默认值。
在实际开发过程当中更多地使用逻辑外键而不是物理外键,就是只要保证表之间的关联关系就好,而不为表设置外键。由于外键要求建立表的时候,父表和子表都必须使用INNODB引擎。
ALTER TABLE tbl_name ADD [COLUMN] col_name col_def [FIRST|AFTER col_name]
复制代码
向指定的表中加入一列。经过FIRST
指定新加入的列处于全部列的最前方,经过AFTER col_name
指定新加入的列相对于某个列的位置。
ALTER TABLE tbl_name ADD [COLUMN] (col_name col_def[, col_name col_def, ...])
复制代码
当向表中添加多个列的时候,只能将新加入列放在表的最后面的位置。
ALTER TABLE tbl_name DROP [COLUMN] col_name[, col_name, ...]
复制代码
能够指定并删除多个列。
ALTER TABLE tbl_name ADD [CONSTRAINT[symbol]] PRIMARY KEY [index_type](index_col_name)
ALTER TABLE tbl_name ADD [CONSTRAINT[symbol]] UNIQUE [index_type](index_col_name)
复制代码
上面的两条语句分别用来向指定的表中的列加入主键和惟一性约束。示例ALTER TABLE temp ADD UNIQUE(name)
(列名上要加括号)。加入了主键和惟一性约束的同时会为指定的列加上索引,因此可使用index_type
来指定索引的类型。要为MySQL设置默认的索引,到my.ini
中的default-storage-engine
中进行设置便可。另外,可使用SHOW INDEXES FROM tbl_name
查看指定表中存在的索引。
ALTER TABLE tbl_name DROP PRIMARY KEY;
ALTER TABLE DROP {INDEX|KEY} col_name;
复制代码
ALTER TABLE tbl_name MODIFY [COLUMN] col_name col_def [FIRST|AFTER col_name]
复制代码
上面这种方式能够修改列的定义语句,它适用的范围比较广——能够经过在col_def中指定约束和数据类型来对列进行更多的修改。
ALTER TABLE tbl_name CHANGE [COLUMN] old_col_name new_col_name col_def [FIRST|AFTER col_name]
复制代码
上面的修改语句的适用范围更广,它能够修改的范围包括:列的数据类型、约束、位置和名称。
ALTER TABLE tbl_name RENAME [TO|AS] new_tbl_name
RENAME TABLE tbl_anem TO new_tbl_name [, tbl_name TO new_tbl_name...]
复制代码
ALTER TABLE tbl_name ADD PRIMARY KEY (col_name)
ALTER TABLE tbl_name ADD UNIQUE (col_name)
ALTER TABLE ADD key(col_name)
以及ALTER TABLE tbl_name ADD INDEX index_name (col_name)
ALTER TABLE tbl_name ADD FULLTEXT (col_name)
ALTER TABLE tbl_name ADD INDEX index_name (col_name1, col_name2, ..)
向表中插入记录
INSERT [INTO] tbl_name [(col_name, ...)] {VALUES|VALUE} ({expr|DEFAULT}, ...), (...), ...
复制代码
以上用来向指定数据库的指定列中插入数据,若是不指定了列的名称,就必须对表的全部的列进行赋值。能够为指定的列指定值,可使用表达式,也可使用默认值。
INSERT [INTO] tbl_name SET col_name = {expr|DEFAULT} [, col_name = {expr|DEFAULT}]
INSERT [INTO] tbl_name [(col_name, ...)] SELECT ...
复制代码
将查询结果插入到指定的表中。好比INSERT INTO temp (name) SELECT name FROM assignment
UPDATE [LOW_PRIORITY] [IGNORE] table_reference
SET col_name1 = {expr|DEFAULT} [, col_name2 = {expr|DEFAULT}] ...
[WHERE where_condition]
复制代码
没有指定WHERE语句,就对整个表的所有记录进行更新。
DELETE FROM tbl_name [WHERE where_condition]
复制代码
SELECT select_expr [, select_expr ...]
[
FROM table_references
[WHERE where_condition]
[GROUP BY {col_name|position} [ASC|DESC], ... ]
[HAVING having_condition]
[ORDER BY {col_name|expr|position} [ASC|DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
]
复制代码
将DISTINCT
关键字放在指定的列前面,用于检索指定的列的不一样的值。好比,select count(distinct cust_id) from orders;
。
DISTINCT
做用于全部的列,而不是其后的那一列。好比,select count(distinct cust_id, order_num) from orders;
将搜索出cust_id不一样而且order_num不一样的列。
select * from orders limit 2 offerset 2;
select * from orders limit 2 , 2;
复制代码
相似于上面这样,前面的数字2表示查询的数目条数,后面的2表示从哪一个位置开始。因此,上面的效果是查询第2条和第3条数据。可是,要注意的是数据库中条的编号的起始位置是0。若是不指定第二个2将查出全部数据中前两个记录。
使用ORDER BY
语句。能够指定多个列进行排序,能够为要排序的列指定排序的方向,使用ASC
表示增序排列,使用DESC
表示降序排列。默认,升序排列。除了使用列名来指定要排序的列,害可使用列的在查询的全部列中的位置来指定排序的列。
DESC
只应用到直接位于其前面的列,若是要为多个列进行降序,就应该每一个列后面加上DESC
。
=
<>
和!=
<
和<=
>
和>=
IS NULL
BETWEEN
BETWEEN
实例:
SELECT * FROM orders WHERE order_num BETWEEN 20006 AND 30000;
复制代码
使用AND和OR操做符的时候要注意优先级是AND>OR
。好比,
select * from orders
where order_num = 20006 or order_num = 200005 and cust_id = 1000000001;
复制代码
会被当成
select * from orders
where order_num = 20006 or (order_num = 20005 and cust_id = 1000000001);
复制代码
而若是咱们想要表达的意思是:
select * from orders
where (order_num = 20006 or order_num = 200005) and cust_id = 1000000001;
复制代码
所以就要在OR操做符上面增长圆括号。
select * from orders where order_num in (20006, 20005);
复制代码
IN操做符其实完成的操做和OR同样。
select * from orders where not order_num = 20005;
复制代码
如上所示将not操做加在where条件的前面能够表示对条件的反。上面的效果就至关于where order_num != 20005
select * from orders t
where 1 = 1
and exists(select * from customers where cust_id = t.cust_id);
复制代码
select * from products where prod_name like '%doll';
复制代码
上面的是查找全部prod_name以doll结尾的记录。还能够,好比Fish%
用来匹配全部以Fish开头的,F%y
用来匹配以F开头而且以y结尾的记录。
通配符%能够用来匹配除NULL意外的记录,即WHERE prod_name like '%'
不会找出prod_name为NULL的记录。
下划线用来匹配指定数量的字符。一个下划线匹配一个字符。
select concat(cust_name,':',cust_city) from customers;
复制代码
如上所示,使用concat函数能够将查询结果拼接起来。
select concat(cust_name,':',cust_city) as cust_city from customers;
复制代码
如上所示,使用AS
操做符来将拼接的字符串命名为cust_city.
下面的是使用正则表达式对数据进行过滤的例子,便可以将REGEXP像like同样使用,并在REGEXP后面加上正则表达式便可。下面的表达式检索出的结果是,customers中全部cust_name中包含'Fun'的记录。
select * from customers where cust_name REGEXP 'Fun';
复制代码
下面的SQL语句用来搜索出全部prod_name开头字符包含在1,2,8以内,而且字符后面是' inch'的记录:
select * from products where prod_name regexp '[812] inch'
复制代码
select order_num, count(order_num) from orderitems group by order_num;
复制代码
使用GROUP BY
能够对数据进行分组,上面的效果是显示出指定order_num的记录的条数。
select t.*, sum(quantity*item_price) as total
from orders as t, orderitems
where t.order_num = orderitems.order_num
group by order_num;
复制代码
上面的语句的执行的结果是,获得了orders表的所有数据,以及每条订单对应的总价(根据orderitems表计算得出)。可是若是没有加入Group BY语句就没法获得上面的结果。
可使用下面的两个SQL语句的执行结果来理解GROUP BY语句的效果:
select sum(quantity*item_price) from orderitems;
select sum(quantity*item_price) from orderitems group by order_num;
复制代码
若是没加Group BY获得的是两个列的每条记录的两个字段相乘以后的总和,使用以后获得的是针对每一个order_num的两个字段相乘以后的总和。前面的只获得了一条记录,后面的获得了针对每一个order_num的记录。
下面的例子也使用了GROUP语句,可是这里在分组的时候的依据不是order_num而是cust_id。这样也是能够的,它获得的结果是:各个cust_id所应该支付的帐单总额。
select sum(i.quantity*i.item_price) as total
from orders as o, orderitems as i
where o.order_num = i.order_num
group by o.cust_id;
复制代码
若是咱们再关联一张customers表,来获得用户的名称,那么咱们能够写成下面的样子:
select c.cust_name as name, sum(i.quantity*i.item_price) as total
from orderitems as i, orders as o, customers as c
where i.order_num = o.order_num and c.cust_id = o.cust_id
group by c.cust_id;
复制代码
select sum(quantity * item_price) as total
from orderitems
group by order_num
having total > 1000;
复制代码
如上所示,咱们使用HAVING
语句来对分组以后的结果进行过滤。上面是找出总价值在1000以上的分组。
下面的使用了子查询的语句执行的结果与上面的同样:指定名称用户的总额。
select c.cust_name, (select sum(i.quantity*i.item_price)
from orderitems as i, orders as o
where i.order_num = o.order_num and c.cust_id = o.cust_id
group by o.cust_id) as total
from customers as c;
复制代码
上面的这种方式是将子查询用做计算字段。
子查询的另外一种是用方式是将子查询的结果放在一个IN中做为取值范围。
所谓的联结能够理解成按照指定的方式将两个或者多个表组合起来,造成一个相似于新的表。由于MySQL是关系型数据库,因此常常会在多个表之间存在一对多或者多对多关系,而联结的效果就是将这样的表联结起来。好比,若是两个数据库之间是一对多关系,那么确定有些字段只存在于父表中,在查询的时候咱们要将这些存在于父表中的字段与存在于子表中的字段组合起来,造成一个完整的“数据”,就应该使用联结来实现。
假若有这样的数据:
在表1中存储着:A0B0, A0B1 在表2中存储着:A0C0, A0C1, A0C2
这里的A, B, C表示的是数据库的列中存储的记录。A表示一个列中的数据,B也表示列中的数据,AB构成一个记录。
那么,若是咱们对表1和表2在A上面使用联结将获得的记录以下:
B0C0, B0C1, B0C2, B1C0, B1C1, B1C2
这就至关于咱们将B中的与A相关的字段补充了起来。
联结表的最多见的形式是使用=
将两表的对应的字段链接起来,这叫作等值联结。
下面是使用内联结的一个实现:
select vend_name, prod_name
from vendors as v inner join products as p
on v.vend_id = p.vend_id;
复制代码
内联结至关于对两个表在指定的列上面取交集,即只有两个表中都存在的字段才会进行联结。
select *
from customers as c1, customers as c2
where c1.cust_name = c2.cust_name
and c2.cust_contact = 'Jim Jones';
复制代码
上面的SQL语句的是自联结的,须要为两个相同的表分别指定一个别名。
所谓的外联结,就是指左联结和右联结。它跟内联结不一样的地方只在于,以左联结为例,若是左表中被用来指定联结的值在右表中不存在,那么也同样将左表中的记录检索出来,只是右表中指定的字段为NULL。
select vend_name, prod_name
from vendors as v left join products as p
on v.vend_id = p.vend_id;
复制代码
好比上面的SQL中,若是vendors中的vend_id在右表中不存在,那么prod_name做为NULL。同理,可得右联结。
联结的语法:
LEFT [OUTER] JOIN,左外链接。
RIGHT [OUTER] JOIN,右外链接。
复制代码
这里的OUTER是可选的,有没有都行。
select prod_name from products
union
select vend_name from vendors;
复制代码
使用UNION
能够将两个分别独立的SQL查询的结果合并起来。(可是要求两个SQL检索出的列的数目要相等,其实它的效果和OR差很少)
若是查询出来的两条记录同样,重复的行会被取消,可使用UNION ALL
关键字来替代UNION
,这样重复的行就不会被取消。
使用UNION组合查询的时候,只能有一条ORDER BY子句,且必须位于最后一条SELECT语句的后面。
视图能够用来简化SQL操做,你能够将一次的查询结果做为一个视图,并为其添加一个名称,好比A。而后,咱们能够像使用一个表同样从A中检索出数据。
视图的建立语句以下:
create view orderdetail as
select o.*, i.order_item, i.prod_id, i.quantity, i.item_price
from orders as o left join orderitems as i
on o.order_num = i.order_num;
复制代码
即在一个标准的查询语句上面增长一个create view orderdetail as
语句来建立视图。建立完毕视图以后,咱们就能够像使用表同样从视图中检索数据。好比:
select * from orderdetail order by cust_id;
复制代码
存储过程和视图类似,也是提供一种SQL复用的机制。由于自己视图只能用来将指定的数据检索出来做为数据表同样使用,它自己只能用于“查询”操做,具备必定的局限性。所以,这里有存储过程来将指定功能的SQL封装起来,使其像一个函数同样能够被调用。
存储过程的可移植性比较差,并且须要更高的技能和经验,所以经过被限制建立。
在MySQL命令行中建立存储过程的示例:
mysql> delimiter //
mysql> create procedure mypp()
-> begin
-> select * from orders;
-> end//
复制代码
在这里delimiter //
的做用是使用//
而不是';'做为语句分隔符。
MySQL支持IN(传递给存储过程)、 OUT(从存储过程传出,如这里所用)和INOUT(对存储过程传入和传出)类型的参数。
mysql> create procedure avgprice(in num int, out price decimal(8,2))
-> begin
-> select avg(item_price)
-> from orderitems
-> where order_num = num
-> into price;
-> end//
复制代码
上面的语句中建立了一个名为avgprice的存储过程。它接受两个参数,num是传入的参数;price是传出的参数。在存储过程内部,咱们为orderitems的指定order_num为num的全部记录的平均item_price赋值非price.
建立完毕了存储过程以后,咱们能够像下面这样调用以上存储过程:
call avgprice(20009, @price);
复制代码
而后,咱们可使用SELECT语句获得price的计算结果:
select @price
复制代码
没有参数的存储过程的使用示例:
call mypp();
复制代码
drop procedure mypp;
复制代码
show create procedure avgprice;
复制代码
MySQL游标只能用于存储过程(和函数)
mysql> create procedure copyprodname()
-> begin
-> --定义局部变量,结束条件
-> declare done boolean default 0;
-> --定义局部变量,产品名称
-> declare name varchar(255);
->
-> --定义游标
-> declare names cursor
-> for
-> select prod_name from products;
->
-> --定义循环结束条件
-> declare continue handler for sqlstate '02000' set done = 1;
->
-> --建立表
-> create table if not exists prod_name(name varchar(255));
->
-> --打开游标
-> open names;
->
-> --定义循环
-> repeat
-> --获取游标的数据,将其填充到name中
-> fetch names into name;
-> --将游标中的数据插入到prod_name表中
-> insert into prod_name values(name);
-> --定义循环的结束条件
-> until done end repeat;
->
-> --结束游标
-> close names;
-> end//
复制代码
在上面的代码中,使用
declare done boolean default 0;
复制代码
定义了循环的条件为布尔类型,并将其默认值设置为0. 而后,使用定义了循环结束的条件
declare continue handler for sqlstate '02000' set done = 1;
复制代码
这里的'02000'是一个未找到条件, 当REPEAT因为没有更多的行供循环而不能继续时,出现这个条件。在使用游标以前,须要先打开游标。这经过SQL语句:
open names;
复制代码
来完成。当咱们执行完业务逻辑以后,须要关闭游标。这经过SQL语句:
close names;
复制代码
来完成。在游标的打开和关闭的做用域内,咱们经过
fetch names into name;
复制代码
将从游标中获得的数据填充到name中。
触发器用来在某事件发生时自动执行,有些相似于监听器的做用。它只能为delete, insert, update三种操做设置触发器。触发器能够设置在指定的操做执行以前或者以后触发。
只有表才支触发器,视图和临时表都不支持。
每一个表最多设置6个触发器,且同一触发器不能与多个事件或多个表关联。
触发器建立的基本语法格式:
CREATE TRIGGER <触发器名称> --触发器必须有名字,最多64个字符
{ BEFORE | AFTER } --触发器有执行的时间设置:能够设置为事件发生前或后。
{ INSERT | UPDATE | DELETE } --触发的事件:insert、update或delete的过程当中触发。
ON <表名称> --触发器是属于某一个表的:当在这个表上执行插入、 更新或删除操做的时候就触发。
FOR EACH ROW --触发器的执行间隔:FOR EACH ROW子句通知触发器 每隔一行执行一次动做,而不是对整个表执行一次。
<触发器SQL语句> --触发器包含所要触发的SQL语句:这里的语句能够是任何合法的语句, 包括复合语句,可是这里的语句受的限制和函数的同样。
复制代码
触发器的使用示例:
mysql> create trigger watcher after insert on prod_name
-> for each row
-> begin
-> insert into prod_name_copy values(new.name);
-> end//
复制代码
上面的触发器监听prod_name表的插入操做,每当向表prod_name中插入一条记录的同时向prod_name_copy也插入一条记录。
insert触发器代码内,能够引用一个名为new的虚拟表,访问被插入的行。
delete触发器代码内,能够引用一个名为old的虚拟表,访问被删除的行。
update触发器代码内,可使用一个名为old的虚拟表,访问更新以前的数据,使用名为new的虚拟表,访问更新的值。
DROP TRIGGER 触发器名称:
复制代码
事务保证了一系列操做的原子性,只有当执行过程当中没有产生错误,而且提交了以后才会将执行的结果反应到数据库上。若是使用了回滚操做将回复到开始事务以前的状态。
MySQL中的数据库引擎分别支持不一样类型的事务。
开始事务可使用下面的语句:
START TRANSACTION;
复制代码
回滚事务使用:
ROLLBACK;
复制代码
提交事务使用:
COMMIT;
复制代码
可使用语句
SAVEPOINT 名称;
复制代码
来建立保留点。在准备回滚的时候,咱们可使用
ROLLBACK TO 名称;
复制代码
来回滚到指定的保留点。这样指定保留点以前的操做不会回滚,而保留点以后的操做将所有被会滚。
一般,保留点越多越好。当提交或者回滚以后,保留点会被自动释放。此外,也可使用RELEASE
来主动释放保留点。
使用
SET autocommit = 0;
复制代码
来设置不自动提交。
在MySQL的数据库中存在一个mysql库,那里面的user表用于存储MySQL的用户。
create user shouheng identified by 'psd';
复制代码
上面的SQL用来MySQL中添加一个用户。若是要对用户进行重命名,可使用:
rename user little_boy to shouheng;
复制代码
若是删除用户可使用:
drop user username;
复制代码
查看授予用户的权限:
show grants for shouheng;
复制代码
授予权限:
grant select on sql_test_db.* to shouheng;
复制代码
以上操做用来将sql_test_db的全部数据的只读权限授予指定用户。若是要回收指定用户的权限,可使用
revoke select on sql_test_db.* from shouheng;
复制代码
它表示回收指定用户对sql_test_db的只读权限。
除了上面示例的只读权限之外,MySQL还容许为新加入的用户指定其余权限。
为指定的用户修改密码:
set password for shouheng = Password('psd');
复制代码
一、该项目整理了设计模式、Java语法、JVM、SQL、数据结构与算法等相关内容:https://github.com/Shouheng88/Java-Programming。
二、因为时间仓促,难免于存在错误,欢迎批评指正。