MySQL入门

作者: C就要毕业了 | 来源:发表于2017-03-28 00:41 被阅读55次

作为一个数据库小白,在面试过程中无数次被问到有没有数据库经验,十分尴尬。于是准备从MySQL开始入门一下,只求学会基本操作。学习的是慕课网的《与MySQL的零距离接触》,个人觉得足够日常使用了。

1. 初涉MySQL

安装MySQL

mac下使用homebrew

brew install mysql

不用配置什么文件,使用下面的命令就可以使用root身份进入mysql服务器

mysql.server start
mysql -u root -p
回车(因为没有密码)

数据库基本操作

查看现有数据库

SHOW DATABASES;

创建一个数据库

CREATE DATABASE d1;

打开一个数据库

USE d1;

修改数据库编码方式

ALTER DATABASE d1 CHARACTER SET = utf8;

删除数据库

DROP DATABASE d1;

2. 数据类型和操作数据表

数据类型

  • 整形有5种:INT,SMALLINT等等
  • 浮点型2种:FLOAT[(M,D)],DOUBLE[(M,D)],M是总位数,D是小数点后位数
  • 日期时间型:YEAR,TIME,DATE,DATETIME,TIMESTAMP
  • 字符型:CHAR(M),VARCHAR(M), TEXT等,ENUM('value1', 'value2',...),SET('value1', 'value2'...)

数据表操作

创建数据表

mysql> CREATE TABLE tb1(
    -> username VARCHAR(20),
    -> age TINYINT UNSIGNED,
    -> salary FLOAT(8,2) UNSIGNED);

查看创建数据表详细

SHOW CREATE TABLE tb1;

查看数据表

SHOW TABLES [FROM db_name];

查看当前数据库

SELECT DATABASE();

查看数据表结构

SHOW COLUMNS FROM tb1;

插入数据

INSERT tb1 VALUES('Tom',25,7863.25);
INSERT tb1(username, salary) VALUES('John', 1700.25);

查找数据

SELECT * FROM tb1;

空值与非空,即某个字段不能为空

mysql> CREATE TABLE tb2(
    -> username VARCHAR(20) NOT NULL,
    -> age TINYINT UNSIGNED NULL);

自动编号与主键

  • 一个表只能有一个主键
  • 主键必定是NOT NULL,而且不允许重复值出现
  • 主键不一定要AUTO_INCREMENT,反之不对
mysql> CREATE TABLE tb3(
    -> id SMALLINT UNSIGNED AUTO_INCREMENT KEY,
    -> username VARCHAR(30) NOT NULL);
mysql> INSERT tb3(username) VALUES('Tom');

Unique Key, 保证唯一性,NULL也只能有一个

username VARCHAR(20) NOT NULL UNIQUE KEY,

Default

sex ENUM('1','2','3') DEFAULT '3'

3. 约束以及修改数据表

约束

  • NOT NULL 非空约束
  • PRIMARY KEY 主键约束
  • UNIQUE KEY 唯一约束
  • DEFAULT 默认约束
  • FOREIGN KEY 外键约束

DEFAULT和NOT NULL必是列级约束,其他不一定

外键

  • 数据库引擎必须为InnoDB
  • 被参照的叫父表,参照的叫子表,上父下子

定义外键方法

mysql> CREATE TABLE provinces(
    -> id TINYINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    -> pname VARCHAR(20) NOT NULL);
mysql> CREATE TABLE users(
    -> id SMALLINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    -> username VARCHAR(10) NOT NULL,
    -> pid TINYINT UNSIGNED,  %这里必须要和上面相同
    -> FOREIGN KEY(pid) REFERENCES provinces (id));

外键约束的参照操作

FOREIGN KEY(pid) REFERENCES provinces (id) ON DELETE CASCADE

将会导致父表中某条记录删除时,子表中相应记录也删除,此外还有 SET NULL,RESTRICT

修改数据表

添加列

ALTER TABLE user ADD age TINYINT UNSIGNED DEFAULT 10;

删除列

ALTER TABLE user DROP age;

添加约束

ALTER TABLE users2 ADD CONSTRAINT PRIMARY KEY(id);
ALTER TABLE users2 ADD CONSTRAINT UNIQUE KEY(username);
ALTER TABLE users2 ADD CONSTRAINT FOREIGN KEY (pid) REFERENCES province(id);
ALTER TABLE users2 ALTER age SET DEFAULT 15;

删除约束

ALTER TABLE users2 DROP PRIMARY KEY;
% 删除唯一约束前先要查看key name
SHOW INDEXES FROM users2;
ALTER TABLE users2 DROP KEY username;
% 删除外键约束前要先查看constriant的名字
SHOW CREATE TABLE users2;
ALTER TABLE users2 DROP FOREIGN KEY users2_ibfk_1;
% 外键虽然删除,但是key还在,需要进一步删除key,方法同删除唯一约束
% 删除默认约束
ALTER TABLE users2 ALTER age DROP DEFAULT;

修改列的定义

% AFTER column name意思是放在某个列后面,FIRST意思是放在第一个
ALTER TABLE users2 MODIFY id TINYINT AFTER username;
% 使用CHANGE可以改列名字以及定义
ALTER TABLE users2 CHANGE pid new_pid TINYINT UNSIGNED;

修改数据表的名字

ALTER TABLE users2 RENAME users3;

4. 操作数据表中的记录

插入记录

创建数据表

mysql> CREATE TABLE users(
    -> id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    -> username VARCHAR(20) NOT NULL,
    -> password VARCHAR(32) NOT NULL,
    -> age TINYINT UNSIGNED NOT NULL DEFAULT 10,
    -> sex BOOLEAN);

插入记录的第一种方法

% 不指定对哪些COLUMN赋值的话,AUTO_INCREMENT的可以用NULL或者DEFAULT来代替
INSERT users VALUES(NULL,'Tom','123',24,1);
% 赋值可以使用表达式
INSERT users VALUES(DEFAULT,'John','123',3*7-1,1);
% 赋值还可以是函数,如md5
INSERT users VALUES(DEFAULT,'Phil',md5('123'),DEFAULT,0);
% 插入多条记录用逗号隔开即可

使用SET做插入可以使用子查询

INSERT users SET username='Bob',password='1223';

第三种是INSERT ... SELECT

更改记录

% 这样会更新所有记录
UPDATE users SET age = age + 2, sex = 0;
% 增加一些条件
UPDATE users SET age = age + 10 WHERE id % 2 = 0;

删除记录

DELETE [users] FROM users WHERE id = 3;
% 注意这个时候再插入一条记录id号会变成原有的最大的+1

查找记录

% 查找某些函数,表达式
SELECT NOW();
SELECT 3 + 5;
% 查询某几列,可以自定义顺序
SELECT username, id FROM users;
% 字段可以更改别名
SELECT id AS userID, username AS uname FROM users;
% 使用WHERE来指定条件
SELECT * FROM users WHERE id = 2;
% 使用GROUP BY进行结果分组,这里不太懂
SELECT sex FROM users GROUP BY sex;
% HAVING语句设置分组条件,这里也会报错,不懂
SELECT sex,age FROM users GROUP BY sex HAVING age > 10;
% ORDER BY对查询结果进行排序
SELECT * FROM users ORDER BY id DESC;
SELECT * FROM users ORDER BY password,username;
% LIMIT限制查询返回结果的数量,例子中返回第4,5两个结果
SELECT * FROM users LIMIT 3,2;

插入查询的结果

mysql> CREATE TABLE test(
    -> id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    -> username VARCHAR(20) NOT NULL);
mysql> INSERT test(username) SELECT username FROM users WHERE age > 20;

5. 子查询与连接

子查询

子查询指嵌套在查询内部,且必须出现在圆括号内

创建数据库,这是一个包含了一些淘宝商品信息的TABLE: tdb_goods

  CREATE TABLE IF NOT EXISTS tdb_goods(
    goods_id    SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    goods_name  VARCHAR(150) NOT NULL,
    goods_cate  VARCHAR(40)  NOT NULL,
    brand_name  VARCHAR(40)  NOT NULL,
    goods_price DECIMAL(15,3) UNSIGNED NOT NULL DEFAULT 0,
    is_show     BOOLEAN NOT NULL DEFAULT 1,
    is_saleoff  BOOLEAN NOT NULL DEFAULT 0
  );

使用比较运算符的子查询

查询大于平均价格的商品
SELECT * FROM tdb_goods WHERE goods_price > (SELECT ROUND(AVG(goods_price),2) FROM tdb_goods);

用ANY, SOME, ALL修饰比较运算符(ANY = SOME)

... WHERE goods_price > ANY  (SELECT .....);

使用INSERT...SELECT插入记录

创建一个tdb_goods_cates新表,用来记录tdb_goods中的所有商品种类

INSERT tdb_goods_cates (cate_name) (SELECT goods_cate FROM tdb_goods GROUP BY goods_cate);

使用INNER JOIN进行多表更新

更新tdb_goods表使得goods_cate中存的是tab_goods_cates表中种类的id

UPDATE tdb_goods INNER JOIN tdb_goods_cates 
-> ON goods_cate = cate_name SET goods_cate = cate_id;

把创建和INSERT合成一步

这里要做的是品牌的连接

mysql> CREATE TABLE tdb_goods_brands(
    -> brand_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    -> brand_name VARCHAR(40) NOT NULL)
    -> SELECT brand_name FROM tdb_goods GROUP BY brand_name;

多表更新的时候如果两张表有同名COLUMN则最好使用别名

mysql> UPDATE tdb_goods AS g INNER JOIN tdb_goods_brands AS b ON
    -> g.brand_name = b.brand_name SET g.brand_name = b.brand_id;

最后把brand和category的定义给改成INT实现数据表减肥

mysql> ALTER TABLE tdb_goods
    -> CHANGE goods_cate cate_id SMALL_INT UNSIGNED NOT NULL,
    -> CHANGE brand_name brand_id SMALL_INT UNSIGNED NOT NULL;

那我们要不要使用外键?
不一定要使用物理外键,这样子的三张表实际上有外键的关系。

连接

  • 内连接,左外连接,右外连接
  • 使用ON关键字来设定连接条件,使用WHERE也可以

举个例子,列出所有的货物以及它的名字和种类(注意种类名字是在tdb_goods_cates表中的,tdb_goods里只有种类id)

SELECT goods_id, goods_name, cate_name FROM tdb_goods 
INNER JOIN tdb_goods_cates ON tdb_goods.cate_id = tdb_goods_cates.cate_id;

左外连接就是显示左表中的全部和右表中符合条件的 LEFT JOIN,对于左表中出现但是不符合右表条件的,会在相应字段显示NULL

SELECT goods_id, goods_name, cate_name FROM tdb_goods 
LEFT JOIN tdb_goods_cates ON tdb_goods.cate_id = tdb_goods_cates.cate_id;
% 会查询出某一条记录,这条记录在的cate_name找不到
24 |  LaserJet Pro P1606dn 黑白激光打印机 | NULL 

多表连接

其实就是多个INNER JOIN,返回了最初减肥前的结果

SELECT goods_id, goods_name, cate_name, brand_name, goods_price FROM tdb_goods AS g 
INNER JOIN tdb_goods_cates AS c ON g.cate_id = c.cate_id 
INNER JOIN tdb_goods_brands AS b ON g.brand_id = b.brand_id;

无限级分类表设计

比如分类有服装,服装底下又有男装女装,男装下面又有鞋子之类的。

用到一张表模拟多表连接

+---------+-----------------+-----------+
| type_id | type_name       | parent_id |
+---------+-----------------+-----------+
|       1 | 家用电器        |         0 |
|       2 | 电脑、办公      |         0 |
|       3 | 大家电          |         1 |
|       4 | 生活电器        |         1 |
|       5 | 平板电视        |         3 |
...
+---------+-----------------+-----------+

列出所有类的父类(暂时无法递归查询)

SELECT s.type_id, s.type_name, p.type_name FROM tdb_goods_types AS p
INNER JOIN tdb_goods_types AS s ON s.parent_id = p.type_id;

列出所有类的子类数目

SELECT p.type_id,p.type_name,count(s.type_name) AS children_count 
FROM tdb_goods_types AS p LEFT JOIN tdb_goods_types AS s 
ON s.parent_id = p.type_id GROUP BY p.type_id ORDER BY p.type_id;

+---------+-----------------+----------------+
| type_id | type_name       | children_count |
+---------+-----------------+----------------+
|       1 | 家用电器        |              2 |
|       2 | 电脑、办公      |              2 |
|       3 | 大家电          |              2 |
...

多表删除

首先找出出现了多次的商品,之前碰到的GROUP BY的问题了解了,MySQL高版本中要保证使用GROUP BY之后不能取出多个记录,有多个的话一定要用聚类函数类似MAX,COUNT这种

SELECT COUNT(goods_id), goods_name AS num 
FROM tdb_goods GROUP BY goods_name HAVING COUNT(goods_id) > 1;

删除重复商品中编号大的那个,由于GROUP BY的问题,这个会报错

DELETE t1 FROM tdb_goods AS t1 
LEFT JOIN (SELECT goods_id,goods_name FROM tdb_goods GROUP BY goods_name HAVING count(goods_name) >= 2 ) 
AS t2  ON t1.goods_name = t2.goods_name  WHERE t1.goods_id > t2.goods_id;

6. 运算符和函数

字符函数

% 合并两个数据
CONCAT('imooc', 'MySQL');
% 合并两个字段
SELECT CONCAT(first_name, last_name) AS fullname FROM name;
% 带分隔符连接,imooc-MySQL
SELECT CONCAT_WS('-', 'imooc', 'MySQL');
% 得到12,560.8
SELECT FORMAT(12560.75, 1)
% 大小写转换
SELECT LOWER('mysql');
% 取得左侧或右侧几个字符,得到My
SELECT LEFT('MySQL', 2);
% LENGTH取得字符串长度
% LTRIM 删除前导空格,RTRIM删除后导空格,TRIM删除前后空格
SELECT TRIM('  MySQL  ');
% 删除前导后导的问号,LEADING,TRAILING
SELECT TRIM(LEADING '?' FROM '??MySQL');
% 字符串替换
SELECT REPLACE('??My??SQL??', '?', '');
% 取子串,得到ySQ,起始位置,长度
SELECT SUBSTRING('MySQL', 2, 3);
% 模式匹配,%任意个任意字符,_任意一个字符,返回1或者0
SELECT 'MySQL' LIKE '%S%';

数值运算符及函数

SELECT CEIL(3.01); % 4
SELECT FLOOR(3.99); % 3
SELECT 3 DIV 4; % 0
SELECT 3 / 4; % 0.75
SELECT POWER(3, 2); % 9
SELECT ROUND(3.652, 2); % 3.65
SELECT TRUNCATE(125.89, 1); % 125.8
SELECT 1 IS NULL;

日期时间函数

NOW()等等,还可以实现日期时间的加减等等

SELECT DATE_FORMAT(NOW(), '%Y年%m月%d日%h时');

信息函数

DATABASE(); % 当前数据库
USER(); % 当前用户
ROW_COUNT(); % 上一条操作影响的记录数
等等

聚合函数

AVG(), COUNT(), MAX(), MIN(), SUM()

加密函数

MD5(); % 尽量使用MD5();
PASSWORD();

7. 自定义函数

mysql> CREATE FUNCTION f(num1 SMALLINT, num2 SMALLINT)
    -> RETURNS FLOAT(10,2) 
    -> RETURN (num1 + num2) / 2;
% 如果函数有多句一定要用BEGIN AND,同时要暂时修改结束符
DELIMITER //
函数定义...
DELIMITER ;

8. MySQL存储过程

  • 存储过程就是预先编译的SQL语句,可以使得在使用的时候大大加快速度。因为平时每句都是做语法分析,编译执行。
  • IN代表输入,OUT代表输出,INOUT代表输入再输出
  • INTO是存入某个变量
  • @代表用户变量,可以用SET @a = 3来设置
  • 可以返回多个值,函数只能返回一个值
DELIMITER //
CREATE PROCEDURE removeUserByID(IN del_id INT UNSIGNED, OUT userNums INT UNSIGNED)
BEGIN
DELETE FROM users WHERE id = del_id;
SELECT count(id) FROM users INTO userNums;
END//

DELIMITER ;
CALL removeUserByID(3, @nums);
SELECT @nums;

9. MySQL存储引擎

简介

  • 每一种存储引擎使用不同的存储机制,索引技巧,锁定水平,最终提供广泛而且不同的功能。
  • MySQL支持:MyISAM, InnoDB, Memory, CSV

并发控制

  • 当多个用户操作同一个记录时,使用锁技术
  • 共享锁(读锁):多个用户可以同时读取,读取过程中数据不变
  • 排他锁(写锁): 只有一个用户可以写入,同时阻塞其他读写锁
  • 锁颗粒
    表锁,开销小;
    行锁,开销大,并发度高

事务处理

  • 事务用于保证数据库完整性
  • 比如转账(A减少钱,B增加钱)
  • 原子性,一致性,隔离型,持久性。简称ACID

索引

  • 是对数据表中的一列或者多列的值进行排序的一种结构

各种存储引擎特点

设置存储引擎

  • 改配置文件

  • 创建表的时候制定
    ENGINE = MyISAM;

10. 管理工具

  • 可以实现备份等等操作
  • PHPMyAdmin:需要PHP支持
  • Navicat
  • MySQL Workbench

相关文章

  • MySQL教程

    MySQL 入门教程 MySQL 安装 MySQL 管理 MySQL PHP 语法 MySQL 连接 MySQL ...

  • MySQL,从入门到熟练

    MySql入门

  • MySQL入门教程 - 收藏集 - 掘金

    MySQL入门教程系列-1.5 如何学习MySQL - 掘金 在这里持续更新 MySQL入门教程系列-1.5 如何...

  • 如何入门 MySQL

    如何入门MySQL 前言: 关于如何入门MySQL,后台有好多同学咨询我,可能部分读者刚开始学习MySQL,我前面...

  • MySQL教程

    MySQL 入门教程MySQL 安装MySQL 管理MySQL PHP 语法MySQL 连接MySQL 创建数据库...

  • MySQL入门教程系列-1.5 如何学习MySQL

    MySQL入门教程系列-1.5 如何学习MySQL 在这里持续更新MySQL入门教程系列-1.5 如何学习MySQ...

  • 01 MySQL学习

    参考书籍:MySQL8入门到精通参考网络课程:mysql入门_尚硅谷(https://www.bilibili.c...

  • MySQL入门教程

    MySQL 入门教程[http://www.codingdict.com/article/7038] MySQL ...

  • MySQL之SQL语句

    引用 MySQL教程:MySQL数据库学习宝典(从入门到精通) MySQL 8.0 Reference Manua...

  • MySQL资源大合集

    与MySQL的零距离接触Python 操作数据库—— MySQL 篇MySQL入门MySQL进阶SQL for D...

网友评论

    本文标题:MySQL入门

    本文链接:https://www.haomeiwen.com/subject/qxjdottx.html