数据库

MySQL入门

2017-03-28  本文已影响55人  C就要毕业了

作为一个数据库小白,在面试过程中无数次被问到有没有数据库经验,十分尴尬。于是准备从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. 数据类型和操作数据表

数据类型

数据表操作

创建数据表

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);

自动编号与主键

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. 约束以及修改数据表

约束

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

外键

定义外键方法

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;

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

连接

举个例子,列出所有的货物以及它的名字和种类(注意种类名字是在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存储过程

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存储引擎

简介

并发控制

事务处理

索引

各种存储引擎特点

设置存储引擎

10. 管理工具

上一篇下一篇

猜你喜欢

热点阅读