【Mac】PostgreSQL和MySQL(基础)
【公式】PostgreSQL
【公式】MySQL
【安装 -> 连接】
PostgreSQL => 数据库系统PostgreSQL
如果没有指定任何版本,默认安装最新版本:
“`
$ brew install postgresql
“`
如果在执行时出现以下错误:
“`
psql -l: error: could not connect to server: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket “/tmp/.s.PGSQL.5432”?
“`
可以通过升级postgreSQL来解决:
“`
brew postgresql-upgrade-database
“`
连接
# 确认版本
“`
$ psql -V
“`
# 查看数据库列表
“`
$ psql -l
“`
# 连接数据库
“`
$ psql 数据库名
“`
MySQL –> MySQL是一种开源关系型数据库管理系统。
如果没有指定版本,默认为最新版本
brew install mysql
指定版本
$ brew search mysql # 使用brew search确认可安装的版本
==> Formulae
automysqlbackup mysql-client@5.7 mysql-search-replace
mysql ✔ mysql-connector-c++ mysql@5.6
mysql++ mysql-connector-c++@1.1 mysql@5.7
mysql-client mysql-sandbox mysqltuner
==> Casks
mysql-connector-python mysql-utilities navicat-for-mysql
mysql-shell mysqlworkbench sqlpro-for-mysql
$ brew install mysql @5.6 # 指定安装5.6版本
确认版本
brew info mysql
如果在运行时遇到以下错误
$ mysql.server start
ERROR! The server quit without updating PID file (/usr/local/var/mysql/USER-no-MacBook-Air.local.pid).
删除/usr/local/var/mysql并重新安装即可解决
$ sudo rm -rf /usr/local/var/mysql
$ brew uninstall mysql
$ brew install mysql
$ mysql.server start
Starting MySQL
.. SUCCESS!
以root身份登录
$ mysql -u root
【指令/查询/评论】
「#」用于内部执行
操作
PostgreSQL
帮助
$ psql –help # \h # \?
版本确认
$ psql –version $ psql -V
数据库列表
$ psql –list $ psql -l # \l
删除数据库
$ drop 数据库名
数据库连接
$ psql 数据库名
选择数据库
# \c 数据库名
当前选择的数据库
# select current_database();
断开连接
# \q #quit;
表格列表
# \dt
表格详情
# \d 表格名
删除表格
# drop table 表格名 view中使用中无法删除
视图列表
# \dv
用户列表
# \du
显示登录用户
# select session_user; # select current_user;
执行外部文件
# \i 文件名
注释
— (行末) /* */ (多行)
扩展显示(以垂直方式显示)
# \x
**「>」在内部执行**
| 操作 | MySQL |
|—|—|—|
| 帮助 | $ mysql –help > h; |
| 版本确认 | $ mysql –version |
| 数据库列表 | > show databases; > show schemas > show databases like ‘搜索字符串’ |
| 创建数据库 | > create database 数据库名; |
| 删除数据库 | > drop database 数据库名; |
| 连接数据库 | > mysql -u 用户名 -p ※ 如果是root用户不需要-p |
| 选择数据库 | > use 数据库名 |
| 当前选择的数据库 | > select database(); |
| 断开连接 | > \q > quit; > exit |
| 表列表 | > show tables; > show tables like ‘搜索字符串’; |
| 表详细信息 | > desc 表名; |
| 删除表 | > drop table 表名; |
| 视图列表 | > show tables; |
| 删除视图 | > drop view名; |
| 显示CREATE VIEW语句 | > show create view view名; |
| 用户列表 | > select Host, User from mysql.user; |
| 显示登录用户 | > select user();|
| 外部文件执行 | $ mysql -u 用户名 < 文件名(路径) > source 文件名(路径) > \. 文件名(路径) |
| 注释 | #(到行末) — (到行末) /* */ (多行) |
| 扩展显示(以竖直形式输出) | > select * from 表名 \G; ※ 在查询末尾添加\G ※ 在连接mysql时使用-E选项 |
| 确认数据库存在 | > create database if not exists 数据库名; |
| 确认字符编码 | > show variables like ‘%char%’; |
| 确认警告信息 | > show warnings; |
| 运行中线程信息 | > show processlist; |
| 取消命令 | > \c |
| 创建用户 | > create user 用户名@连接来源 identified by ‘密码’; |
| 删除用户 | > drop user 用户名@连接来源; |
| 连接 | $ mysql -u 用户名 -p 数据库名; |
| 显示登录用户 | > select user(); |
| 授权 | > grant 权限类型 on 数据库名.目标的表 to 用户名@连接来源; |
**权限级别**
级别
描述
全局级别(G)
适用于所有数据库,存储在mysql.user表中
数据库级别(D)
适用于特定数据库中的所有对象,存储在mysql.db表中
表级别(T)
适用于特定表中的所有列,存储在mysql.tables_priv表中
列级别(C)
适用于特定表中的单个列,存储在mysql.columns_priv表中
例程级别(R)
CREATE ROUTINE、ALTER ROUTINE、EXECUTE、GRANT OPTION权限适用于存储过程,在全局和数据库级别授权,在CREATE ROUTINE之外可以在每个例程上应用,存储在mysql.procs_priv表中
代理用户权限(P)
一个用户可以成为另一个用户的代理,存储在mysql.proxies_priv表中
**权限列表**
权限
级别
含义
ALL [PRIVILEGES]
GDT
除了GRANT OPTION和PROXY之外的所有权限
ALTER
GDT
修改表
ALTER ROUTINE
GDR
修改和删除存储过程
CREATE
GDT
创建数据库和表
CREATE ROLE
G
创建角色
CREATE ROUTINE GD
创建存储过程
CREATE TABLESPACE
G
创建、修改和删除表空间和日志组
CREATE TEMPORARY TABLES
GD
使用CREATE TEMPORARY TABLE
CREATE USER
G
使用CREATE USER、DROP USER、RENAME USER、REVOKE ALL PRIVILEGES
CREATE VIEW
GDT
创建和修改视图
DELETE
GDT
删除数据库、表和视图
DROP
GDT
删除表
DROP ROLE
G
删除角色
EVENT
GD
启用事件调度程序
EXECUTE
GDR
运行存储过程
FILE
G
使用SELECT … INTO OUTFILE和LOAD DATA INFILE
GRANT OPTION
GDTRP
授予和撤销其他账户的权限
INDEX
GDT
创建和删除索引
INSERT
GDTC
使用INSERT
LOCK TABLES
GD
使用LOCK TABLES在具有SELECT权限的表上锁定
PROCESS
G
使用SHOW FULL PROCESSLIST
PROXY
—
使用代理
REFERENCES
GDTC
创建外键
RELOAD
G
使用FLUSH
REPLICATION CLIENT
G
询问从库和主库的位置信息
REPLICATION SLAVE
G
使用复制从库(读取主库的二进制日志事件)
SELECT
GDTC
使用SELECT
SHOW DATABASES
G
使用SHOW DATABASES
SHOW VIEW
GDT
使用SHOW CREATE VIEW
SHUTDOWN
G
使用mysqladmin shutdown
SUPER
G
使用CHANGE MASTER TO、KILL、PURGE BINARY LOGS、SET GLOBAL、mysqladmin debug命令
TRIGGER
GDT
创建和删除触发器
UPDATE
GDTC
使用UPDATE
USAGE
G
“无权限”
SELECT权限可以在全局级别和列级别之间任意级别设置,可以设置具有权限获取所有数据库中的数据的权限,也可以设置仅允许获取特定列数据的权限。
服务器和客户端的字符编码
项目名
适用对象(客户端/服务器)
描述
character_set_client
客户端
在客户端向服务器发送查询时使用的字符集
character_set_results
服务器
在服务器向客户端发送查询结果时使用的字符集
character_set_connection
客户端
服务器解析客户端发送的查询时使用的字符集
character_set_database
服务器
服务器的默认字符集。LOAD DATA INFILE语句将使用此指定。在启动MySQL时,character_set_server的值将应用。
character_set_server
服务器
服务启动时的默认字符集
character_set_system
–
使用此字符集处理文件名
character_sets_dir
–
用于处理字符集所需文件的目录
关于扩展表达的内容
-
- 列が多く横長だと見にくい場合に便利
- 横か縦かの違い
=# 从用户选择*/* 提取结果 */
id | 姓名 | 分数 | 团队
—-+————+——-+——-
1 | taguchi | 5.5 | 红色
2 | fkoji | 8.3 | 蓝色
3 | dotinstall | 2.2 | 红色
4 | sasaki | 5 | 绿色
5 | sasaki | 4.6 | 红色
6 | kimura | 4.7 | 绿色
(6 行)
=# select * from users;-[ RECORD 1 ]—–
id | 1
name | taguchi
score | 5.5
team | red
-[ RECORD 2 ]—–
id | 2
name | fkoji
score | 8.3
team | blue
-[ RECORD 3 ]—–
id | 3
name | dotinstall
score | 2.2
team | red
.
.
.
=# \x
拓展显示已关闭。
【SQL评估顺序】
|顺序| 语句 | 动作 |
|:—:|—|—|
|先| FROM | 指定目标表格 |
|↓|ON| 指定连接的列 |
|| JOIN | 指定要连接的表格 |
|| WHERE | 进行目标数据筛选 |
|| GROUP BY | 对目标数据进行分组 |
|| 函数 | 进行聚合操作 |
|| HAVING | 对分组结果进行筛选 |
|| SELECT | 指定要提取的列 |
|| DISTINCT | 指定要提取的列 |
|| ORDER BY | 排序 |
|后| LIMIT | 指定提取的数量 |
⑧ 去重抽取的列
① 從指定的目標表中選擇
② 指定要結合的表
③ 指定要結合的列
④ 過濾目標數據
⑤ 按組分組
⑥ 從組結果中過濾
⑨ 按指定順序排序
⑩ 指定抽取的數量;
根据HAVING子句的条件来决定SELECT子句的指定,因此在创建HAVING子句之后才能指定SELECT子句。即使限制获取数据的数量较少,LIMIT在最后才进行评估,并不意味着处理会更快。
只有在以下情况下,通过LIMIT限制获取数据的数量才能实现更快的操作:
1. 没有指定ORDER BY
2. ORDER BY中指定的列已定义为索引
如果不使用WHERE子句进行筛选或创建索引,则无法实现更快的操作。
由于WHERE子句在SELECT子句之前进行评估,因此不能使用SELECT子句中使用AS指定的别名。
要加快查询速度,应尽早减少获取的数据量。
【桌子操作】
创建表
创建表 表名 (列名 类型(), 列名 类型());
例子
创建表 users(name varchar(255), age integer);
修改表名
将当前表名更改为新表名
例子
将表名users更改为employees
将表 现表名 改名为 新表名;
例子
将表 users 改名为 employees;
删除表
刪除 表名;
例子
刪除 users;
数据类型
PostgreSQL
MySQL
固定长度文本
char(5)
char(5)
可变长度文本
varchar(255) text
varchar(255) text
整数
integer或int
int (可正可负) int unsigned (仅正数且范围更大)
浮点数
real
float double
序列号
serial
布尔值
boolean(值: true, false, t, f)
boolean 别名 -> tinyint(1) 内部表示 true -> 1 false -> 0
日期(仅日期)
date
date
时间(仅时间)
time
time
日期时间
timestamp
datetime 2020-01-01 12:00:00
PostgreSQL文档: 数据类型
列举类型
创建表格users (
id int unsigned primary key auto_increment,
ranks enum(‘gold’, ‘silver’, ‘bronze’) — 枚举类型,在内部分别使用1、2、3进行数字分配
);
插入数据:insert into users (ranks) values (‘silver’);
插入数据:insert into users (ranks) values (‘gold’);
插入数据:insert into users (ranks) values (‘bronze’);
插入数据:insert into users (ranks) values (‘red’); — 将会插入NULL值
插入数据:insert into users (ranks) values (1);
插入数据:insert into users (ranks) values (2);
插入数据:insert into users (ranks) values (3);
插入数据:insert into users (ranks) values (4); — 将会插入NULL值
选择查询:select * from users where ranks = ‘gold’;
+—-+——-+——-+——-+
| id | name | score | ranks |
+—-+——-+——-+——-+
| 2 | fkoji | 8.2 | gold |
+—-+——-+——-+——-+
1 row in set (0.00 sec)
选择查询:select * from users where ranks = 1;
+—-+——-+——-+——-+
| id | name | score | ranks |
+—-+——-+——-+——-+
| 2 | fkoji | 8.2 | gold |
+—-+——-+——-+——-+
1 row in set (0.00 sec)
在內部,第一個元素被賦予“2的0次方”數值,第二個元素被賦予“2的1次方”數值,第三個元素被賦予“2的2次方”數值…
如果想指定第一和第二個元素,可以用“1 + 2”來表示“3”,第三和第四個元素可以用“4 + 8”來表示“12”
在insert和update中,使用內部分配的數值也是有效的
MySQL
創建表users (
id int unsigned 主鍵 auto_increment,
coins set(‘gold’, ‘silver’, ‘bronze’) — [第一個-> 2的0次方(1), 第二個-> 2的1次方(2), 第三個-> 2的2次方(4)]
);
插入數據users (coins) values (‘gold’); — (1)也可以
插入數據users (coins) values (‘silver’); — (2)也可以
插入數據users (coins) values (‘bronze’); — (4)也可以
插入數據users (coins) values (‘gold,silver’); — (3)也可以 1 + 2
插入數據users (coins) values (‘gold,bronze’); — (5)也可以 1 + 4
插入數據users (coins) values (‘silver,bronze’); — (6)也可以 2 + 4
插入數據users (coins) values (‘silver,bronze,bronze’); — (7)也可以 1 + 2 + 4
從users中選擇coins=’gold,silver’; — gold,silver
從users中選擇coins like ‘%gold%’;
+—-+——————–+
| id | coins |
+—-+——————–+
| 1 | gold |
| 4 | gold,silver |
| 5 | gold,bronze |
| 7 | gold,silver,bronze |
+—-+——————–+
共4行 (0.00 秒)
從users中選擇coins=1; — gold
從users中選擇coins=2; — silver
從users中選擇coins=3; — gold,silver
從users中選擇coins=4; — bronze
從users中選擇coins=5; — gold,bronze
從users中選擇coins=6; — silver,bronze
從users中選擇coins=7; — gold,silver,bronze
從users中選擇coins=8; — 空
限制
PostgresSQL
MySQL
输入必须
非空
非空
不可重复
唯一
唯一
输入检查
检查
初始值
默认
默认
主键
主键
主键
postgreSQL
postgresql.sql
创建表posts (
id serial 主键,
title varchar(255) 非空,
body text 检查(length(body) > 5),
is_draft boolean 默认TRUE,
created timestamp 默认statement_timestamp()
);
/*
制约
非空 输入必须
唯一 不可重复
检查
默认 默认值
主键 (非空 + 唯一) 只能在表中设置一个
*/
/*
statement_timestamp() -> 记录插入时间
*/
MySQL
mysql.sql
创建表users (
id int unsigned 主键 自增,
name varchar(20) 唯一,
score float 默认0.0
);
使用检索结果创建表格。
create table 表格名称 as 查询语句;
创建用户与团队对应的表格
create table users_with_team as
select
name,
score,
case
when score > 8.0 then ‘团队A’
when score > 6.0 then ‘团队B’
else ‘团队C’
end as Team
from
users;
查看用户与团队对应的表格的结构
desc users_with_team;
+———+————-+——+—–+———+——-+
| 字段名 | 类型 | 可空 | 键 | 默认 | 备注 |
+———+————-+——+—–+———+——-+
| name | varchar(20) | 是 | | NULL | |
| score | float | 是 | | NULL | |
| Team | varchar(6) | 否 | | | |
+———+————-+——+—–+———+——-+
共3行(0.01 秒)
桌子复制
格式:
create table 目标表名 (like 源表名 including all);
示例:
create table users_copy (like users including all);
列 | 类型 | 排序规则 | 是否可空 | 默认值
—-+————————+———+———-+———————————-
id | integer | | not null | nextval(‘users_id_seq’::regclass)
name | character varying(255) | | not null |
score | real | | | 0
team | character varying(255) | | |
索引:
“users_copy_pkey” PRIMARY KEY, btree (id)
通过查询结果复制
复制表结构和记录,不复制约束。
格式:
create table 目标表名 as 查询语句;
示例:
create table users_copy as select * from users;
列 | 类型 | 排序规则 | 是否可空 | 默认值
—-+————————+———+———-+———
id | integer | | |
name | character varying(255) | | |
score | real | | |
team | character varying(255) | | |
只复制表结构(不复制记录)
保留Primary key和索引
格式
create table 新建表名 like 源表名;
例子
create table users_empty like users;
desc users_empty;
+——-+————–+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+——-+————–+——+—–+———+—————-+
| id | int unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
| score | float | YES | | NULL | |
+——-+————–+——+—–+———+—————-+
3 rows in set (0.00 sec)
使用抽出结果进行复制
复制表结构和记录
不复制约束
不继承Primary key和索引
将扩展的默认值替换为0
格式
create table 新建表名 as select * from 原表名;
例子
create table users_copy select * from users;
+——-+————–+——+—–+———+——-+
| Field | Type | Null | Key | Default | Extra |
+——-+————–+——+—–+———+——-+
| id | int unsigned | NO | | 0 | |
| name | varchar(20) | YES | | NULL | |
| score | float | YES | | NULL | |
+——-+————–+——+—–+———+——-+
3 rows in set (0.01 sec)
改变表格的结构
PostgreSQL
/* 添加字段 */
alter table 表名 add 字段名 类型;
alter table users add fullname varchar(255);
/* 删除字段 */
alter table 表名 drop 字段名;
alter table users drop 字段名;
/* 修改字段名 */
alter table 表名 rename 原名 to 新名;
alter table users rename name to myname;
/* 修改字段类型 */
alter table 表名 alter 字段名 type 类型;
alter table users alter myname type varchar(32);
/* 添加索引 */
create index 索引名 on 表名(字段名);
create index team_index on users(team);
/* 删除索引 */
drop index 索引名;
drop index team_index;
MySQL
/* 添加列 */
alter table 表名 add column 列名 类型 after 列名;
alter table users add column email varchar(255) after name; /* 在列name之后添加列email */
/* 删除列 */
alter table 表名 drop column 列名;
alter table users drop column score;
/* 修改列名 */
alter table 表名 change 旧列名 新列名 类型 约束;
alter table users change name user_name varchar(80) default ‘no-name’;
/* 修改表名 */
alter table 旧表名 rename 新表名;
alter table users rename persons;
/* 添加索引 */
alter table 表名 add index 索引名 (要添加索引的列名);
alter table users add index index_score (score);
/* 删除索引 */
alter table 表名 drop index 索引名;
alter table users drop index index_score;
/* 查看索引 */
show index from 表名;
show index from users;
关于索引
primary keyに指定されたカラムは自動的にインデックスされる。
インデックスの追加は、検索のときは早くなるがレコードの挿入、更新時に新しいインデックスを作るので遅くなるためバランスを考える。
排列。
在 PostgreSQL 中,无法在命令级别对列进行排序。
以下方法可实现对列进行排序。
-
- 新建一个已经调整列顺序的表格,
- 更新数据并删除旧表。
其他方式
【插入】
插入语法:insert into 表名(列名, 列名…) values (值, 值…), (值, 值…)…;
示例
插入数据:insert into users(name, age)
values (
(‘田中’, 20),
(‘铃木’, 30),
(‘佐藤’, 40)
);
向表名 (列名, 列名…) 插入数据,值为 (值, 值…),(值, 值…)…
例子
向 users 表插入数据:
(1, ‘田中’, 20),
(2, ‘铃木’, 30),
(3, ‘佐藤’, 40);
最后插入的ID
前提条件
如果存在users表则删除;
如果存在posts表则删除;
创建users表:
id int unsigned 主键 自增,
name varchar(255)
创建posts表:
id int unsigned 主键 自增,
user_id int unsigned 非空
为posts表添加外键约束:
外键(user_id) 参考users表中的id
向users表插入数据:
name为”a”的记录,
name为”b”的记录,
name为”c”的记录
向posts表插入数据:
user_id为1的记录,
user_id为1的记录,
user_id为3的记录
从users表中删除id为2的记录
向posts表插入数据:
user_id为最近插入的记录的ID(即3)
查询users表中的所有记录
查询posts表中的所有记录
删除posts表中的外键约束
+—-+——+
| id | name |
+—-+——+
| 1 | a |
| 3 | c |
+—-+——+
共2条记录(0.00秒)
+—-+———+
| id | user_id |
+—-+———+
| 1 | 1 |
| 2 | 1 |
| 3 | 3 |
| 4 | 3 |
+—-+———+
共4条记录(0.01秒)
在插入/更新时刻创建记录
使用default current_time on update current_timestamp来更新记录时使用更新时间。
如果存在则删除users表。
创建users表,包含以下列:
– id:无符号整数型,主键,自动递增
– name:字符串型,长度255
– created_at:日期时间型,默认为当前时间
– updated_at:日期时间型,默认为当前时间,在更新时自动更新
向users表插入数据,name为’name1’的记录。
向users表插入数据,name为’name2’的记录。
向users表插入数据,name为’name3’的记录。
从users表中查询所有内容。
更新users表,将id为2的记录的name更改为’update name’。
等待5秒钟。
从users表中查询所有内容。
结果如下:
+—-+————-+———————+———————+
| id | name | created_at | updated_at |
+—-+————-+———————+———————+
| 1 | name1 | 2020-09-17 21:16:12 | 2020-09-17 21:16:12 |
| 2 | update name | 2020-09-17 21:16:12 | 2020-09-17 21:16:17 | — 更新时间会更新为记录更新时的时间
| 3 | name3 | 2020-09-17 21:16:12 | 2020-09-17 21:16:12 |
+—-+————-+———————+———————+
共3行 (0.00 秒)
查询到0行受影响 (5.01 秒)
.
.
.
+—-+————-+———————+———————+
| id | name | created_at | updated_at |
+—-+————-+———————+———————+
| 1 | name1 | 2020-09-17 21:16:12 | 2020-09-17 21:16:12 |
| 2 | update name | 2020-09-17 21:16:12 | 2020-09-17 21:16:17 | — 更新时间会更新为记录更新时的时间
| 3 | name3 | 2020-09-17 21:16:12 | 2020-09-17 21:16:12 |
+—-+————-+———————+———————+
共3行 (0.00 秒)
【选择】
從資料表中選取欄位名稱為「抽出するカラム」的資料。
範例
從users資料表中選取所有資料。
從users資料表中選取名稱和分數欄位的資料。
重新排序
格式
降序
order by 列名 desc;
升序
order by 列名 asc;
抽取指定数量的记录
limit 抽取数目 offset 从第n个位置开始;
/* 升序 */
select * from users order by score;
select * from users order by score asc;
/* 降序 */
select * from users order by score desc;
/* 从第n个位置开始抽取n个 */
select * from users limit 3 offset 3;
/* 分数排名前3 */
select * from users order by score limit 3;
/* 分数排名第4到第6 */
select * from users order by score limit 3 offset 3;
/* 分数为空的记录 */
select * from users where score is null;
/* 分数不为空的记录 */
select * from users where score is not null;
查看在抽取时使用的索引。
explain 抽出文;
———————————————————-
来自 users 表的顺序扫描 (成本=0.00..10.88,行数=23,宽度=1040)
过滤条件: (id > 1)
(2 行)
| 表 | 非唯一 | 关键名称 | 索引中的顺序 | 列名称 | 顺序 | 基数 | 子部分 | 打包 | 空值 | 索引类型 | 评论 | 索引评论 | 可见 | 表达式 |
+——-+————+————-+————–+————-+———–+————-+———-+——–+——+————+———+—————+———+————+
| 用户 | 0 | 主键 | 1 | ID | A | 0 | NULL | NULL | | BTREE | | | 是 | NULL |
| 用户 | 1 | 分数索引 | 1 | 分数 | A | 0 | NULL | NULL | 是 | BTREE | | | 是 | NULL |
+——-+————+————-+————–+————-+———–+————-+———-+——–+——+————+———+—————+———+————+
两行显示结果(0.00秒)
【哪里】
从表名选择列名 满足条件的记录;
例子
从用户表中选择所有满足分数大于1的记录;
从用户表中选择所有满足分数大于2.0且团队为’red’的记录;
从用户表中选择所有团队为’red’或者’blue’的记录;
比较运算符
运算符
意义
>
大于
< 小于 >=
大于等于
<=
小于等于
=
等于
<>
不等于
!=
不等于
逻辑运算符
— and
从用户表中选择所有分数大于等于3.0且小于等于6.0的记录;
从用户表中选择所有分数范围在3.0和6.0之间的记录;
— or
从用户表中选择名称为’taguchi’或者’fkoji’的记录;
从用户表中选择名称在’taguchi’和’fkoji’之间的记录;
模糊搜索/通配符
PostgreSQL / MySQL
默认设置
PostgreSQL区分大小写
MySQL不区分大小写
通配符
意义
_
匹配任意1个字符
%
匹配0个或多个字符
a%
以a开头的字符串
%a%
包含a的字符串
PostgreSQL: 不区分大小写搜索
从用户表中选择所有名称以大写字母A开头的记录;
MySQL: 区分大小写搜索
从用户表中选择所有名称以大写字母A开头的记录;
【记录汇总】
四则运算
意义+
加法
–
减法
*
乘法
/
除法
%
取余
/* 查询id为偶数的记录 */
select * from users where id % 2 = 0;
/* 将id为偶数的记录的score乘以1.2 */
update users set score = score * 1.2 where id % 2 = 0;
统计函数
操作
count
记录数
distinct
数据类型
sum
总计
avg
平均值
max
最大值
min
最小值
从用户中选择计数(积分);
从用户中选择计数(ID);
从用户中选择计数(*);
从用户中选择总计(积分);
从用户中选择最小值(积分);
从用户中选择最大值(积分);
从用户中选择平均值(积分);
从用户中选择不同的团队;
从用户中选择计数(不同的团队);– 团队的种类数
按照……分组 ……
组 | 总和
——-+———–
蓝 | 8.3
红 | 12.299999
绿 | 9.7
请提供更多的上下文以更准确地翻译。”HAVING句”在中文中没有明确的对应短语。
- 集計後のデータに対しての絞り込み
概要
WHERE句
从SELECT句的结果中进行筛选
HAVING句
从使用group by进行聚合的结果中进行筛选
/* 每个团队总分大于10.0的记录 */
select team, sum(score) from users group by team having sum(score) > 10.0;
/* 先筛选id > 3的记录,再使用group by进行聚合 */
select sum(score), team from users_with_team where id > 3 group by team;
计算时间
-
- date_add()
- date_format()
创建表users (
id int unsigned primary key auto_increment,
name varchar(255),
created_at datetime 默认 current_timestamp,
updated_at datetime 默认 current_timestamp on update current_timestamp
);
向users插入数据 (name) values (‘name1’);
向users插入数据 (name) values (‘name2’);
向users插入数据 (name) values (‘name3’);
当 id = 2 时,更新users中的created_at = ‘2019-09-17 10:00:00’; — 更新日期
选择 * 从users表;
+—-+——-+———————+———————+
| id | name | created_at | updated_at |
+—-+——-+———————+———————+
| 1 | name1 | 2020-09-17 21:35:37 | 2020-09-17 21:35:37 |
| 2 | name2 | 2019-09-17 10:00:00 | 2020-09-17 21:35:37 |
| 3 | name3 | 2020-09-17 21:35:37 | 2020-09-17 21:35:37 |
+—-+——-+———————+———————+
共 3 行 (0.00 sec)
选择 * 从users表,条件为created_at > ‘2019-12-31’; — 指定日期条件
+—-+——-+———————+———————+
| id | name | created_at | updated_at |
+—-+——-+———————+———————+
| 1 | name1 | 2020-09-17 21:35:37 | 2020-09-17 21:35:37 |
| 3 | name3 | 2020-09-17 21:35:37 | 2020-09-17 21:35:37 |
+—-+——-+———————+———————+
共 2 行 (0.00 sec)
选择created_at, date_add(created_at, interval 21 day) 从users表; — 21天后
+———————+—————————————+
| created_at | date_add(created_at, interval 21 day) |
+———————+—————————————+
| 2020-09-17 21:35:37 | 2020-10-08 21:35:37 |
| 2019-09-17 10:00:00 | 2019-10-08 10:00:00 |
| 2020-09-17 21:35:37 | 2020-10-08 21:35:37 |
+———————+—————————————+
共 3 行 (0.00 sec)
选择created_at, date_add(created_at, interval 3 week) 从users表; — 3周后
+———————+—————————————+
| created_at | date_add(created_at, interval 3 week) |
+———————+—————————————+
| 2020-09-17 21:35:37 | 2020-10-08 21:35:37 |
| 2019-09-17 10:00:00 | 2019-10-08 10:00:00 |
| 2020-09-17 21:35:37 | 2020-10-08 21:35:37 |
+———————+—————————————+
共 3 行 (0.00 sec)
选择created_at, date_format(created_at, ‘%W %M %Y’) 从users表; — 指定提取时的格式
+———————+————————————-+
| created_at | date_format(created_at, ‘%W %M %Y’) |
+———————+————————————-+
| 2020-09-17 21:35:37 | Thursday September 2020 |
| 2019-09-17 10:00:00 | Tuesday September 2019 |
| 2020-09-17 21:35:37 | Thursday September 2020 |
+———————+————————————-+
共 3 行 (0.00 sec)
函数
選擇 name, length(name) from users;
/* 提取結果 */
name | 長度
————+——–
taguchi | 7
fkoji | 5
dotinstall | 10
sasaki | 6
sasaki | 6
kimura | 6
(6 rows)
串聯(字串連接)
選擇 concat(name, ‘(‘, team, ‘)’) as from users;
/* 結果 */
串聯
—————–
taguchi(red)
fkoji(blue)
dotinstall(red)
sasaki(green)
sasaki(red)
kimura(green)
(6 rows)
作為(別名)
blogapp=# 選擇 concat(name, ‘(‘, team, ‘)’) as nameteam from users;
nameteam
—————–
taguchi(red)
fkoji(blue)
dotinstall(red)
sasaki(green)
sasaki(red)
kimura(green)
(6 rows)
子字串(n字元開始取出m個字元)
blogapp=# 選擇 substring(team, 1, 1) as teaminitiale from users;
/* 結果 */
teaminitiale
————–
r
b
r
g
r
g
(6 rows)
隨機(隨機抽取)
blogapp=# 選擇 * from users order by random() limit 1;
/* 結果 */
id | name | score | team
—-+——-+——-+——
2 | fkoji | 8.3 | blue
(1 row)
select round(5.355); — 5
select round(5.355, 1); — 5.4 指定第二个参数为要显示的小数位数
floor()(向下取整)
select floor(5.833); — 5
select floor(5.238); — 6
rand()(随机数)
select rand(); — 随机数
select * from users order by rand() limit 1; — 随机获取一条记录
length()(长度)
select length(‘Hello’); — 5
substring()(获取字符串的一部分)
select substring(‘Hello’, 2); — ello
select substring(‘Hello’, 2, 3); — ell
upper()(转换为大写)
select upper(‘Hello’); — HELLO
lower()(转换为小写)
select lower(‘Hello’); — hello
concat()(字符串连接)
select concat(‘Hello’, ‘World’); — HelloWorld
as(别名)
select length(name) as len, name from users order by len;
+——+————+
| len | name |
+——+————+
| 5 | fkoji |
| 6 | Tanaka |
| 6 | yamada |
| 7 | taguchi |
| 7 | tashiro |
| 10 | dotinstall |
+——+————+
6 rows in set (0.00 sec)
【分岐条件】
如果
如果有users表,则删除users表;
从users表中选择
姓名,
分数,
如果(分数>5.0,’合格’,’不合格’)作为结果
;
+————+——-+——–+
| 姓名 | 分数 | 结果 |
+————+——-+——–+
| 田口 | 5.8 | 合格 |
| fkoji | 8.2 | 合格 |
| dotinstall | 6.1 | 合格 |
| 田中 | 4.2 | 不合格 |
| 山田 | NULL | 不合格 |
| 田代 | 7.9 | 合格 |
+————+——-+——–+
6 行 (0.00 秒)
案例文件
选择
姓名,
分数,
case floor(score) % 2
当为0时则为 ‘偶数’
当为1时则为 ‘奇数’
其他情况下为 null
结果将名为 类型
从
用户表中;
+————+——-+——+
| 姓名 | 分数 | 类型 |
+————+——-+——+
| 田口 | 5.8 | 奇数 |
| fkoji | 8.2 | 偶数 |
| dotinstall | 6.1 | 偶数 |
| 田中 | 4.2 | 偶数 |
| 山田 | NULL | NULL |
| 田代 | 7.9 | 奇数 |
+————+——-+——+
6 行记录 (0.00 秒)
给定条件时的返回值
选择
姓名,
分数,
case
当分数 > 8.0时则为 ‘团队-A’
当分数 > 6.0时则为 ‘团队-B’
其他情况下为 ‘团队-C’
结果将名为 团队
从
用户表中;
+————+——-+——–+
| 姓名 | 分数 | 团队 |
+————+——-+——–+
| 田口 | 5.8 | 团队-C |
| fkoji | 8.2 | 团队-A |
| dotinstall | 6.1 | 团队-B |
| 田中 | 4.2 | 团队-C |
| 山田 | NULL | 团队-C |
| 田代 | 7.9 | 团队-B |
+————+——-+——–+
6 行记录 (0.00 秒)
【更新】
UPDATE users SET score = score + 1 WHERE team = ‘red’;
UPDATE users SET name = ‘sasaki’, score = score + 1 WHERE name = ‘taguchi’;
【删除】
删除 users表;
/* 删除满足条件的记录 */
删除 users表中 score 小于 4.0 的记录;
删除 1个记录
【处理多张桌子】
从 表A,表B 中选择 表A.列名,表B.列名
通过 表A, 表B 进行连接,以 表A.列名 = 表B.列名 作为条件
/* 在where子句中指定表A和表B中哪些列被视为相同,并创建表之间的连接*/
例子:
从 用户表,帖子表 中选择 用户表.姓名,帖子表.标题
通过 用户表,帖子表 进行连接,以 用户表.编号 = 帖子表.用户编号 作为条件
/* 将用户表和帖子表连接起来,连接条件是用户表中的编号与帖子表中的用户编号相同*/
例如:
/* 使用别名缩短语句,在from子句中为表命名别名 */
/* from子句是最先执行的,所以别名在from子句中定义 */
选择 u.姓名, p.标题 从 用户表 u, 帖子表 p where u.编号 = p.用户编号;
/* 使用and添加条件 */
选择 u.姓名, p.标题 从 用户表 u, 帖子表 p where u.编号 = p.用户编号 and u.编号 = 1;
使用view
创建视图
观点使用
查看删除
删除视图taguchi_posts;
【交易】
开始; — 开始
/* 处理 */
回滚; — 取消
提交; — 完成
开始事务;– 开始
/* 处理 */
回滚;– 取消
提交;– 完成
【子查询】
使用从句中的提取结果。
从
(选择 id, name, score, — 从子查询开始
情况
当得分 > 8.0 则 ‘A队’
当得分 > 6.0 则 ‘B队’
否则 ‘C队’
作为 Team
从用户) as t — 到此为止。
按 t.team 分组;+——————-+——–+
| sum(t.score) | Team |
+——————-+——–+
| 10 | C队 |
| 8.199999809265137 | A队 |
| 14 | B队 |
+——————-+——–+
3 行结果 (0.00 秒)
【表格的连接】
前提条件
select * from posts;
+----+---------+--------+
| id | title | body |
+----+---------+--------+
| 1 | title 1 | body 1 |
| 2 | title 2 | body 2 |
| 3 | title 3 | body 3 |
+----+---------+--------+
select * from comments;
+----+---------+---------------------------+
| id | post_id | body |
+----+---------+---------------------------+
| 1 | 1 | first comment for post 1 |
| 2 | 1 | second comment for post 1 |
| 3 | 3 | first comment for post 3 |
| 4 | 4 | first comment for post 4 |
+----+---------+---------------------------+
内连接
- テーブル同士共通のデータだけを取得する
查询语句通常使用SELECT语句来从一个或多个表中检索所需的数据。JOIN子句用于将两个或多个表中的行连接在一起,基于一个或多个共同的列进行匹配。
以下是一个使用JOIN的示例查询语句:
“`sql
SELECT * FROM posts JOIN comments ON posts.id = comments.post_id;
“`
这个查询语句将两个表(posts和comments)连接在一起,通过id和post_id这两个列进行匹配。结果包含来自两个表的列,如果匹配成功,则会返回匹配的行。
查询语句也可以指定要返回的列,并且可以为列指定别名。在这个示例中,
“`sql
SELECT posts.id, title, body AS posts_body, comments.body AS comments_body FROM posts JOIN comments ON posts.id = comments.post_id;
“`
这个查询语句使用了表的别名,并为每个返回的列指定了一个别名,以便更清晰地表示不同列的作用。
全外连接
- 片方にしかレコードがない場合でも抽出する
下面是一些关于使用LEFT JOIN和RIGHT JOIN的例子:
例1:在基于左侧表的左外连接中,取出posts表中的所有数据,同时根据posts.id和comments.post_id进行连接。如果comments表中没有post_id = 2的数据,则显示为NULL。
“`
select * from posts left join comments on posts.id = comments.post_id;
+—-+———+——–+——+———+—————————+
| id | title | body | id | post_id | body |
+—-+———+——–+——+———+—————————+
| 1 | title 1 | body 1 | 1 | 1 | first comment for post 1 |
| 1 | title 1 | body 1 | 2 | 1 | second comment for post 1 |
| 2 | title 2 | body 2 | NULL | NULL | NULL |
| 3 | title 3 | body 3 | 3 | 3 | first comment for post 3 |
+—-+———+——–+——+———+—————————+
4 行受到影响 (0.01 秒)
“`
例2:在基于右侧表的右外连接中,取出comments表中的所有数据,同时根据posts.id和comments.post_id进行连接。如果posts表中没有id = 4的数据,则显示为NULL。
“`
select * from posts right join comments on posts.id = comments.post_id;
+——+———+——–+—-+———+—————————+
| id | title | body | id | post_id | body |
+——+———+——–+—-+———+—————————+
| 1 | title 1 | body 1 | 1 | 1 | first comment for post 1 |
| 1 | title 1 | body 1 | 2 | 1 | second comment for post 1 |
| 3 | title 3 | body 3 | 3 | 3 | first comment for post 3 |
| NULL | NULL | NULL | 4 | 4 | first comment for post 4 |
+——+———+——–+—-+———+—————————+
4 行受到影响 (0.00 秒)
“`
通过使用不同类型的JOIN操作,可以根据不同的连接条件获取想要的结果。
外部键约束
添加外键约束
-
- 外部キー制約を付けるカラムは、紐づくカラムと同じ型にする必要がある
-
- 紐づくレコードが存在しない場合レコードを挿入できない
- カラムに外部キー制約が付いている場合deleteで削除できなくなる
**前提**
创建表users (
id int unsigned primary key auto_increment,
name varchar(255)
);创建表posts (
id int unsigned primary key auto_increment,
user_id int unsigned not null
);
書式
/* 列A将与表A中的列B相关联 */
/* 表B是要相关联的表名 */
/* 列B是要相关联的列名 */
alter table 表A add constraint 键名 foreign key (列A) references 表B (列B);
例
alter table posts add constraint fk_posts foreign key (user_id) references users (id);
删除外键约束
修改表 `表名` 删除外键 `键名`;
例如:
修改表 posts 删除外键 fk_posts;
【触发器】
-
- トリガー起動時に実行されるSQL文において、old.カラム名とNEW.カラム名を使って参照可能。
-
- トリガー操作がINSERTの場合はNEW.カラム名で新しく追加されたデータの値を参照できる。
-
- トリガー操作がDELETEの場合は OLD.カラム名で削除されたデータの値を参照できる。
- トリガー操作操作がUPDATEの場合はOLD.カラム名とNEW.カラム名の両方が使用でき更新される前の値と更新された後の値を参照できる。
觸發器建立
触发器是一种特殊的存储过程,它在满足特定条件时自动执行。在MySQL中,可以使用CREATE TRIGGER语句来创建触发器。触发器可以在INSERT、UPDATE或DELETE操作之前或之后触发,可以指定触发器所针对的表以及触发时要执行的操作。
以下是一些使用触发器的示例:
示例1:
创建一个在插入数据后将相应信息插入日志表的触发器。
“`mysql
CREATE TRIGGER posts_insert_trigger AFTER INSERT ON posts FOR EACH ROW
INSERT INTO logs (msg) VALUES (‘post added!’);
“`
示例2:
创建一个在更新用户表时将相应信息插入日志表的触发器。
“`mysql
DROP TRIGGER IF EXISTS users_update_logs;
DELIMITER //
CREATE TRIGGER users_update_logs AFTER UPDATE ON users FOR EACH ROW
BEGIN
INSERT INTO logs (msg) VALUES (‘users updated’);
INSERT INTO logs (msg) VALUES (CONCAT(old.name, ‘->’, new.name));
END //
DELIMITER ;
“`
通过使用触发器,可以在数据更改时执行自定义操作,从而实现更灵活和自动化的数据库管理。
触发器列表
显示触发器 \G;
触发删除
删除触发器 触发器名;
例子
删除触发器 posts_insert_trigger;
【备份/恢复】
使用mysqldump命令创建备份文件
$ mysqldump -u 用户名 -p 数据库名 > 文件名
数据库恢复:
使用\.命令恢复备份文件
$ \. ./备份文件名