参考教程
以下操作以 Aliyun Linux 2 操作系统为例进行演示。
MariaDB 数据库管理系统是 MySQL 的一个分支,主要由开源社区在维护,采用 GPL 授权许可。开发这个分支的原因之一是:甲骨文公司收购了 MySQL 后,有将 MySQL 闭源的潜在风险,因此社区采用分支的方式来避开这个风险。
MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。
安装的命令:
yum install mariadb-server mariadb
查看版本信息的命令:
mysqladmin --version
启动服务的命令:
systemctl start mariadb
其他命令:
systemctl start mariadb #启动MariaDB
systemctl stop mariadb #停止MariaDB
systemctl restart mariadb #重启MariaDB
systemctl enable mariadb #设置开机启动
初始 root 密码为空,可以通过以下命令设置:
mysqladmin -u root password "new_password"
设置密码以后,使用如下命令连接 MySQL 服务器:
mysql -u root -p
输入密码即可。
执行以下命令:
mysqladmin -u root -p原密码 password "新密码"
注意,-p 和原密码之间不要有空格。
show databases;
use 数据库名;
show tables;
show tables from 数据库名;
select database();
desc 表名;
select version();
# 注释文字
-- 注释文字
/* 多行注释 */
这样,通过 SSH 的方式就可以连接到远程 MySQL 服务器了。
先执行网上下的sql文件:myemployees.sql,便生成了数据库myemployees。
链接:https://pan.baidu.com/s/1skbVEuiFYQRPS5IIG3yACw
提取码:j6je
SELECT last_name, email
FROM employees;
SELECT *
FROM employees;
用在SQL查询语句之前。
USE myemployees;
SELECT 100;
SELECT 'yaya';
作用:1. 便于理解;2. 如果要查询的字段有重名,使用别名可以区别开。
SELECT last_name AS 姓 -- AS可以省略
FROM employees;
如果别名含有空格:
SELECT last_name AS "last name"
FROM employees;
SELECT DISTINCT department_id
FROM employees;
-- 两个操作数均为数值型,做加法运算
SELECT 100 + 90; -- 190
-- 若操作数为字符型,尝试将字符型转为数值型,继续加法运算
SELECT '100' + 90; -- 190
-- 如果转换失败,则将字符型视为0
SELECT 'yaya' + 90; -- 90
SELECT 'yaya' * 90; -- 0
-- 只要操作数有null,则结果为null
SELECT NULL + 10; --
SELECT NULL * 10; --
SELECT NULL - NULL; --
SELECT CONCAT(last_name, ' ', first_name) AS 姓名
FROM employees;
如果参数一值为NULL,则返回参数二;否则返回参数一。
SELECT IFNULL(commission_pct, 999)
FROM employees;
SELECT 查询列表 FROM 表名 WHERE 筛选条件;
SELECT *
FROM employees
WHERE salary > 12000;
SELECT *
FROM employees
WHERE salary >= 10000 AND salary <= 20000;
效果同上。(闭区间)
SELECT *
FROM employees
WHERE salary BETWEEN 10000 AND 20000;
默认不区分大小写
通配符:
百分号——替代0个或多个字符
下划线——替代一个字符
SELECT *
FROM employees
WHERE last_name LIKE '%a%';
SELECT *
FROM employees
WHERE last_name LIKE '__n_l%';
SELECT *
FROM employees
WHERE last_name LIKE '_\_%';
使用任何字符当转义符。
SELECT *
FROM employees
WHERE last_name LIKE '_$_%' ESCAPE '$';
SELECT *
FROM employees
WHERE job_id IN ('IT_PROG', 'AD_VP');
SELECT *
FROM employees
WHERE commission_pct IS NULL; -- 这里不能用=比较
SELECT *
FROM employees
WHERE commission_pct IS NOT NULL;
既可以判断普通的值,也可以判断NULL值。
SELECT *
FROM employees
WHERE commission_pct <=> NULL OR commission_pct <=> 0.2;
升序排序,则不写DESC。
SELECT *
FROM employees
ORDER BY salary DESC;
-- 写法一
SELECT *, salary * 12 * (1 + IFNULL(commission_pct, 0)) AS 年薪
FROM employees
ORDER BY salary * 12 * (1 + IFNULL(commission_pct, 0)) DESC;
-- 写法二
SELECT *, salary * 12 * (1 + IFNULL(commission_pct, 0)) AS 年薪
FROM employees
ORDER BY 年薪 DESC;
SELECT *
FROM employees
ORDER BY salary DESC, employee_id ASC;
SELECT *, LENGTH(last_name)
FROM employees
ORDER BY LENGTH(last_name);
略。
支持中文、索引从1开始。
SELECT SUBSTR('abcdefg', 2); -- bcdefg
SELECT SUBSTR('我是耿耿欧耶', 2); -- 是耿耿欧耶
SELECT SUBSTR('我是耿耿欧耶', 2, 3); -- 是耿耿
SELECT INSTR('尔等看好了!', '看好'); -- 3
SELECT INSTR('尔等看好了!', '看好啦'); -- 0
SELECT INSTR('你猜猜看', '猜'); -- 2
略。
SELECT LPAD('耿鸭', 10, '*'); -- ********耿鸭
SELECT LPAD('耿鸭', 10, '*+-'); -- *+-*+-*+耿鸭
SELECT LPAD('我是很长的字符串', 3, '*+-'); -- 我是很
略。
SELECT TRUNCATE(3.1999, 0); -- 3
SELECT TRUNCATE(3.1999, 1); -- 3.1
SELECT TRUNCATE(3.1999, 2); -- 3.19
SELECT TRUNCATE(-3.1999, 0); -- -3
SELECT TRUNCATE(-3.1999, 1); -- -3.1
SELECT TRUNCATE(-3.1999, 2); -- -3.19
与%一样。
SELECT NOW(); -- 2020-03-27 09:49:21
SELECT CURDATE(); -- 2020-03-27
SELECT CURTIME(); -- 09:50:38
SELECT YEAR(NOW()); -- 2020
SELECT YEAR('1998-1-1'); -- 1998
SELECT MONTH(NOW()); -- 3
SELECT MONTHNAME(NOW()); -- March
SELECT DAY(NOW()); -- 27
SELECT HOUR(NOW());
SELECT MINUTE(NOW());
SELECT SECOND(NOW());
SELECT STR_TO_DATE('09-13-2019', '%m-%d-%Y'); -- 2019-09-13
SELECT STR_TO_DATE('59:07:40', '%i:%H:%s'); -- 07:59:40
SELECT DATE_FORMAT(NOW(), '%Y年%m月%d日 %H时%i分%s秒'); -- 2020年03月29日 07时36分31秒
-- 查看版本号
SELECT VERSION(); -- 8.0.19
-- 查看当前数据库
SELECT DATABASE(); -- myemployees
-- 查看当前用户
SELECT USER(); -- root@localhost
SELECT IF(10 > 5, '大', '小'); -- 大
SELECT IF(10 > 15, '大', '小'); -- 小
-- 查询每个员工是否有奖金
SELECT last_name, commission_pct, IF(commission_pct IS NULL, '无奖金', '有奖金')
FROM employees;
SELECT last_name,
salary AS 原始工资,
department_id,
CASE department_id
WHEN 30 THEN salary + 100
WHEN 40 THEN salary + 200
WHEN 50 THEN salary + 300
ELSE salary
END AS 新工资
FROM employees;
SELECT SUM(salary)
FROM employees;
COUNT统计的是非NULL的个数!
上面5个函数都忽略了NULL值!
SELECT SUM(salary), AVG(salary), MAX(salary), MIN(salary), COUNT(salary)
FROM employees;
-- 去重以后求和
SELECT SUM(DISTINCT salary), SUM(salary)
FROM employees;
-- 统计不相同的工资数目
SELECT COUNT(DISTINCT salary), COUNT(salary)
FROM employees;
-- 统计表中有多少行
SELECT COUNT(*)
FROM employees;
SELECT COUNT(1) -- 每一行增加一列,值为1,统计1的数量,就相当于统计行数
FROM employees;
WHERE一定放在FROM后面,GROUP BY放在WHERE后面,ORDER BY放最后。
SELECT job_id, MAX(salary)
FROM employees
GROUP BY job_id;
SELECT location_id, COUNT(*)
FROM departments
GROUP BY location_id;
SELECT department_id, AVG(salary)
FROM employees
WHERE email LIKE '%a%'
GROUP BY department_id;
-- 写法一
SELECT department_id, COUNT(*)
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 2;
-- 写法二
SELECT department_id, COUNT(*) cnt
FROM employees
GROUP BY department_id
HAVING cnt > 2;
SELECT job_id, MAX(salary)
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING MAX(salary) > 12000;
SELECT manager_id, MIN(salary)
FROM employees
WHERE manager_id > 102
GROUP BY manager_id
HAVING MIN(salary) > 5000;
查询每个部门每个工种的员工平均工资
SELECT department_id, job_id, AVG(salary)
FROM employees
GROUP BY department_id, job_id;
查询每个部门每个工种的员工平均工资(按平均工资排序)
SELECT department_id, job_id, AVG(salary)
FROM employees
GROUP BY department_id, job_id
ORDER BY AVG(salary) DESC;
连接查询又称为“多表查询”。
SELECT COUNT(*) FROM a;
假设输出12行。
SELECT COUNT(*) FROM b;
假设输出4行。
SELECT COUNT(*) FROM a, b;
输出 12 × 4 = 48 12\times4=48 12×4=48 行。
特点:
案例1:查询员工名和对应的部门名。
SELECT last_name, department_name
FROM employees, departments
WHERE employees.department_id = departments.department_id;
案例2(分组查询):查询每个城市的部门个数。
SELECT city, COUNT(*)
FROM departments d, locations l
WHERE d.location_id = l.location_id
GROUP BY city;
案例3:查询 有奖金 的 每个部门 的 部门名 和 部门的领导编号 和 该部门的最低工资。
SELECT department_name, d.manager_id, MIN(salary)
FROM departments d, employees e
WHERE d.department_id = e.department_id
AND commission_pct IS NOT NULL
GROUP BY department_name, manager_id;
案例:查询员工的工资和工资级别。
(先执行百度云共享中的job_grades.sql)
SELECT first_name, salary, grade_level
FROM employees e, job_grades j
WHERE e.salary BETWEEN j.lowest_sal AND j.highest_sal;
自己连接自己。
案例:查询 员工名 和 对应的领导名。
SELECT e.employee_id, e.last_name, m.employee_id, m.last_name
FROM employees e, employees m
WHERE e.manager_id = m.employee_id;
分为等值连接、非等值连接、自连接,和上面差不多,语法有一些区别。
案例1:查询 员工名 部门名。
SELECT last_name, department_name
FROM employees e
INNER JOIN departments d
ON e.department_id = d.department_id;
案例2:查询 姓名 中 包含 e 的 员工名 和 工种名。
SELECT last_name, job_title
FROM employees e
INNER JOIN jobs j
ON e.job_id = j.job_id
WHERE e.last_name LIKE '%e%';
语法:
INSERT INTO 表名(列名,...) VALUES (值1,...);
例如,在 beauty 表中插入一行记录。首先查看 beauty 有哪些字段:
然后使用 insert 语句插入:
INSERT INTO beauty(id, name, sex, borndate, phone, photo, boyfriend_id)
VALUES (99, '耿鸭', '男', '1999-9-9', '123456', NULL, 99);
也可以一次插入多行:
INSERT INTO beauty(id, name, phone)
VALUES (101, '甲', '110'),
(102, '乙', '119'),
(103, '丙', '120');
还可以使用子查询:
INSERT INTO beauty(id, name, phone)
SELECT 105, '猫猫', 'xxx';
相当于把 SELECT 的查询结果对应插入相应的列。
注:
语法:
INSERT INTO 表名 SET 列名=值,列名=值,...
为空的字段可以不写。
INSERT INTO beauty
SET id=100, name='萨斯给', phone='110';
显然方式一的功能比较多。
语法:
UPDATE 表名 SET 列 = 新值,列 = 新值,... WHERE 筛选条件;
注:
案例:
-- 案例1:修改beauty表中所有姓周的女神的电话
UPDATE beauty SET phone = '12306'
WHERE name LIKE '周%';
语法:
UPDATE 表1 别名,表2 别名 SET 列 = 值,... WHERE 连接条件 AND 筛选条件;
SQL99 语法:
UPDATE 表1 别名 INNER|LEFT|RIGHT JOIN 表2 别名 ON 连接条件 SET 列 = 值,... WHERE 筛选条件;
-- 案例1:修改张无忌的女朋友的手机号
UPDATE boys bo
INNER JOIN beauty b ON bo.id = b.boyfriend_id
SET b.phone = '114'
WHERE bo.boyName = '张无忌';
-- 案例2:修改没有男朋友的女神的男朋友编号都为2
UPDATE boys bo
RIGHT JOIN beauty b ON bo.id = b.boyfriend_id
SET b.boyfriend_id = 2
WHERE bo.id IS NULL;
语法:
DELETE FROM 表名 WHERE 筛选条件;
注:如果不加 WHERE 子句,则删除表中所有记录。
案例:
-- 案例1:删除手机号以9结尾的女神信息
DELETE FROM beauty
WHERE phone LIKE '%9';
语法:
DELETE 表1或表2的别名 FROM 表1 别名,表2 别名 WHERE 连接条件 AND 筛选条件;
SQL99 语法:
DELETE 表1或表2的别名 FROM 表1 别名 INNER|LEFT|RIGHT JOIN 表2 别名 ON 连接条件 WHERE 筛选条件;
注:DELETE 后面跟几个表的别名就删除几个表的记录。
语法:
TRUNCATE TABLE 表名;
删除表中所有记录。
删库跑路!
用于数据库和表的管理。
创建数据库,存在则报错:
CREATE DATABASE 库名;
创建数据库,无则创建,有则无事发生:
CREATE DATABASE IF NOT EXISTS 库名;
一般不修改数据库的名称,为了防止各种问题。
修改数据库的字符集:
ALTER DATABASE 库名 CHARACTER SET gbk;
删除数据库,不存在则报错:
DROP DATABASE 库名;
删除数据库,有则删除,无则无事发生:
DROP DATABASE IF EXISTS 库名;
语法:
CREATE TABLE (
列名 列的类型(长度) 约束,
列名 列的类型(长度) 约束,
......
);
案例:
CREATE TABLE book (
id INT, # 编号
name VARCHAR(20), # 书名
price DOUBLE, # 价格
author_id VARCHAR(20), # 作者编号
publish_date DATE # 出版日期
);
DESC book;
语法:
ALTER TABLE 表名 CHANGE COLUMN 字段名 新字段名 新类型;
语法:
ALTER TABLE 表名 MODIFY COLUMN 字段名 新类型;
语法:
ALTER TABLE 表名 ADD COLUMN 新字段名 类型;
语法:
ALTER TABLE 表名 DROP COLUMN 字段名;
语法:
ALTER TABLE 原表名 RENAME TO 新表名;
语法:
DROP TABLE 表名;
DROP DATABASE IF EXISTS 库名;
CREATE DATABASE 库名;
DROP TABLE IF EXISTS 表名;
CREATE TABLE 表名(...);
语法:
CREATE TABLE 新表名 LIKE 原表名;
语法:
CREATE TABLE 新表名 SELECT * FROM 原表名;
很巧妙的方法:
CREATE TABLE 新表名
SELECT 字段名1,字段名2
FROM 原表名
WHERE 1=2;
CREATE TABLE test_enum (
sex ENUM('男', '女')
);
INSERT INTO test_enum VALUE ('男');
INSERT INTO test_enum VALUE ('女');
INSERT INTO test_enum VALUE ('妖'); -- 异常
CREATE TABLE test_date (
t0 DATE,
t1 DATETIME,
t2 TIMESTAMP
);
INSERT INTO test_date VALUES (NOW(), NOW(), NOW());
SELECT * FROM test_date;
用于保证该字段的值不为 NULL。
示例:
CREATE TABLE student (
id INT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
sex ENUM('男', '女'),
seat INT UNIQUE,
age INT DEFAULT 18
);
可将多个字段组合成一个主键,唯一键同理:
CREATE TABLE major (
id INT,
major_name VARCHAR(20),
PRIMARY KEY (id, major_name)
);
用于保证该字段有默认值。
示例:见 4.4.1 节。
用于保证该字段的值具有唯一性,并且非空。
示例:见 4.4.1 节。
用于保证该字段的值具有唯一性,可以为空,但是只能有一个 NULL 值的记录。
示例:见 4.4.1 节。
MySQL中不支持。
用于限制两个表的关系,保证该字段的值来自另一个表关联列的值。
示例:
DROP TABLE IF EXISTS student;
DROP TABLE IF EXISTS major;
CREATE TABLE major (
id INT PRIMARY KEY,
major_name VARCHAR(20) NOT NULL
);
CREATE TABLE student (
id INT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
major_id INT,
FOREIGN KEY (major_id) REFERENCES major(id)
);
注:被参考的外键(如本例 major 表的 id)一定要是键(主键、唯一键)。
方式一:直接重新定义某个字段(列级约束)
ALTER TABLE 表名 MODIFY COLUMN 字段名 类型 约束;
方式二:给某个字段添加约束(表级约束)
ALTER TABLE 表名 ADD 约束 (字段名);
方式一:直接重新定义某个字段
同 4.4.8 节。
DROP TABLE IF EXISTS student;
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20)
);
-- 两种插入方法
INSERT INTO student (name) VALUES ('haha');
INSERT INTO student VALUES (NULL, 'xixi');