TCP/IP套接字方式
mysql [-h 主机IP -P 端口号]
-u 用户名
-p密码
[数据库名] -e 'sql语句';
//最后加上数据库名可直接选中数据库
Unix域套接字
该方式只适用于mysql客户端和数据库实例在同一台服务器上的情况.
先找出Unix域套接字文件位置
SHOW VARIABLES LIKE 'socket';
-> /tmp/mysql.sock //在该位置
接着就可以用它连接了
mysql -S /tmp/mysql.sock -u 用户名 -p 密码
EXIT;
SELECT version();
SHOW databases;
DROP database 数据库名;
USE 数据库名;
SELECT database();
SHOW tables;
OR
SHOW tables from 数据库名;
DESC 表名;//基本表结构
or
SHOW CREATE TABLE 表名;//详细表结构
SHOW TABLE STATUS LIKE '表名';
CREATE TABLE 表名(
列名 列类型 not null primary key,
列名 列类型 auto_increment,
列名 列类型 default(value),
constraint 约束名 foreign key(列名) references 另一个表名(列名)
. . .
);
方式1:
CREATE TABLE 新表名
AS
SELECT * FROM 旧表名;
方式2:
SELECT *
INTO 新表名
FROM 旧表名
[WHERE condition]; //添加过滤条件可插入部分记录.
方式3:
INSERT INTO 新表名
SELECT * FROM 旧表名;
DROP TABLE 表名;
⚠️若要删除的表中有外键约束,需要先删除外键约束,再用上述命令删除表.
ALTER TABLE 旧表名 RENAME TO 新表名;
MODIFY
,CHANGE
)ALTER TABLE 表名 MODIFY 字段名 要修改的字段类型
[添加一些约束,如not null, unique, default xxx]
or 修改字段名如下
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 新字段类型; 、
ADD
,DROP
)ALTER TABLE 表名 ADD 字段名 字段类型;
or
ALTER TABLE 表名 DROP 字段名;
INSERT INTO 表名(C1,C2,...,Cn)
VALUES(....,
....,
.....);
DELETE FROM 表名
WHERE 过滤条件;
//不加过滤条件则删除整张表记录
UPDATE 表名
SET 列1=值1,列2=值2,...
WHERE 过滤条件;
用以区分关键字和字段名,如
SELECT NAME FROM xxx
中NAME为关键字,易引起歧义,故可加上着重号表示它为字段名而非关键字,即
SELECT `NAME` FROM xxx
在mysql中,+号只表示为运算符.
CASE1: SELECT 10+90; 结果为100.
CASE2: SELECT ‘10’+90; 结果也为100,即若其中一方为字符型,mysql试图会将其转换成数值型,并做加法运算.
CASE3: SELECT ‘cjy’+90; 结果为90,即若其中一方的字符型转换失败,mysql将其视为0.
CASE4: SELECT NULL+90; 结果为NULL.
%号表示 匹配任意多个字符,包括0个.
_ 号表示 匹配单个字符.
若不想让#或者_作为通配符,即想匹配#或者_,则可使用转义字符 \;或者用关键字ESCAPE,如:
SELECT DISTINCT last_name
FROM employees
WHERE last_name LIKE '\_!_%' ESCAPE '!'
既可以判断普通数值型或字符串型,相当于 = ,也可以判断NULL值,如:
WHERE commission_pct IS NULL 相当于 WHERE commission_pct <=> NULL.
ISNULL(expr),若expr为NULL,则返回1,否则,返回0.
SELECT CONCAT('Michael',' ', 'Jordan');
-> Michael Jordan
SELECT TRIM(leading '*' from '!!!hitccc!!!');
-> hitccc!!!
SELECT TRIM(both '!' from '!!!hitccc!!!'); //不加分类符时默认为both
-> hitccc
SELECT TRIM(trailing '!' from '!!!hitccc!!!');
-> !!!hitccc
----------------
TRIM() 还可用于去掉空格,另 LTRIM() 去左边空格, RTRIM() 去右边空格
//replace函数
SELECT REPLACE('mysql is the best','mysql','sql server');
-> sql server is the best
//insert函数
SELECT INSERT('hello world!',1,5,'my');
-> my world!
SELECT INSERT('hello world!',7,0,'my ')
-> hello my world!
SELECT lpad('hitccc',10,'*'); //其中,10为填充后的字符串长度
-> ****hitccc
SELECT rpad('hitccc',10,'*');
-> hitccc****
SELECT length('hitccc'); /*一个英文字符1字节,一个汉字3字节*/
-> 6
SELECT substr('hello world!',1,5);
-> hello
SELECT instr('hitccc','c');
-> 4
SELECT vchar_fld FROM string_tb1;
-> This is a piece of cake.
SELECT position('piece' IN vchar_fld) FROM string_tb1;
-> 11
SELECT round(-1.65);
-> -2
SELECT round(-1.65,1);
-> -1.7
SELECT round(17,-1);
-> 20
SELECT truncate(-1.42424,2);
-> -1.42
SELECT TRUNCATE(17,-1);
-> 10
SIGN(a) 用于返回a的符号,有-1,0,1.
ABS(a) 用于返回a的绝对值.
SELECT date_add(current_date(),INTERVAL 5 year);
-> 2024-09-15
注:INTERVAL为关键字,时间间隔单位可取 second /minute /hour /day /year /month,另外,还可取较为特殊的hour_second,year_month……(如下)
SELECT date_add(NOW(), INTERVAL '3:30:12' hour_second);
-> 2019-09-16 00:31:42
SELECT dayname('2019-10-01');
-> Tuesday
SELECT extract(year FROM now());
-> 2019
SELECT datediff('2019-9-01','2019-10-01');
-> -30
SELECT str_to_date('4-3 1989','%c-%d %Y');
-> 1989-04-03
SELECT date_format('2019/12/22','%Y年%m月%d日');
-> 2019年12月22日
日期格式 | 对应描述 |
---|---|
%a | 缩写星期名 |
%c或者%m | 月份序号(01~12) |
%M | 月名称(1月~12月) |
%d | 日序号(01~31) |
%j | 日在一年中的序号(01~366) |
%W | 星期名称(星期一~星期日) |
%Y | 4位数字的年份 |
%y | 2位数字的年份 |
%H | 小时(01~24) |
%h | 小时(01~12) |
%i | 分钟(00~59) |
%s | 秒钟(00~59) |
%f | 微秒(000000~999999) |
%p | A.M.或者P.M. |
类型可为
BINARY
,CHAR
,SIGNED
,UNSIGNED
,DATE
,DATETIME
,TIME
等等.
SELECT cast('-1234.32' AS SIGNED INTEGER);
-> -1234
group by 字段名 可按字段名进行分组
group by子句中可以增加WITH ROLLUP
选项,作用是在原来分组的基础上再增加几行进行统计汇总,下面是一个具体例子.
SELECT `Grade`,`Class`,SUM(`Stu_num`)
FROM explain_rollup
GROUP BY Grade, Class WITH ROLLUP;
可以理解为从不同的维度再计算一下.
顾名思义,聚集函数是以分组为单位,对分组中的所有行进行的特定操作.
⚠️:在使用这些聚集函数时,最好用显示分组方式,即用group by子句,否则可能会报错. 隐式分组即为整张表.
可用 COUNT(DISTINCT 字段名) 的组合来查询分组的指定列中不同值的个数.
聚集函数中的参数可以是表达式.
对于Count()函数,Count(*) 不会忽略null值,即有多少行就返回多少行数,而Count(列名) 则会忽略该列名中为null值的那些行,返回的行数中不包括null值.
聚集函数不能用在where子句中,只能用在having子句中.
除Count()函数外,其他几个聚集函数会自动忽略null值
Max()和Min()函数中的参数可以是字符串型数据、日期型数据.字符串就是看字典序来确定大小,日期型数据就是根据时间的早晚来确定,越早越小.
inner join
,若不指定连接条件则退化为交叉连接. 在关键字on
后给出连接条件,可为等值连接和非等值连接.等值连接 A inner join B on A.列名 = B.列名;
非等值连接可为 不等号,between … and … 等.
e.g. A inner join B on A.列名 between B.列名1 and B.列名2
可分为左外连接、右外连接和全外连接.
left [outer] join
,可理解为左边的表为主表,右边的表为副表,使用左外连接操作返回的结果中左表中原有的记录都要出现,右表中的列值可为null值.right [outer] join
,意思和上面类似,此时右边的表决定结果集合中的行数.full [outer] join
,很遗憾,MySQL8.0暂不支持全外连接,使用这个关键字会报错. 我们可以用 左外连接+右外连接 这个组合来实现全外连接,即全外连接实际上就是左外连接和右外连接的并集.cross join
,其实本质就相当于笛卡尔积.e.g. 若表A有m行记录,表B有n行记录,那么做 A cross join B 的操作结果会返回m*n行记录.
natural join
,不用给出连接条件,数据库服务器会自动找出两张表中列名相同的两列进行等值连接,若没有两列的列名是一样的,那么很抱歉,自然连接会自动退化成交叉连接,且系统不会报错.- IF(condition,a,b)
若condition为真,则返回a;否则,返回b.
e.g.
SELECT last_name, commission_pct, if(isnull(commission_pct) = 1,'呵呵','哈哈') as 备注
from employees;
//上述SQL语句表示若员工奖金率为空值,则返回 ‘呵呵’,否则,返回 ‘哈哈’.
- 简单型case表达式:
CASE 字段名或表达式
when 值1 then 结果1
when 值2 then 结果2
when 值3 then 结果3
. . .
else 结果N
end
- 查找型case表达式:
CASE
when 条件1 then 结果1
when 条件2 then 结果2
. . .
else 结果N
end
查找型case表达式相较于第一种来说更加的灵活,简单型case表达式只能用于等式条件,即CASE后面的字段名活着表达式在下面对号入座,而查找型case表达式可以构造不等式条件. 第一种类似于C语言中switch语句.
⚠️ 上面两个表达式的返回表达式就是then后面的一个结果i.
case表达式用途
SELECT c.cust_id, c.fed_id, c.cust_type_cd,
CASE
WHEN EXISTS (SELECT * FROM account a
WHERE a.cust_id = c.cust_id
AND a.product_cd = 'CHK') THEN 'Y'
ELSE 'N'
END has_checking
FROM customer c;
IFNULL(expr_1, expr_2) 函数用于判断 expr_1 是否为 NULL,如果为 NULL 则返回 expr_2 的值,如果不为 NULL 则返回 expr_1 的值. 如:
SELECT employee_id, IFNULL(commission_pct, 0) //表示若奖金率为NULL值,则返回0.
FROM employees;
注:上述特性引用自维基百科
MySQL在一个新会话下默认开启自动提交模式,使用set autocommit = 0
可以关闭自动提交,这是就可以用rollback
回滚了.
事务保存点:类似于断点的意思,操作者可回滚到指定事务保存点而不是事务启动位置.
SAVEPOINT sp_name;
//回滚时
ROLLBACK TO SAVEPOINT sp_name;
⚠️索引是在存储引擎层面实现的,不同的存储引擎支持不同的索引类型. MySQL一般默认索引类型为B树索引.
MySQL主要有以下三种索引类型.
//为某一列创建索引,可创建 单列索引,也可创建 多列索引.
ALTER TABLE table_name
ADD INDEX index_name(列名1,列名2,...,列名N);
e.g.
ALTER TABLE `department`
ADD INDEX dept_name_idx(name);
注:当表被创建的时候,MySQL会自动为主键列创建索引.
当某一列的值不允许出现重复值,但是该字段又不是主键时,我们可以为该列创建一个唯一索引.
ALTER TABLE table_name
ADD UNIQUE INDEX index_name(列名);
注:ERROR 1062 即此产生.
SHOW INDEX FROM table_name;
//删除某一索引
ALTER TABLE table_name
DROP INDEX index_name;
or
DROP INDEX index_name ON table_name;
⚠️(1)为被外键约束引用的列创建索引;(2)为那些被频繁检索的列创建索引.
约束一般有以下几种类型:
主键约束
CONSTRAINT [约束名] PRIMARY KEY (列名) //可多列
外键约束
CONSTRAINT [约束名] FOREIGN KEY (列名) REFERENCES refer_table_name(列名) [ON UPDATE/DELETE CASCADE] //可多列
注:在没有选级联更新选项的时候,外键约束不允许参照这个字段的表插入的记录中所参照的那一列有它没有的值;若有级联更新,则可行,且所产生的变化会传播相关联的表. 级联删除同.
唯一性约束
CONSTRAINT [约束名] UNIQUE (列名) //可多列
检查约束
CONSTRAINT [约束名] CHECK (condition)
空值约束
列名 NOT NULL
方式一:在创建表的时候就用上面语句添加约束
方式二:若表已经创建完,之后想添加约束在,则如下语句
ALTER TABLE table_name
ADD CONSTRAINT ...; //同上面的语句
ALTER TABLE table_name
DROP CONSTRAINT 约束名;
//删除主键约束时直接
ALTER TABLE table_name
DROP PRIMARY KEY;
视图不涉及数据存储,为虚拟表.
CREATE OR REPLACE VIEW 视图名 AS (
SELECT ...
FROM ...
WHERE ...);
向视图中插入/删除数据,结果会体现到(base table)基表上.
⚠️以下几种情况下视图不可更新:
另外,注意当多表连接生成的视图时,你插入数据一次只能更新其中一个基表中的列,不能多表插入!!!
DROP VIEW 视图名;
即数据的数据,是数据的抽象描述. 类似于模式是对关系表的抽象描述.
在MySQL中用information_schema
数据库来提供元数据,可用以下命令来查看该数据库中的各种视图的结构,从中知道里面的每张视图存了什么.
use information_schema;
show tables;
desc table_name;
较为常用的有有以下这几个表.
Schema -----数据库信息
Tables -----表和视图的信息
Columns -----表和视图的列信息
Statistics -----索引信息
Schema/Table/Column_Privileges -----数据库/表/列 权限分配
Views -----视图信息
Triggers -----触发器信息
Engines -----可用存储引擎信息