接下来的一些内容,我们需要提前学一些简单的sql语句,方便大家理解接下来的知识。
DDL—数据定义语言(Create,Alter,Drop,DECLARE)
DML—数据操纵语言(Select,Delete,Update,Insert)
DCL—数据控制语言(GRANT,REVOKE,COMMIT,ROLLBACK)
DQL-数据查询语言(select)
DML(data manipulation language):
它们是SELECT、UPDATE、INSERT、DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言
DDL(data definition language):
DDL比DML要多,主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定义或改变表(TABLE)的结构,数据类型,表之间的链接和约束等初始化工作上,他们大多在建立表时使用
DCL(Data Control Language):
是数据库控制功能。是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。在默认状态下,只有sysadmin,dbcreator,db_owner或db_securityadmin等人员才有权力执行DCL
-----------------------------------------
接下来我们逐步学习SQL语句,在学习之前我们先注意一下SQL语句的注意事项.
1.每条SQL语句结束时要以;做为结束符.(除了use命令)
2.SQL语句的关键字不区分大小写(除了库名字和表名字)
3.在查询数据库信息或者表信息时,可以以G做为结束符,表示以文本模式输出
4.当你不需要一条语句输出的结果以c结束,不可以使用ctrl+c,否则登出mysql.
5.我们可以在命令行执行sql语句,要通过mysql -e参数
mysql -e "show databases G" 显示到shell上
6.如果需要获取SQL语句的帮助可以用help命令
如:help create
如果需要进一步获取帮助,可以继续使用help命令
如:help create database
---------------------------------------------------
1.DDL数据库定义语句
建立数据库以及查询
create database db;
create database db CHARACTER SET = 'utf8'
show database;
show create database db;
alter database db CHARACTER SET = 'latin1';
修改库名只需要改数据库目录名称
drop database db;
建立表以及查询
数据类型
数值类型
整数类型 字节 范围(有符号) 范围(无符号) 用途
TINYINT 1字节 (-128,127) (0,255) 小整数值
SMALLINT 2字节 (-32 768,32 767) (0,65 535) 大整数值
MEDIUMINT 3字节 (-8 388 608,8 388 607) (0,16 777 215) 大整数值
INT或INTEGER 4字节 (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整数值
BIGINT 8字节 (-9 233 372 036 854 775 808,9 223 372 036 854 775 807) (0,18 446 744 073 709 551 615) 极大整数值
FLOAT 4字节 (-3.402 823 466 E+38,1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) 0,(1.175 494 351 E-38,3.402 823 466 E+38) 单精度浮点数值 (7个有效位)
DOUBLE 8字节 (1.797 693 134 862 315 7 E+308,2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 双精度浮点数值 (15个有效位)
DECIMAL 不存在精度损失,常用于银行帐目计算。(28个有效位)
默认整数类型有符号
mysql> create table t2(id tinyint);
mysql> create table t3(id tinyint UNSIGNED);
unsigned 表示有无符号
不足5位,用0补齐
mysql> create table t5(id int(5) zerofill);
mysql> insert into t5 values(1);
mysql> insert into t5 values(2);
mysql> select * from t5;
+-------+
| id |
+-------+
| 00001 |
| 00002 |
+-------+
浮点数类型
float类型出现不精确情况
mysql> create table t1(money float(10,2));
Query OK, 0 rows affected (0.05 sec)
mysql> insert into t1 values(697302.68);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t1;
+-----------+
| money |
+-----------+
| 697302.69 |
+-----------+
1 row in set (0.01 sec)
超出数值范围
mysql> create table t1(age tinyint);
Query OK, 0 rows affected (0.08 sec)
mysql> insert into t1 values(500);
ERROR 1264 (22003): Out of range value for column 'age' at row 1
mysql> select @@sql_mode
-> ;
+--------------------------------------------+
| @@sql_mode |
+--------------------------------------------+
| STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |
+--------------------------------------------+
1 row in set (0.00 sec)
mysql5.0以上版本支持三种sql_mode模式:ANSI、TRADITIONAL和STRICT_TRANS_TABLES。
ANSI模式:宽松模式,对插入数据进行校验,如果不符合定义类型或长度,对数据类型调整或截断保存,报warning警告。
TRADITIONAL模式:严格模式,当向mysql数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,报error错误。用于事务时,会进行事务的回滚。
STRICT_TRANS_TABLES模式:严格模式,进行数据的严格校验,错误数据不能插入,报error错误。
临时修改模式:可以插入数据,报warning
mysql> set @@sql_mode=ANSI;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t1 values(500);
Query OK, 1 row affected, 1 warning (0.01 sec)
如果需要永久设置为ANSI模式,需写入配置/etc/my.cnf
-------------------
字符串类型
char() 定长
varchar() 变长
create table t1(id int(6),name char(10));
create table t1(id int(6),name varchar(10));
日期时间类型
date类型
create table t4(aa date);
insert into t4 values('2010-04-01'),(20100401);
select * from t4;
+------------+
| aa |
+------------+
| 2010-04-01 |
| 2010-04-01 |
+------------+
time类型
create table t5(showttime time);
insert into t5 values ('11:11:11'),('11:11'),('111111');
select * from t5;
+-----------+
| showttime |
+-----------+
| 11:11:11 |
| 11:11:00 |
| 11:11:11 |
+-----------+
出现的问题
create table t6 (a_data data,a_time time);
insert into t6 values('1978-4-6',123412),(651212,'3:5:6');
select * from t6;
+------------+----------+
| a_date | a_time |
+------------+----------+
| 1978-04-06 | 12:34:12 |
| 2065-12-12 | 03:05:06 |
+------------+----------+
年份的范围00-69为2000-2069&&70-99为1970-1999
year类型
create table t7 (year year);
insert into t7 values(2003),(04),(53),(89),(90);
select * from t7;
+------+
| year |
+------+
| 2003 |
| 2004 |
| 2053 |
| 1989 |
| 1990 |
+------+
datetime和timestamp类型
create table t8(f_datetime datetime,f_timestamp timestamp);
insert into t8 values('1999-11-11 11:11:11','2002-11-111:11:11');
insert into t8 values(19991111111111,20021111111111);
insert into t8 values(now(),null);
select * from t8;
+---------------------+---------------------+
| f_datetime | f_timestamp |
+---------------------+---------------------+
| 1999-11-11 11:11:11 | 2002-11-11 11:11:11 |
| 1999-11-11 11:11:11 | 2002-11-11 11:11:11 |
| 2012-03-21 21:05:21 | 2012-03-21 21:05:21 |
+---------------------+---------------------+
mysql> create table t15(name char(10),t_datetime datetime,t_timestamp timestamp);
mysql> insert into t15 values('robin',20160906101010,20151010101010);
mysql> select * from t15;
+-------+---------------------+---------------------+
| name | t_datetime | t_timestamp |
+-------+---------------------+---------------------+
| robin | 2016-09-06 10:10:10 | 2015-10-10 10:10:10 |
+-------+---------------------+---------------------+
mysql> insert into t15 values('robin',null,null);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t15;
+-------+---------------------+---------------------+
| name | t_datetime | t_timestamp |
+-------+---------------------+---------------------+
| robin | 2016-09-06 10:10:10 | 2015-10-10 10:10:10 |
| robin | NULL | 2016-09-03 12:05:03 |
+-------+---------------------+---------------------+
2 rows in set (0.00 sec)
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2016-09-03 12:06:51 |
+---------------------+
1 row in set (0.00 sec)
mysql> insert into t15 values('robin',now(),now());
Query OK, 1 row affected (0.01 sec)
mysql> select * from t15;
+-------+---------------------+---------------------+
| name | t_datetime | t_timestamp |
+-------+---------------------+---------------------+
| robin | 2016-09-06 10:10:10 | 2015-10-10 10:10:10 |
| robin | NULL | 2016-09-03 12:05:03 |
| robin | 2016-09-03 12:07:13 | 2016-09-03 12:07:13 |
+-------+---------------------+---------------------+
3 rows in set (0.00 sec)
mysql> update t15 set name='zorro' where name='robin' and t_datetime = '2016-09-03 12:07:13';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from t15; +-------+---------------------+---------------------+
| name | t_datetime | t_timestamp |
+-------+---------------------+---------------------+
| robin | 2016-09-06 10:10:10 | 2015-10-10 10:10:10 |
| robin | NULL | 2016-09-03 12:05:03 |
| zorro | 2016-09-03 12:07:13 | 2016-09-03 12:10:30 |
+-------+---------------------+---------------------+
timestamp 不能为空值 其他列的变化会使timestamp类型关联变化
-----------------------------------------
ENUM和SET类型
create table t10(gerder ENUM('M','F'));
insert into t10 values('M'),('m'),('F'),('aa'),(null);
select * from t10;
+------+
| gender |
+------+
| M |
| M |
| F |
| |
| NULL |
+------+
create table t11 (type SET('a','b','c','d','e'));
insert into t11 values(a);
insert into t11 values('b,c');
insert into t11 values('J');
select * from t11;
+------+
| type |
+------+
| a |
| b,c |
| |
+------+
insert into t11 values('b,c,e,f');既有合法字符又有非法字符
select * from t11;
+-------+
| type |
+-------+
| a |
| b,c |
| |
| b,c,e |
+-------+
练习:
创建表test id name money gender hobby email qq idcardl jointime
create table test(id tinyint,name char(10),money float(10,2),gender enum('M','F'),hobby set('a','b','c'),email varchar(50),qq char(15),shenfenzheng char(18),jointime datetime);
mysql> rename table test to newtest;
mysql> alter table test change id uid smallint;
mysql> alter table test modify id smallint;
------------------------------------------------------
修饰符(约束)
无符号 unsigned
用0补齐 zerofill
desc t11;
+-------+--------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------------------+------+-----+---------+-------+
| type | set('a','b','c','d','e') | YES | | NULL | |
+-------+--------------------------+------+-----+---------+-------+
not null约束
create table t12 (id int,gender enum('M','W') NOT NULL );
desc t12;
+-------+---------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------------+------+-----+---------+-------+
| id | int(10) unsigned zerofill | YES | | NULL | |
| gender | enum('M','W') | YES | | NULL | |
+-------+---------------------------+------+-----+---------+-------+
insert into t12(id) values(1);
Query OK, 1 row affected (0.00 sec)
select * from t12;
+---+-----+
|id | gender |
+---+-----+
| 1 | NULL|
+---+-----+
DEFAULT约束
create table t13 (id int ,gender enum('M','W') NOT NULL default 'M' );
desc t13;
+-------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| gender | enum('M','W') | YES | | M | |
+-------+---------------+------+-----+---------+-------+
insert into t13(id) values(3);
select * from t13;
+------+------+
| id | gender |
+------+------+
| 2 | M |
| 3 | M |
+------+------+
AUTO_INCREMENT修饰符自动增长只适用于int字段 一般用于主键 一个表只能有一个
create table t14(id int auto_increment primary key,name char(10) not ll);
desc t14
+-------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | char(10) | NO | | NULL | |
+-------+----------+------+-----+---------+----------------+
insert into t14(name) values(zhb);
insert into t14(name) values('haha');
select * from t14;
+----+------+
| id | name |
+----+------+
| 1 | zhb |
| 2 | haha |
+----+------+
索引建立
create table t15(id int not null ,name char(10),index(id));
desc t15;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | NO | MUL | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
向已有表添加索引
create table t16(id int not null ,name char(10));
desc t16;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
create index id on t16 (id);
alter table t17 add index(id);
desc t16;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | NO | MUL | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
删除索引
drop index id on t16;
desc t16;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
查询索引
show index from t16;
UNIQUE索引(允许空值)
create table t17(id int ,name char(10),unique(id));
desc t17;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | YES | UNI | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
insert into t17 values(null,'zhb');
select * from t17;
+------+------+
| id | name |
+------+------+
| NULL | zhb |
+------+------+
mysql> show index from t6G
mysql> drop index id on t6;
mysql> create unique index id on t6(id);
PRIMARY KEY(主键约束 值唯一 uniq和not null的结合)
一个表中只能有一个主键,但是一个主键可以作用在多个列上
create table t18(id int,name char(10),primary key(id));
desc t18;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | NO | PRI | 0 | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
insert into t18 values(1,'zhb');
select * from t18;
+----+------+
| id | name |
+----+------+
| 1 | zhb |
+----+------+
insert into t18 values(1,'zhb');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY' 不允许重复
删除主键
mysql> alter table t19 drop primary key;
向已有表添加主键
mysql> alter table t19 add primary key(id);
在多个列上建立主键
create table t19(id int,name char(10),primary key(id,name));
desc t19;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | NO | PRI | 0 | |
| name | char(10) | NO | PRI | | |
+-------+----------+------+-----+---------+-------+
insert into t19 values(1,'zhb');
insert into t19 values(1,'zorro');
select * from t19;
+----+-------+
| id | name |
+----+-------+
| 1 | zhb |
| 1 | zorro |
+----+-------+
外键myisam引擎不支持只能用innodb引擎
create table dpmnt(id int not null,name char(10) not null,primary key(id)) type = INNODB;
desc dpmnt;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | char(10) | NO | | NULL | |
+-------+----------+------+-----+---------+-------+
建立外键
create table emp (id int not null, name char(10) not null,fk_dpmnt int not null ,primary key(id),index (fk_dpmnt),foreign key (fk_dpmnt) references dpmnt(id)) type=innodb;
desc emp;
+----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | char(10) | NO | | NULL | |
| fk_dpmnt | int(11) | NO | MUL | NULL | |
+----------+----------+------+-----+---------+-------+
insert into dpmnt values(1,hr);
insert into dpmnt values(2,'yw');
insert into emp values(10,'zhb',3);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`db`.`emp`, CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`fk_dpmnt`) REFERENCES `dpmnt` (`id`))
fk_dpmnt字段的数据必须得是dpmnt表里有的不然报错...
即使表存在外键约束,MySQL还允许我们删除表,并且不会产生错误。这是删除外键的方法。
alter table emp drop foreign key emp_ibfk_1;
删除外键
全文本索引
create table t22(id int,name char(10),fulltext(id));
创建表 id name age gender hobby email phone qq money
自己选择合适的类型和修饰 必须出现 primary key index unique not null
defalt
alter 去掉修饰
alter 添加所有修饰
练习:
创建表test id name money gender hobby email qq shenfezheng jointime
create table test(id tinyint,name char(10),money float(10,2),gender enum('M','F'),hobby set('a','b','c'),email varchar(50),qq char(15),shenfenzheng char(18),jointime datetime);
1.添加约束
create table test1 ( id int primary key auto_increment, name char(20) not null, money float(10,2) not null, gender enum('M','F') not null default 'M', hobby set('a','b','c') not null default 'a', qq char(15) unique, email char(50), jointime datetime,index(email));
2.删除掉所有的约束
alter table test1 modify id int; 删除auto_increment
alter table test1 drop primary key; 删除primary key
alter table test1 modify id int; 删除 not null
alter table test1 modify name char(10);//删除 not null
alter table test1 modify money float(10,2);
alter table test1 modify gender enum('M','F');
alter table test1 modify hobby set('a','b','c');
drop index qq on test1; //删除unique索引
drop index email on test1; //删除index索引
3.在添加约束
alter table test1 add primary key(id);
alter table test1 modify id int auto_increment;
alter table test1 add unique phone;
show tables;
show create table t1;
ALTER table t2 RENAME t1;
alter table t2 MODIFY a tinyint not null,CHANGE b c char(20);
create table members ( id int(11),name char(10),tel char(15));
alter table members ADD qq int;
alter table members drop qq;
alter table members add qq int after name ;
alter table members add phone first;
alter table test1 modify qq char(15) after id;
drop table t1;
2.DML 数据库操作语句
insert
mysql> INSERT INTO members ( member_id,fname,lname,tel,email) VALUES ( NULL,'john','Doe','1234567','jdoe@163.com');
mysql> INSERT INTO members VALUES ( NULL,'kyo','oyk','7654321','kyo@163.com');
mysql> INSERT INTO members (fname,lname,email,tel,member_id) VALUES ('bob','kk','bob@163.com','22334455',NULL);
update
mysql> UPDATE members SET email = 'kyo@163.com' WHERE member_id = 3;
mysql> UPDATE members SET email = 'hoho@163.com',lname = 'ho' WHERE member_id = 2;
delete
mysql> DELETE FROM members;
mysql> DELETE FROM members WHERE member_id = 1;
sql语句使用
连接数据库
mysql -u root -p123 -h localhost
查看服务器状态
show staus;
显示所有库名
show databases;
使用数据库
use db;
显示当前数据库中的所有表
show tables;
查看表结构
desc tables;
select查询语句
select name from tables; 从表中查询指定列
select id,name,sal from tables; 指定多个列名
select * from tables;查询所有的列
select distinct id from tables; 去掉重复行
select name from tables limit 5; 显示前5行
select name from tables limit 5,5;显示从第5行开始的后5行即6-10行
select name from db.t1;没有使用use进入db库时查询db库的t1表
select t1.name from db.t1; 指定库的表 指定表的列
显示mysql中第一个用户名字?
在shell命令行显示用户的名字和密码
显示mysql中的前3个用户
-------------------------------------
修改root帐号密码为456
[root@robin mysql]# /usr/local/mysql/bin/mysqld_safe --user=mysql --skip-grant-tables &
mysql> update mysql.user set password=password('123') where user='root' and host='localhost';
排序检索语句
select id,name from t1 order by id; 按id排序
select id,name from t1 order by id,name;先按id排序id相同在按name排序
select id,name from t1 order by id desc; 按id反向排序
select id,name from t1 order by id desc,name; 先按id反向排序再按名字排序
select id,name,sal from t1 order by sal desc limit 1;查找工资最高的人
where子句
select id,name,sal from t1 where name='tom'; 查找tom的信息
where 子句的操作符
= 等于
<> 不等于
!= 不等于
< 小于
<= 小于等于
> 大于
>= 大于等于
between 5 and 10 在两个值之间
is null 空值
is not null 非空值
select id,name from t1 where id>5 and name='tom'; and操作符表示两个条件都要满足 与操作
select id,name from t1 where id=10 or name='tom';or操作符表示满足任意条件 或操作
select id,name,sal from t1 where id=10 or id=20 and sal > 5000; id为10的 或者id为20并且薪水大于5000的;and优先执行
select id,name,sal from t1 where (id=10 or id=20) and sal > 5000;id为10或者20 并且薪水大于5000的
select id,name,sal from t1 where id in (10,20,30);id在 10 20 30 中的记录
这条语句用or可以做到相同的结果,那in的好处
1.in的语法更加直观
2.in的计算次序更容易管理(操作符少)
3.in 一般比or执行的更快
4.in的最大优点可以包含其他子句 or不行
取最高薪水的人
select * from test2 where money=(select money from test2 order by money desc limit 1);
select id,name,sal from t1 where id not in (10,20,30); id不在10 20 30的记录 not找到不匹配的记录更简单
通配符%匹配多个字符_匹配一个字符
select id,name from t1 where name like 'jer%';模糊查询名字为jer开头的记录
select id,name from t1 where name like 'j%y'; 匹配j开头y结尾的
select id,name from t1 where name like '_err%' 匹配e前边有一个字符的记录
原则:
尽量少使用通配符,如果其他操作符能做到就不要使用通配符
在确实需要通配符时,尽量不要使用%erry 这种用法搜索起来会更慢
至于使用位置,使用错了得不到想要的结果
正则表达式的使用regexp
select id,name from t1 where name regexp 'je*';调用正则匹配je开头
select id,name from t1 where name regexp 'y$';
语句的拼接
select concat(id ,'(',name,')') from t1 将id和name 拼接为1列 oracle用||
select concat(id ,'(',name,')') all_name from t1 别名也可以使用as
select sal*12 from t1 计算全年薪水 + - * /
mysql> select concat(id,'name') from g1;
+-------------------+
| concat(id,'name') |
+-------------------+
| 1name |
| 2name |
+-------------------+
2 rows in set (0.00 sec)
函数使用
select upper(name) as new_name from t1; 将名字转换为大写 lower 小写
group by 分组 必须在where之后 分组前过滤 having 可以分组后过滤
sum max min avg count year month day hour minute second
ysql> alter table g1 rename h1; //改表名