一对一关联
1 | select * from city; |
根据MySQL的设置,默认接受使用单引号或双引号来表示字符串。
将上面两句以子查询的方式合并一句
1 | select * from code where id=(select code_id from city where city_name='北京'); |
on
和where
后面所跟的条件不同:
select
+查询字段+from
+查询表+join
+关联表+on
+关联条件+where
+筛选条件
1 | select city_name,code_name from city join code as c on code_id=c.id where city_name='北京'; |
表别名或字段别名,关键字“as”可以省略
一对多关联
多表需添加外键(XX_id)指向主表 ,例如:班级和学生,是一对多关系,学生表students表添加外键class_id
,指向班级表class
1 | select s.name from class c join students s on c.id=s.class_id where c.class_name = "一班"; |
张三的同班同学(自关联)
1 | select s1.name ,s2.name from students s1 join students s2 on s1.class_id=s2.class_id where s2.name='张三' and s1.name!='张三'; |
多对多关联
多对多关联需添加第三张表作为中间表,中间表至少包含两个字段,这两个字段分别作为外键,指向各自一方的主键。例如以下是articles与tags是多对多关系,添加中间表articles_tags,其中字段分别指向两表
文章表articles
中间表articles_tags
标签表 tags
给每篇文章计数标签
1 | select a.title,count(*) from articles a join articles_tags at on a.id=at.articles_id group by a.title; |
「马上雾霾就来了」文章有哪些标签
1 | select a.title,t.name from articles a join articles_tags at on a.id=at.articles_id join tags t on at.tags_id=t.id where a.title='马上雾霾就来了'; |
数据库操作
创建数据库两种方式
1 | create database testdb charset utf8; |
查看所有数据库以及数据库的设置
1 | show databases; |
进入(使用)数据库
1 | use testdb; |
删除数据库的两种方式
1 | drop database testdb; |
数据库名字不可以修改,数据库的修改仅限库选项: 字符集和校对集(校对集依赖字符集)
表的操作
创建表
1 | 字段+数据类型+其他要求 |
删除表
drop table students,...;
进数据库前不能使用命令show tables
查看表
1 | show tables; |
模糊查询
show tables like 's%';
查看表结构 \g
横向,默认设置;\G
纵向;注意后面不能加分号
1 | desc students;desc students\G |
查看表结构创建语句
1 | show create table students; |
复制表结构
1 | create table stu_bak like students; |
复制表数据
1 | insert into stu_bak select * from students; |
复制表结构同时备份数据
1 | create table stu_bak2 select * from students; |
rename修改表名
1 | alter table 旧表名 rename 新表名; |
字段操作
修改字段名:alter...change...
修改字段修饰:alter...modify...
添加字段:add
删除字段:drop
修改字段名用change
:
Alter table
+表名+change old_name new_name
+字段修饰;
1 | alter table students change username name varchar(100) not null default ''; |
修改字段修饰用modify
:
1 | alter table students modify name varchar(50) not null default '' comment '姓名'; |
添加字段 用add
(after/before):
1 | alter table students add time int not null default 0 after money; |
删除字段drop
:
1 | alter table students drop time; |
主键操作
添加主键自增:先添加主键 ,再添加自增
1 | alter table students add primary key(id); |
删除主键:先删除自增,再删除主键
1 | alter table students modify id int; |
常用数据类型与修饰
decimal(5,2):浮点型,指一共五位数字,其中两位小数,整数3位多了报错,小数多了四舍五入。相比于float,double类型,decimal类型属于精确类型,不会丢失精度,所以只要涉及到金钱,财务相关的数据,对应的类型一定要选择decimal。
1 | Decimal(18,9),18这个数代表最长可以到18位,而9这个数字表示小数点后面有9位数字,那么18-9=9,也就得出了整数位可以有9位。 |
enum:枚举,单选型,用于存储单一值
1 | alter table students add gender1 ENUM('男', '女') |
set:集合类型,多选型,用于存储多个值
1 | alter table students add hobby1 set('羽毛球', '篮球','乒乓球'); |
char(6) :定长 效率高,最多存储6个字符
varchar(30) :变长,省空间
Int(10):指定zerofill前导0填充,不足10位时,以0填充,超过则正常显示,不做宽度限制。无论int(9)还是int(3),都是占用四个字节的空间
unique:唯一约束
primary key:主键,一个表最多只能有一个主键,主键列中不能null 0 重复值
auto_increment:自增
unsigned:非负修饰(设置前导零会自动设置上)
not null:不为空
default :默认值
如果是char或varchar类型,length可以小于字段规定长度。当varchar太大时,会自动转化为text。
Mysql 数据类型:
数值类型:
MySQL 支持所有标准 SQL 数值数据类型。
这些类型包括严格数值数据类型( INTEGER、SMALLINT、DECIMAL 和 NUMERIC ),以及近似数值数据类型( FLOAT、REAL 和 DOUBLE PRECISION )。
关键字 INT 是 INTEGER 的同义词,关键字 DEC 是 DECIMAL 的同义词。
BIT数据类型保存位字段值,并且支持 MyISAM、MEMORY、InnoDB 和 BDB 表。
作为 SQL 标准的扩展,MySQL 也支持整数类型 TINYINT、MEDIUMINT 和 BIGINT
数据类型 | 大小 | 范围(无符号) | 范围(有符号) | 描 述 |
---|---|---|---|---|
TINYINT(size) | 1字节 | (0,255) | (-125,127) | 小整数值 |
SMALLINT(size) | 2字节 | (0,65535) | (-32768,32767) | 大整数值,size 默认为9 |
MEDIUMINT(size) | 3字节 | (0,16777215) | (-8388608,8388607) | 大整数值,size 默认为 9 |
INT(size)或INTEGER | 4字节 | (0,4294967295) | (-2147483648,2147483647) | 大整数值,size 默认为 11 |
BIGINT(size) | 8字节 | (0,18446744073709551615) | (-9223372036854775808,9223372036854775807) | 极大整数值,size 默认为 20 |
FLOAT(size,d) | 4字节 | 0,(1.175 494 351 E-38,3.402 823 466 E+38) | (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) | 单精度浮点数,size 参数中规定显示最大位数,d 参数中规定小数点右侧的最大位数 |
DOUBLE(size,d) | 8字节 | 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 双精度浮点数,size 参数中规定显示最大位数,d 参数中规定小数点右侧的最大位数 |
DECIMAL(M,D) | 默认M=10,D=0 | 依赖于size和d的值 | 依赖于size和d的值 | size 为精度;d 为保留的小数位数 |
以上的 size 代表的并不是存储在数据库中的具体的长度,如 int(4) 并不是只能存储4个长度的数字。
实际上int(size)所占多少存储空间并无任何关系。int(3)、int(4)、int(8) 在磁盘上都是占用 4 btyes 的存储空间。就是在显示给用户的方式有点不同外,int(M) 跟 int 数据类型是相同的。
例如:
1 | int的值为10 (指定zerofill) |
字符创类型:
指 CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM 和 SET
数据类型 | 大小 | 描述 |
---|---|---|
CHAR(size) | 0-255字节 | 定长字符串,保存固定长度的字符串(可包含字母、数字以及特殊字符),括号中指定字符串的长度,最多 255 个字符。 |
VARCHAR(size) | 0-65535 字节 | 变长字符串,保存可变长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的最大长度。最多 255 个字符。**注释:**如果值的长度大于 255,则被转换为 TEXT 类型。 |
TINYTEXT | 0-255字节 | 短文本字符串,存放最大长度为 255 个字符的字符串。 |
TEXT | 0-65 535字节 | 长文本数据,存放最大长度为 65,535 个字符的字符串。 |
TINYBLOB | 0-255字节 | 不超过 255 个字符的二进制字符串 |
BLOB | 0-65 535字节 | 二进制形式的长文本数据,用于 BLOBs(Binary Large OBjects)。存放最多 65,535 字节的数据。 |
MEDIUMTEXT | 0-16 777 215字节 | 中等长度文本数据,存放最大长度为 16,777,215 个字符的字符串。 |
MEDIUMBLOB | 0-16 777 215字节 | 二进制形式的中等长度文本数据,用于 BLOBs(Binary Large OBjects)。存放最多 16,777,215 字节的数据。 |
LONGTEXT | 0-4 294 967 295字节 | 极大文本数据,存放最大长度为 4,294,967,295 个字符的字符串。 |
LONGBLOB | 0-4 294 967 295字节 | 二进制形式的极大文本数据,用于 BLOBs (Binary Large OBjects)。存放最多 4,294,967,295 字节的数据。 |
ENUM(x,y,z,etc.) | - | 允许您输入可能值的列表。可以在 ENUM 列表中列出最大 65535 个值。如果列表中不存在插入的值,则插入空值。**注:**这些值是按照您输入的顺序排序的。 |
SET | - | 与 ENUM 类似,不同的是,SET 最多只能包含 64 个列表项且 SET 可存储一个以上的选择。 |
CHAR 和 VARCHAR 类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。
BINARY 和 VARBINARY 类类似于 CHAR 和 VARCHAR,不同的是它们包含二进制字符串而不是非二进制字符串。也就是说,它们包含字节字符串而不是字符字符串。这说明它们没有字符集,并且排序和比较基于列值字节的数值。
BLOB 是一个二进制大对象,可以容纳可变数量的数据,可以存储图片,音视频等文件。有 4 种 BLOB 类型,它们只是可容纳值的最大长度不同。
1 | TINYBLOB:大小:0 - 255字节,用途:短文本二进制字符串 |
数据库并不适合直接存储图片,如果有大量存储图片的需求,请使用对象存储或文件存储,数据库中可以存储图片路径来调用。
TEXT类型同 char、varchar 类似,都可用于存储字符串,一般情况下,遇到存储长文本字符串的需求时可以考虑使用 text 类型。按照可存储大小区分,有 4 种 类型:
1 | TINYTEXT:大小:0 - 255字节,用途:一般文本字符串 |
不过在日常场景中,存储字符串还是尽量用 varchar ,只有要存储长文本数据时,可以使用 text 类型。
对比 varchar ,text 类型有以下特点
1 | - text 类型无须指定长度。 |
text存储字节,varchar存储字符。
数据库规范中一般不推荐使用 blob 及 text 类型,但由于一些历史遗留问题或是某些场景下,还是会用到这两类数据类型的。
日期时间类型:
表示时间值的日期和时间类型为 DATETIME、DATE、TIMESTAMP、TIME 和 YEAR。
每个时间类型有一个有效值范围和一个"零"值,当指定不合法的 MySQL 不能表示的值时使用"零"值。
TIMESTAMP 类型有专有的自动更新特性。
数据类型 | 大小(字节) | 范围 | 格式 | 描述 |
---|---|---|---|---|
DATE | 3 | 1000-01-01/9999-12-31 | YYYY-MM-DD | 日期 |
DATETIME | 8 | 1000-01-01 00:00:00/9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 日期和时间的组合 |
TIMESTAMP | 4 | '1970-01-01 00:00:01’UTC/'2038-01-09 03:14:07’UTC | YYYY-MM-DD HH:MM:SS | 时间戳,使用 Unix 纪元(‘1970-01-01 00:00:00’ UTC) 至今的秒数来存储。 |
TIME | 3 | ‘-838:59:59’/‘838:59:59’ | HH:MM:SS | 时间 |
YEAR | 1 | 1901/2155 | YYYY | 2 位或 4 位格式的年份值。4 位格式所允许的值:1901 到 2155。2 位格式所允许的值:70 到 69,表示从 1970 到 2069。 |
即便 DATETIME 和 TIMESTAMP 返回相同的格式,它们的工作方式很不同。在 INSERT 或 UPDATE 查询中,TIMESTAMP 自动把自身设置为当前的日期和时间。TIMESTAMP 也接受不同的格式,比如 YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD 或 YYMMDD。
数据操作
别名设置,left(),mid(),right(),count(),year(),max(),avg(),sum()函数,if(条件,成立反值,不成立反值)
显示表所有数据
1 | select * from students; |
在字段中查找set类型数据
find_in_set(s1,s2):返回在字符串s2中与s1匹配的字符串的位置,列中逗号需得是英文","
1 | 在表students中筛选出字段hobby中包含“篮球”的数据 |
连接字符串concat
1 | select concat(username,'-',age) from students; |
distinct去重相同数据,后面数据和前面数据合并为一个数据
1 | select distinct sex from students; |
if表达式 i作为if(条件,成立反值,不成立反值)的字段名,显示大于小于
1 | select age,if(age>30,'大于30','小于等于30') i from students; |
order排序 desc 降序 asc升序 默认升序可以省略,有重复age时可以用到
1 | select * from students order by age desc,id desc; |
随机获取3个数据
1 | select * from students order by rand() limit 3; |
年龄在10-55之间的同学 between… and…
1 | select * from students where age between 10 and 55; |
查询年龄在23,34,45岁的同学
1 | select * from students where age in (23,34,45); |
字符串截取 left(str,length),mid(str,pos,len),right(str,length)
截取左边开始的2个字符
1 | select left(username,2) from students; |
截取左边第2个字开始的1个字符长度
1 | select mid(username,2,1) from students; |
as+别名:查询结果字段显示别名,as可以省略
1 | select username as u,age as a from students; |
获得所有人出生年份
1 | select year(birthday) from students; |
查看班级有多少男同学
1 | select count(*) from students where sex='男'; |
max()最大,sum()求和,avg()求平均值
1 | select max(age) from students; |
男生有多少人
1 | select sex,count(*) from students group by sex having sex='男'; |
插入数据
1 | insert into students set age=18,money=100; |
写入多条数据:省略字段名,则默认所有字段
1 | insert into students (username,age,sex) values ('超人',18,'男'),('葫芦娃',18,'男')...; |
更新数据必须要有主键 ,即主键id,否则视为插入数据
1 | replace into students (id,username,age,sex) values (32,'超人复仇者联盟222',18,'男') |
update:
1 | //所有男变为女 |
replace into 与 update的区别:
REPLACE INTO
和 UPDATE
都是在数据库中更新数据的操作,但REPLACE INTO
语句首先尝试插入一条新记录,如果已存在具有相同主键(或唯一键)的记录,则先删除旧记录,然后再插入新记录。 而 UPDATE
语句仅更新现有记录的某些列,不会删除或重新插入记录。
删除数据
delete from 表名 条件
1 | delete from students where id=19; |
清空所有数据,让id重新从1开始
1 | truncate students; |
显示警告:
1 | show warnings; |
其他
select now(); 获得当前日期时间
顺序:where—group by having—order by—limit
1 | select * from students where id>4 group by gender having gender='女' order by age limit 1; |
使用关键字 需加上"``"
1 | create database `databases`; |
查看服务器识别的字符集
1 | show charset; |
服务器默认的跟客户端打交道的字符集
1 | show variables like 'character_set%'; |
查看mysql中的存储过程和函数状态
1 | SHOW PROCEDURE STATUS LIKE 'insert_%'\G |
查看设置的过程
1 | SHOW CREATE PROCEDURE insert_d(过程名)\G |
MySQL在windows下是不区分大小写的,将script文件导入MySQL后表名也会自动转化为小写。但再将数据库导出放到linux服务器中使用时就报错了,
因为在linux下,表名区分大小写而找不到表,即大小写敏感。可以在linux下更改MySQL的设置使其也不区分大小写,反之要使得在windows下大小写敏感,相应的更改windows中MySQL的设置就行了。